diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs new file mode 100644 index 0000000..ce41ce0 --- /dev/null +++ b/AssemblyInfo.cs @@ -0,0 +1,13 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using System.Security.Permissions; + +[assembly: AssemblyCompany("Microsoft Corporation")] +//[assembly: AssemblyKeyFile("e:\\temp\\471135\\public.amd64fre\\internal\\strongnamekeys\\fake\\36MSApp1024.snk")] +[assembly: ComVisible(false)] +[assembly: AssemblyProduct("Microsoft (R) Windows (R) Operating System")] +[assembly: AssemblyCopyright("Copyright (c) Microsoft Corporation. All rights reserved.")] +[assembly: AssemblyFileVersion("4.8.2345.0")] +[assembly: AssemblyDelaySign(true)] +[assembly: AssemblyVersion("4.7.0.0")] +[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] diff --git a/Microsoft/Zune/MemoryFonts.cs b/Microsoft/Zune/MemoryFonts.cs new file mode 100644 index 0000000..284e690 --- /dev/null +++ b/Microsoft/Zune/MemoryFonts.cs @@ -0,0 +1,66 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.MemoryFonts +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Zune +{ + internal class MemoryFonts + { + public const uint LOAD_LIBRARY_AS_DATAFILE = 2; + public const int RT_DATA = 10; + + public static bool TryLoadFromResource(string resourceDllName, string fontResourceName) + { + IntPtr instanceHandle = IntPtr.Zero; + try + { + instanceHandle = MemoryFonts.LoadLibraryEx(resourceDllName, IntPtr.Zero, 2U); + if (instanceHandle == IntPtr.Zero) + return false; + IntPtr resource = MemoryFonts.FindResource(instanceHandle, fontResourceName, (IntPtr)10); + if (resource == IntPtr.Zero) + return false; + IntPtr resourceHandle = MemoryFonts.LoadResource(instanceHandle, resource); + return !(resourceHandle == IntPtr.Zero) && !(MemoryFonts.AddFontMemResourceEx(MemoryFonts.LockResource(resourceHandle), MemoryFonts.SizeofResource(instanceHandle, resource), IntPtr.Zero, out uint _) == IntPtr.Zero); + } + finally + { + if (instanceHandle != IntPtr.Zero) + MemoryFonts.FreeLibrary(instanceHandle); + } + } + + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr LoadLibraryEx(string moduleName, IntPtr reserved, uint flags); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + public static extern bool FreeLibrary(IntPtr instanceHandle); + + [DllImport("kernel32.dll", EntryPoint = "FindResourceW", CharSet = CharSet.Unicode)] + public static extern IntPtr FindResource( + IntPtr instanceHandle, + string resource, + IntPtr type); + + [DllImport("kernel32.dll")] + public static extern IntPtr LoadResource(IntPtr instanceHandle, IntPtr resourceHandle); + + [DllImport("kernel32.dll")] + public static extern int SizeofResource(IntPtr instanceHandle, IntPtr resourceHandle); + + [DllImport("kernel32.dll")] + public static extern IntPtr LockResource(IntPtr resourceHandle); + + [DllImport("gdi32.dll")] + public static extern IntPtr AddFontMemResourceEx( + IntPtr fontBuffer, + int fontButtonSize, + IntPtr reserved, + out uint fontsInstalled); + } +} diff --git a/Microsoft/Zune/PerfTrace/ActionType.cs b/Microsoft/Zune/PerfTrace/ActionType.cs new file mode 100644 index 0000000..cb687af --- /dev/null +++ b/Microsoft/Zune/PerfTrace/ActionType.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.PerfTrace.ActionType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace Microsoft.Zune.PerfTrace +{ + internal static class ActionType + { + internal const byte Info = 0; + internal const byte StartEvent = 1; + internal const byte EndEvent = 2; + internal const byte Checkpoint = 8; + } +} diff --git a/Microsoft/Zune/PerfTrace/EtwTraceProvider.cs b/Microsoft/Zune/PerfTrace/EtwTraceProvider.cs new file mode 100644 index 0000000..0f0b7e2 --- /dev/null +++ b/Microsoft/Zune/PerfTrace/EtwTraceProvider.cs @@ -0,0 +1,609 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.PerfTrace.EtwTraceProvider +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Win32; +using System; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace Microsoft.Zune.PerfTrace +{ + internal class EtwTraceProvider + { + private const ushort _version = 0; + private EtwTraceProvider.EtwProc _etwProc; + private ulong _registrationHandle; + private ulong _traceHandle; + private byte _level; + private uint _flags; + private bool _enabled; + + internal EtwTraceProvider(Guid controlGuid, string regPath) + { + this._level = (byte)0; + this._flags = 0U; + this._enabled = false; + this._traceHandle = 0UL; + this._registrationHandle = 0UL; + RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(regPath); + num = 1; + if (registryKey == null || !(registryKey.GetValue("EtwEnabled") is int num)) + ; + if (num <= 0) + { + this._enabled = false; + } + else + { + int num1 = (int)this.Register(controlGuid); + } + } + + ~EtwTraceProvider() + { + EtwTraceProvider.UnregisterTraceGuids(this._registrationHandle); + GC.KeepAlive((object)this._etwProc); + } + + internal uint Flags => this._flags; + + internal byte Level => this._level; + + internal bool IsEnabled => this._enabled; + + internal unsafe uint ControllerChangeCallback( + uint requestCode, + IntPtr context, + IntPtr bufferSize, + byte* byteBuffer) + { + try + { + EtwTraceProvider.BaseEvent* baseEventPtr = (EtwTraceProvider.BaseEvent*)byteBuffer; + switch (requestCode) + { + case 4: + this._traceHandle = baseEventPtr->HistoricalContext; + this._flags = (uint)EtwTraceProvider.GetTraceEnableFlags(baseEventPtr->HistoricalContext); + this._level = EtwTraceProvider.GetTraceEnableLevel(baseEventPtr->HistoricalContext); + if (this._flags == 0U && this._level == (byte)0) + { + this._flags = uint.MaxValue; + this._level = (byte)4; + } + this._enabled = true; + break; + case 5: + this._enabled = false; + this._traceHandle = 0UL; + this._level = (byte)0; + this._flags = 0U; + break; + default: + this._enabled = false; + this._traceHandle = 0UL; + break; + } + return 0; + } + catch (Exception ex) + { + switch (ex) + { + case NullReferenceException _: + case SEHException _: + throw; + default: + return 0; + } + } + } + + private unsafe uint Register(Guid controlGuid) + { + EtwTraceProvider.TraceGuidRegistration guidReg = new EtwTraceProvider.TraceGuidRegistration(); + Guid guid = new Guid(3029687280U, (ushort)15089, (ushort)18240, (byte)180, (byte)117, (byte)153, (byte)5, (byte)93, (byte)63, (byte)233, (byte)170); + this._etwProc = new EtwTraceProvider.EtwProc(this.ControllerChangeCallback); + guidReg.Guid = &guid; + guidReg.RegHandle = (void*)null; + return EtwTraceProvider.RegisterTraceGuids(this._etwProc, (void*)null, ref controlGuid, 1U, ref guidReg, (string)null, (string)null, out this._registrationHandle); + } + + internal void TraceEvent(byte level, Guid eventGuid, byte eventType) => this.TraceEvent(level, eventGuid, eventType, (object)null, (object)null); + + internal void TraceEvent(byte level, Guid eventGuid, byte eventType, object data0) => this.TraceEvent(level, eventGuid, eventType, data0, (object)null); + + internal void TraceEvent( + byte level, + Guid eventGuid, + byte eventType, + object data0, + object data1) + { + int num = (int)this.TraceEvent(level, eventGuid, eventType, data0, data1, (object)null, (object)null, (object)null, (object)null, (object)null, (object)null, (object)null); + } + + internal void TraceEvent( + byte level, + Guid eventGuid, + byte eventType, + object data0, + object data1, + object data2) + { + int num = (int)this.TraceEvent(level, eventGuid, eventType, data0, data1, data2, (object)null, (object)null, (object)null, (object)null, (object)null, (object)null); + } + + internal void TraceEvent( + byte level, + Guid eventGuid, + byte eventType, + object data0, + object data1, + object data2, + object data3) + { + int num = (int)this.TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, (object)null, (object)null, (object)null, (object)null, (object)null); + } + + internal void TraceEvent( + byte level, + Guid eventGuid, + byte eventType, + object data0, + object data1, + object data2, + object data3, + object data4) + { + int num = (int)this.TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, data4, (object)null, (object)null, (object)null, (object)null); + } + + internal void TraceEvent( + byte level, + Guid eventGuid, + byte eventType, + object data0, + object data1, + object data2, + object data3, + object data4, + object data5) + { + int num = (int)this.TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, data4, data5, (object)null, (object)null, (object)null); + } + + internal void TraceEvent( + byte level, + Guid eventGuid, + byte eventType, + object data0, + object data1, + object data2, + object data3, + object data4, + object data5, + object data6) + { + int num = (int)this.TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, data4, data5, data6, (object)null, (object)null); + } + + internal void TraceEvent( + byte level, + Guid eventGuid, + byte eventType, + object data0, + object data1, + object data2, + object data3, + object data4, + object data5, + object data6, + object data7) + { + int num = (int)this.TraceEvent(level, eventGuid, eventType, data0, data1, data2, data3, data4, data5, data6, data7, (object)null); + } + + internal unsafe uint TraceEvent( + byte level, + Guid eventGuid, + byte evtype, + object data0, + object data1, + object data2, + object data3, + object data4, + object data5, + object data6, + object data7, + object data8) + { + char* chPtr1 = stackalloc char[144]; + uint offSet = 0; + char* ptr = chPtr1; + int num1 = 0; + uint num2 = 0; + int num3 = 0; + string str1; + string str2 = str1 = ""; + string str3 = str1; + string str4 = str1; + string str5 = str1; + string str6 = str1; + string str7 = str1; + string str8 = str1; + string str9 = str1; + string str10 = str1; + EtwTraceProvider.BaseEvent baseEvent; + baseEvent.ClientContext = 0U; + baseEvent.Flags = 1179648U; + baseEvent.Guid = eventGuid; + baseEvent.EventType = evtype; + baseEvent.Level = level; + baseEvent.Version = (ushort)0; + if (data0 != null) + { + ++num2; + EtwTraceProvider.MofField* mofField = (EtwTraceProvider.MofField*)((UIntPtr) & baseEvent.UserData + (UIntPtr)num3++ * (UIntPtr)sizeof(EtwTraceProvider.MofField)); + if ((str10 = this.ProcessOneObject(data0, mofField, ptr, ref offSet)) != null) + num1 |= 1; + } + if (data1 != null) + { + ++num2; + EtwTraceProvider.MofField* mofField = (EtwTraceProvider.MofField*)((UIntPtr) & baseEvent.UserData + (UIntPtr)num3++ * (UIntPtr)sizeof(EtwTraceProvider.MofField)); + ptr = chPtr1 + offSet; + if ((str9 = this.ProcessOneObject(data1, mofField, ptr, ref offSet)) != null) + num1 |= 2; + } + if (data2 != null) + { + ++num2; + EtwTraceProvider.MofField* mofField = (EtwTraceProvider.MofField*)((UIntPtr) & baseEvent.UserData + (UIntPtr)num3++ * (UIntPtr)sizeof(EtwTraceProvider.MofField)); + ptr = chPtr1 + offSet; + if ((str8 = this.ProcessOneObject(data2, mofField, ptr, ref offSet)) != null) + num1 |= 4; + } + if (data3 != null) + { + ++num2; + EtwTraceProvider.MofField* mofField = (EtwTraceProvider.MofField*)((UIntPtr) & baseEvent.UserData + (UIntPtr)num3++ * (UIntPtr)sizeof(EtwTraceProvider.MofField)); + ptr = chPtr1 + offSet; + if ((str7 = this.ProcessOneObject(data3, mofField, ptr, ref offSet)) != null) + num1 |= 8; + } + if (data4 != null) + { + ++num2; + EtwTraceProvider.MofField* mofField = (EtwTraceProvider.MofField*)((UIntPtr) & baseEvent.UserData + (UIntPtr)num3++ * (UIntPtr)sizeof(EtwTraceProvider.MofField)); + ptr = chPtr1 + offSet; + if ((str6 = this.ProcessOneObject(data4, mofField, ptr, ref offSet)) != null) + num1 |= 16; + } + if (data5 != null) + { + ++num2; + EtwTraceProvider.MofField* mofField = (EtwTraceProvider.MofField*)((UIntPtr) & baseEvent.UserData + (UIntPtr)num3++ * (UIntPtr)sizeof(EtwTraceProvider.MofField)); + ptr = chPtr1 + offSet; + if ((str5 = this.ProcessOneObject(data5, mofField, ptr, ref offSet)) != null) + num1 |= 32; + } + if (data6 != null) + { + ++num2; + EtwTraceProvider.MofField* mofField = (EtwTraceProvider.MofField*)((UIntPtr) & baseEvent.UserData + (UIntPtr)num3++ * (UIntPtr)sizeof(EtwTraceProvider.MofField)); + ptr = chPtr1 + offSet; + if ((str4 = this.ProcessOneObject(data6, mofField, ptr, ref offSet)) != null) + num1 |= 64; + } + if (data7 != null) + { + ++num2; + EtwTraceProvider.MofField* mofField = (EtwTraceProvider.MofField*)((UIntPtr) & baseEvent.UserData + (UIntPtr)num3++ * (UIntPtr)sizeof(EtwTraceProvider.MofField)); + ptr = chPtr1 + offSet; + if ((str3 = this.ProcessOneObject(data7, mofField, ptr, ref offSet)) != null) + num1 |= 128; + } + if (data8 != null) + { + uint num4 = num2 + 1U; + EtwTraceProvider.MofField* mofField = (EtwTraceProvider.MofField*)((UIntPtr) & baseEvent.UserData + (UIntPtr)num3++ * (UIntPtr)sizeof(EtwTraceProvider.MofField)); + ptr = chPtr1 + offSet; + if ((str2 = this.ProcessOneObject(data8, mofField, ptr, ref offSet)) != null) + num1 |= 256; + } + if (ptr - chPtr1 > 144L) + return 1; + uint num5; + fixed (char* chPtr2 = str10) + fixed (char* chPtr3 = str9) + fixed (char* chPtr4 = str8) + fixed (char* chPtr5 = str7) + fixed (char* chPtr6 = str6) + fixed (char* chPtr7 = str5) + fixed (char* chPtr8 = str4) + fixed (char* chPtr9 = str3) + fixed (char* chPtr10 = str2) + { + int index1 = 0; + if ((num1 & 1) != 0) + { + (&baseEvent.UserData)[index1].DataLength = (uint)((str10.Length + 1) * 2); + (&baseEvent.UserData)[index1].DataPointer = (void*)chPtr2; + } + int index2 = index1 + 1; + if ((num1 & 2) != 0) + { + (&baseEvent.UserData)[index2].DataLength = (uint)((str9.Length + 1) * 2); + (&baseEvent.UserData)[index2].DataPointer = (void*)chPtr3; + } + int index3 = index2 + 1; + if ((num1 & 4) != 0) + { + (&baseEvent.UserData)[index3].DataLength = (uint)((str8.Length + 1) * 2); + (&baseEvent.UserData)[index3].DataPointer = (void*)chPtr4; + } + int index4 = index3 + 1; + if ((num1 & 8) != 0) + { + (&baseEvent.UserData)[index4].DataLength = (uint)((str7.Length + 1) * 2); + (&baseEvent.UserData)[index4].DataPointer = (void*)chPtr5; + } + int index5 = index4 + 1; + if ((num1 & 16) != 0) + { + (&baseEvent.UserData)[index5].DataLength = (uint)((str6.Length + 1) * 2); + (&baseEvent.UserData)[index5].DataPointer = (void*)chPtr6; + } + int index6 = index5 + 1; + if ((num1 & 32) != 0) + { + (&baseEvent.UserData)[index6].DataLength = (uint)((str5.Length + 1) * 2); + (&baseEvent.UserData)[index6].DataPointer = (void*)chPtr7; + } + int index7 = index6 + 1; + if ((num1 & 64) != 0) + { + (&baseEvent.UserData)[index7].DataLength = (uint)((str4.Length + 1) * 2); + (&baseEvent.UserData)[index7].DataPointer = (void*)chPtr8; + } + int index8 = index7 + 1; + if ((num1 & 128) != 0) + { + (&baseEvent.UserData)[index8].DataLength = (uint)((str3.Length + 1) * 2); + (&baseEvent.UserData)[index8].DataPointer = (void*)chPtr9; + } + int index9 = index8 + 1; + if ((num1 & 256) != 0) + { + (&baseEvent.UserData)[index9].DataLength = (uint)((str2.Length + 1) * 2); + (&baseEvent.UserData)[index9].DataPointer = (void*)chPtr10; + } + baseEvent.BufferSize = (uint)(48 + num3 * sizeof(EtwTraceProvider.MofField)); + num5 = EtwTraceProvider.TraceEvent(this._traceHandle, (char*)&baseEvent); + } + return num5; + } + + private unsafe string ProcessOneObject( + object data, + EtwTraceProvider.MofField* mofField, + char* ptr, + ref uint offSet) + { + return this.EncodeObject(data, mofField, ptr, ref offSet); + } + + private unsafe string EncodeObject( + object data, + EtwTraceProvider.MofField* mofField, + char* ptr, + ref uint offSet) + { + if (data == null) + { + mofField->DataLength = 0U; + mofField->DataPointer = (void*)null; + return (string)null; + } + Type type = data.GetType(); + if (type.IsEnum) + data = Convert.ChangeType(data, Enum.GetUnderlyingType(type), (IFormatProvider)CultureInfo.InvariantCulture); + switch (data) + { + case sbyte num: + mofField->DataLength = 1U; + sbyte* numPtr1 = (sbyte*)ptr; + *numPtr1 = num; + mofField->DataPointer = (void*)numPtr1; + ++offSet; + break; + case byte num: + mofField->DataLength = 1U; + byte* numPtr2 = (byte*)ptr; + *numPtr2 = num; + mofField->DataPointer = (void*)numPtr2; + ++offSet; + break; + case short num: + mofField->DataLength = 2U; + short* numPtr3 = (short*)ptr; + *numPtr3 = num; + mofField->DataPointer = (void*)numPtr3; + offSet += 2U; + break; + case ushort num: + mofField->DataLength = 2U; + ushort* numPtr4 = (ushort*)ptr; + *numPtr4 = num; + mofField->DataPointer = (void*)numPtr4; + offSet += 2U; + break; + case int num: + mofField->DataLength = 4U; + int* numPtr5 = (int*)ptr; + *numPtr5 = num; + mofField->DataPointer = (void*)numPtr5; + offSet += 4U; + break; + case uint num: + mofField->DataLength = 4U; + uint* numPtr6 = (uint*)ptr; + *numPtr6 = num; + mofField->DataPointer = (void*)numPtr6; + offSet += 4U; + break; + case long num: + mofField->DataLength = 8U; + long* numPtr7 = (long*)ptr; + *numPtr7 = num; + mofField->DataPointer = (void*)numPtr7; + offSet += 8U; + break; + case ulong num: + mofField->DataLength = 8U; + ulong* numPtr8 = (ulong*)ptr; + *numPtr8 = num; + mofField->DataPointer = (void*)numPtr8; + offSet += 8U; + break; + case char ch: + mofField->DataLength = 2U; + char* chPtr = ptr; + *chPtr = ch; + mofField->DataPointer = (void*)chPtr; + offSet += 2U; + break; + case float num: + mofField->DataLength = 4U; + float* numPtr9 = (float*)ptr; + *numPtr9 = num; + mofField->DataPointer = (void*)numPtr9; + offSet += 4U; + break; + case double num: + mofField->DataLength = 8U; + double* numPtr10 = (double*)ptr; + *numPtr10 = num; + mofField->DataPointer = (void*)numPtr10; + offSet += 8U; + break; + case bool flag: + mofField->DataLength = 1U; + bool* flagPtr = (bool*)ptr; + *flagPtr = flag; + mofField->DataPointer = (void*)flagPtr; + ++offSet; + break; + case Decimal num: + mofField->DataLength = 16U; + Decimal* numPtr11 = (Decimal*)ptr; + *numPtr11 = num; + mofField->DataPointer = (void*)numPtr11; + offSet += 16U; + break; + default: + return data.ToString(); + } + return (string)null; + } + + [DllImport("advapi32", CharSet = CharSet.Unicode)] + internal static extern int GetTraceEnableFlags(ulong traceHandle); + + [DllImport("advapi32", CharSet = CharSet.Unicode)] + internal static extern byte GetTraceEnableLevel(ulong traceHandle); + + [DllImport("advapi32", EntryPoint = "RegisterTraceGuidsW", CharSet = CharSet.Unicode)] + internal static extern unsafe uint RegisterTraceGuids( + [In] EtwTraceProvider.EtwProc cbFunc, + [In] void* context, + [In] ref Guid controlGuid, + [In] uint guidCount, + ref EtwTraceProvider.TraceGuidRegistration guidReg, + [In] string mofImagePath, + [In] string mofResourceName, + out ulong regHandle); + + [DllImport("advapi32", CharSet = CharSet.Unicode)] + internal static extern int UnregisterTraceGuids(ulong regHandle); + + [DllImport("advapi32", CharSet = CharSet.Unicode)] + internal static extern unsafe uint TraceEvent(ulong traceHandle, char* header); + + internal sealed class RequestCodes + { + internal const uint GetAllData = 0; + internal const uint GetSingleInstance = 1; + internal const uint SetSingleInstance = 2; + internal const uint SetSingleItem = 3; + internal const uint EnableEvents = 4; + internal const uint DisableEvents = 5; + internal const uint EnableCollection = 6; + internal const uint DisableCollection = 7; + internal const uint RegInfo = 8; + internal const uint ExecuteMethod = 9; + + private RequestCodes() + { + } + } + + [StructLayout(LayoutKind.Explicit, Size = 16)] + internal struct MofField + { + [FieldOffset(0)] + internal unsafe void* DataPointer; + [FieldOffset(8)] + internal uint DataLength; + [FieldOffset(12)] + internal uint DataType; + } + + [StructLayout(LayoutKind.Explicit, Size = 304)] + internal struct BaseEvent + { + [FieldOffset(0)] + internal uint BufferSize; + [FieldOffset(4)] + internal byte EventType; + [FieldOffset(5)] + internal byte Level; + [FieldOffset(6)] + internal ushort Version; + [FieldOffset(8)] + internal ulong HistoricalContext; + [FieldOffset(16)] + internal long TimeStamp; + [FieldOffset(24)] + internal Guid Guid; + [FieldOffset(40)] + internal uint ClientContext; + [FieldOffset(44)] + internal uint Flags; + [FieldOffset(48)] + internal EtwTraceProvider.MofField UserData; + } + + internal unsafe delegate uint EtwProc( + uint requestCode, + IntPtr requestContext, + IntPtr bufferSize, + byte* buffer); + + internal struct CSTRACE_GUID_REGISTRATION + { + internal unsafe Guid* Guid; + internal uint RegHandle; + } + + internal struct TraceGuidRegistration + { + internal unsafe Guid* Guid; + internal unsafe void* RegHandle; + } + } +} diff --git a/Microsoft/Zune/PerfTrace/PerfTrace.cs b/Microsoft/Zune/PerfTrace/PerfTrace.cs new file mode 100644 index 0000000..6624d5f --- /dev/null +++ b/Microsoft/Zune/PerfTrace/PerfTrace.cs @@ -0,0 +1,91 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.PerfTrace.PerfTrace +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace Microsoft.Zune.PerfTrace +{ + public sealed class PerfTrace + { + private static readonly EtwTraceProvider _EventProvider; + internal static readonly Guid ZUNE_ETW_CONTROL_GUID = new Guid(1496399467U, (ushort)53017, (ushort)20072, (byte)142, (byte)243, (byte)135, (byte)107, (byte)12, (byte)8, (byte)232, (byte)1); + internal static readonly Guid PERFTRACE_LAUNCHEVENT_GUID = new Guid(1815200785, (short)23272, (short)18087, (byte)190, (byte)166, (byte)76, (byte)236, (byte)117, (byte)51, (byte)196, (byte)218); + internal static readonly Guid PerftraceUICollectionGuid = new Guid(235915657U, (ushort)37778, (ushort)18043, (byte)146, (byte)252, (byte)128, (byte)212, (byte)193, (byte)153, (byte)154, (byte)151); + + private PerfTrace() + { + } + + static PerfTrace() => Microsoft.Zune.PerfTrace.PerfTrace._EventProvider = new EtwTraceProvider(Microsoft.Zune.PerfTrace.PerfTrace.ZUNE_ETW_CONTROL_GUID, "SOFTWARE\\Microsoft\\Zune"); + + internal static bool IsEnabled( + EtwTraceProvider provider, + Microsoft.Zune.PerfTrace.PerfTrace.Flags flag, + Microsoft.Zune.PerfTrace.PerfTrace.Level level) + { + return (uint)level <= (uint)provider.Level && provider.IsEnabled && (flag & (Microsoft.Zune.PerfTrace.PerfTrace.Flags)provider.Flags) > ~Microsoft.Zune.PerfTrace.PerfTrace.Flags.All; + } + + internal static bool IsEnabled(Microsoft.Zune.PerfTrace.PerfTrace.Flags flags, Microsoft.Zune.PerfTrace.PerfTrace.Level level) => Microsoft.Zune.PerfTrace.PerfTrace.IsEnabled(Microsoft.Zune.PerfTrace.PerfTrace._EventProvider, flags, level); + + internal static bool IsEnabled(Microsoft.Zune.PerfTrace.PerfTrace.Flags flags) => Microsoft.Zune.PerfTrace.PerfTrace.IsEnabled(Microsoft.Zune.PerfTrace.PerfTrace._EventProvider, flags, Microsoft.Zune.PerfTrace.PerfTrace.Level.Normal); + + public static void PERFTRACE_LAUNCHEVENT(Microsoft.Zune.PerfTrace.PerfTrace.LAUNCH_EVENT launchEvent, uint data) + { + if (!Microsoft.Zune.PerfTrace.PerfTrace.IsEnabled(Microsoft.Zune.PerfTrace.PerfTrace.Flags.Launch, Microsoft.Zune.PerfTrace.PerfTrace.Level.Normal)) + return; + Microsoft.Zune.PerfTrace.PerfTrace._EventProvider.TraceEvent((byte)4, Microsoft.Zune.PerfTrace.PerfTrace.PERFTRACE_LAUNCHEVENT_GUID, (byte)launchEvent, (object)data); + } + + public static void TraceUICollectionEvent(UICollectionEvent traceEvent, string eventDetail) + { + if (!Microsoft.Zune.PerfTrace.PerfTrace.IsEnabled(Microsoft.Zune.PerfTrace.PerfTrace.Flags.Collection, Microsoft.Zune.PerfTrace.PerfTrace.Level.Normal)) + return; + Microsoft.Zune.PerfTrace.PerfTrace._EventProvider.TraceEvent((byte)4, Microsoft.Zune.PerfTrace.PerfTrace.PerftraceUICollectionGuid, (byte)traceEvent, (object)eventDetail); + } + + [System.Flags] + internal enum Flags : uint + { + DB_Mutex = 1, + Launch = 2, + QRS = 4, + Collection = 16, // 0x00000010 + All = 4294967295, // 0xFFFFFFFF + } + + internal enum Level : byte + { + Fatal = 1, + Error = 2, + Warning = 3, + Normal = 4, + Verbose = 5, + } + + internal enum Tag + { + COMPONENT1 = 1129270577, // 0x434F4D31 + COMPONENT2 = 1129270578, // 0x434F4D32 + } + + public enum LAUNCH_EVENT + { + LAUNCHER_AT_WINMAIN = 1, + WINMAIN_ABOUT_TO_LAUNCH = 2, + START_PHASE2_INIT = 3, + END_PHASE2_INIT = 4, + ZUNENATIVELIB_STARTUP = 5, + LAUNCHING_MANAGED_APP = 6, + IN_MANAGED_LAUNCH = 7, + REQUEST_UI_LOAD = 8, + REQUEST_UI_LOAD_COMPLETE = 9, + QUERYDB_BEGIN = 10, // 0x0000000A + QUERYDB_END = 11, // 0x0000000B + DEVICE_CONNECTED = 12, // 0x0000000C + } + } +} diff --git a/Microsoft/Zune/PerfTrace/UICollectionEvent.cs b/Microsoft/Zune/PerfTrace/UICollectionEvent.cs new file mode 100644 index 0000000..94f0f74 --- /dev/null +++ b/Microsoft/Zune/PerfTrace/UICollectionEvent.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.PerfTrace.UICollectionEvent +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace Microsoft.Zune.PerfTrace +{ + public enum UICollectionEvent + { + LibraryQueryIssued = 1, + LibraryQueryResultsAvailable = 2, + LibraryQueryResultsVisible = 3, + MusicLibraryViewCommandInvoked = 4, + DeviceIconItemDropped = 5, + SearchQueryIssued = 6, + SearchQueryResultsAvailable = 7, + SearchQueryResultsVisible = 8, + MarketplaceQueriesIssued = 9, + MarketplaceQueriesResultsAvailable = 10, // 0x0000000A + MarketplaceQueriesResultsVisible = 11, // 0x0000000B + PlayRequestIssued = 12, // 0x0000000C + PlayRequestComplete = 13, // 0x0000000D + BulkEventsPushBegin = 14, // 0x0000000E + BulkEventsPushEnd = 15, // 0x0000000F + RecommendationQueriesIssued = 16, // 0x00000010 + RecommendationQueriesResultsAvailable = 17, // 0x00000011 + RecommendationQueriesResultsVisible = 18, // 0x00000012 + SocialQueriesIssued = 19, // 0x00000013 + SocialQueriesResultsAvailable = 20, // 0x00000014 + SocialQueriesResultsVisible = 21, // 0x00000015 + MixQueriesIssued = 22, // 0x00000016 + MixQueriesResultsAvailable = 23, // 0x00000017 + MixQueriesResultsVisible = 24, // 0x00000018 + QuickplayQueriesIssued = 25, // 0x00000019 + QuickplayQueriesResultsAvailable = 26, // 0x0000001A + QuickplayQueriesResultsVisible = 27, // 0x0000001B + DataProviderQueryBegin = 28, // 0x0000001C + DataProviderQueryComplete = 29, // 0x0000001D + QuickMixBegin = 30, // 0x0000001E + QuickMixUpdate = 31, // 0x0000001F + QuickMixComplete = 32, // 0x00000020 + MarketplaceSearchResultArtistClicked = 33, // 0x00000021 + SearchHintCollectionQueryArtistBegin = 34, // 0x00000022 + SearchHintCollectionQueryArtistComplete = 35, // 0x00000023 + SearchHintMarketplaceQueryPrefixBegin = 36, // 0x00000024 + SearchHintMarketplaceQueryPrefixComplete = 37, // 0x00000025 + SyncStatusVisible = 38, // 0x00000026 + } +} diff --git a/Microsoft/Zune/Shell/AggregateDataProviderQuery.cs b/Microsoft/Zune/Shell/AggregateDataProviderQuery.cs new file mode 100644 index 0000000..245cd25 --- /dev/null +++ b/Microsoft/Zune/Shell/AggregateDataProviderQuery.cs @@ -0,0 +1,110 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.AggregateDataProviderQuery +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; + +namespace Microsoft.Zune.Shell +{ + public class AggregateDataProviderQuery : DataProviderQuery + { + private List _currentQueries = new List(); + + internal static void Register() => Application.RegisterDataProvider("Aggregate", new DataProviderQueryFactory(AggregateDataProviderQuery.ConstructAggregateDataProviderQuery)); + + internal static DataProviderQuery ConstructAggregateDataProviderQuery( + object queryTypeCookie) + { + return (DataProviderQuery)new AggregateDataProviderQuery(queryTypeCookie); + } + + protected AggregateDataProviderQuery(object queryTypeCookie) + : base(queryTypeCookie) + { + } + + protected override void BeginExecute() + { + this.InitializeCurrentQueries(); + this.RefreshCurrentQueries(); + } + + private void InitializeCurrentQueries() + { + this.Result = (object)null; + this.UnsubscribeFromCurrentQueries(); + this._currentQueries.Clear(); + if (this.GetProperty("Queries") is IList property) + { + foreach (object obj in (IEnumerable)property) + { + if (obj is DataProviderQuery dataProviderQuery) + this._currentQueries.Add(dataProviderQuery); + } + } + this.SubscribeToCurrentQueries(); + } + + private void RefreshCurrentQueries() + { + foreach (DataProviderQuery currentQuery in this._currentQueries) + currentQuery.Refresh(); + } + + private void SubscribeToCurrentQueries() + { + foreach (DataProviderQuery currentQuery in this._currentQueries) + currentQuery.PropertyChanged += new PropertyChangedEventHandler(this.OnQueryPropertyChanged); + } + + private void UnsubscribeFromCurrentQueries() + { + foreach (DataProviderQuery currentQuery in this._currentQueries) + currentQuery.PropertyChanged -= new PropertyChangedEventHandler(this.OnQueryPropertyChanged); + } + + private void OnQueryPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!("Status" == args.PropertyName)) + return; + this.UpdateStatusAndResult(); + } + + private void UpdateStatusAndResult() + { + int num = 0; + bool flag = false; + foreach (DataProviderQuery currentQuery in this._currentQueries) + { + if (DataProviderQueryStatus.Complete == currentQuery.Status || DataProviderQueryStatus.Error == currentQuery.Status) + { + ++num; + if (DataProviderQueryStatus.Error == currentQuery.Status) + flag = true; + } + } + if (this._currentQueries.Count == num) + { + this.Status = DataProviderQueryStatus.ProcessingData; + ArrayList arrayList = new ArrayList(); + foreach (DataProviderQuery currentQuery in this._currentQueries) + arrayList.Add(currentQuery.Result); + this.Result = (object)arrayList; + this.Status = flag ? DataProviderQueryStatus.Error : DataProviderQueryStatus.Complete; + } + else + this.Status = DataProviderQueryStatus.RequestingData; + } + + protected override void OnDispose() + { + this.UnsubscribeFromCurrentQueries(); + base.OnDispose(); + } + } +} diff --git a/Microsoft/Zune/Shell/CanAddMediaArgs.cs b/Microsoft/Zune/Shell/CanAddMediaArgs.cs new file mode 100644 index 0000000..abbe1f5 --- /dev/null +++ b/Microsoft/Zune/Shell/CanAddMediaArgs.cs @@ -0,0 +1,13 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.CanAddMediaArgs +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace Microsoft.Zune.Shell +{ + internal class CanAddMediaArgs + { + public bool Aborted; + } +} diff --git a/Microsoft/Zune/Shell/CommandLineArgument.cs b/Microsoft/Zune/Shell/CommandLineArgument.cs new file mode 100644 index 0000000..51ac6ec --- /dev/null +++ b/Microsoft/Zune/Shell/CommandLineArgument.cs @@ -0,0 +1,53 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.CommandLineArgument +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Microsoft.Zune.Shell +{ + internal struct CommandLineArgument + { + public string Name; + public string Value; + + public CommandLineArgument(string name, string value) + { + this.Name = name != null ? name.ToLower(CultureInfo.InvariantCulture) : throw new ArgumentNullException(nameof(name)); + this.Value = value; + } + + public static CommandLineArgument[] ParseArgs( + string[] arArgs, + string stDefaultName) + { + List commandLineArgumentList = new List(); + foreach (string arArg in arArgs) + { + if (string.IsNullOrEmpty(arArg)) + throw new ArgumentException(nameof(arArgs)); + string str = (string)null; + string name; + if (arArg[0] == '-' || arArg[0] == '/') + name = arArg.Substring(1, arArg.Length - 1); + else if (stDefaultName != null) + name = stDefaultName + ":" + arArg; + else + continue; + int length = name.IndexOf(':'); + if (length != -1) + { + str = name.Substring(length + 1).Trim('"'); + name = name.Substring(0, length); + } + CommandLineArgument commandLineArgument = new CommandLineArgument(name, str); + commandLineArgumentList.Add(commandLineArgument); + } + return commandLineArgumentList.ToArray(); + } + } +} diff --git a/Microsoft/Zune/Shell/ILaunchZuneShell.cs b/Microsoft/Zune/Shell/ILaunchZuneShell.cs new file mode 100644 index 0000000..afcef14 --- /dev/null +++ b/Microsoft/Zune/Shell/ILaunchZuneShell.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.ILaunchZuneShell +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Zune.Shell +{ + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("79493c51-2a79-410c-ab77-da1ead887f11")] + [ComImport] + internal interface ILaunchZuneShell + { + IntPtr GetLaunchDelegate(string args, IntPtr hWndSplashScreen); + + IntPtr GetRenderWindow(); + + void ProcessMessageFromCommandLine(string cmdLine); + + void SetDesktopLockState(bool locked); + } +} diff --git a/Microsoft/Zune/Shell/InitializationFailsafe.cs b/Microsoft/Zune/Shell/InitializationFailsafe.cs new file mode 100644 index 0000000..b84c013 --- /dev/null +++ b/Microsoft/Zune/Shell/InitializationFailsafe.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.InitializationFailsafe +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Threading; + +namespace Microsoft.Zune.Shell +{ + internal class InitializationFailsafe + { + private bool _complete; + private DeferredInvokeHandler _onCompleteHandler; + private System.Threading.Timer _failsafeTimer; + + public void Initialize(DeferredInvokeHandler onCompleteHandler) + { + if (this._complete) + { + Application.DeferredInvoke(onCompleteHandler, DeferredInvokePriority.Low); + } + else + { + int dueTime = 30000; + this._onCompleteHandler = onCompleteHandler; + this._failsafeTimer = new System.Threading.Timer(new TimerCallback(this.FailsafeCallback), (object)null, dueTime, -1); + } + } + + public void Complete() + { + if (this._complete) + return; + this._complete = true; + if (this._onCompleteHandler != null) + Application.DeferredInvoke(this._onCompleteHandler, DeferredInvokePriority.Low); + if (this._failsafeTimer == null) + return; + this._failsafeTimer.Change(-1, -1); + } + + private void FailsafeCallback(object state) + { + if (this._complete) + return; + this._complete = true; + Application.DeferredInvoke(this._onCompleteHandler, DeferredInvokePriority.Low); + } + } +} diff --git a/Microsoft/Zune/Shell/LaunchZuneShell.cs b/Microsoft/Zune/Shell/LaunchZuneShell.cs new file mode 100644 index 0000000..5ef5e74 --- /dev/null +++ b/Microsoft/Zune/Shell/LaunchZuneShell.cs @@ -0,0 +1,41 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.LaunchZuneShell +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Zune.Shell +{ + [ComVisible(true)] + [ClassInterface(ClassInterfaceType.None)] + [Guid("53048eb3-0906-4bd2-890d-48daf1f25413")] + [ComDefaultInterface(typeof(ILaunchZuneShell))] + public sealed class LaunchZuneShell : ILaunchZuneShell + { + private static LaunchZuneShell.LaunchDelegate s_launch; + private static string s_args; + private static IntPtr s_hWndSplashScreen; + + [STAThread] + public IntPtr GetLaunchDelegate(string args, IntPtr hWndSplashScreen) + { + LaunchZuneShell.s_args = args; + LaunchZuneShell.s_hWndSplashScreen = hWndSplashScreen; + LaunchZuneShell.s_launch = new LaunchZuneShell.LaunchDelegate(this.LaunchZuneShellHelper); + return Marshal.GetFunctionPointerForDelegate((Delegate)LaunchZuneShell.s_launch); + } + + private int LaunchZuneShellHelper() => ZuneApplication.Launch(LaunchZuneShell.s_args, LaunchZuneShell.s_hWndSplashScreen); + + public IntPtr GetRenderWindow() => ZuneApplication.GetRenderWindow(); + + public void ProcessMessageFromCommandLine(string args) => ZuneApplication.ProcessMessageFromCommandLine(args); + + public void SetDesktopLockState(bool locked) => ZuneApplication.SetDesktopLockState(locked); + + private delegate int LaunchDelegate(); + } +} diff --git a/Microsoft/Zune/Shell/SetupInstallContext.cs b/Microsoft/Zune/Shell/SetupInstallContext.cs new file mode 100644 index 0000000..1906aea --- /dev/null +++ b/Microsoft/Zune/Shell/SetupInstallContext.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.SetupInstallContext +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace Microsoft.Zune.Shell +{ + public enum SetupInstallContext + { + Zune, + WindowsPhone, + } +} diff --git a/Microsoft/Zune/Shell/StandAlone.cs b/Microsoft/Zune/Shell/StandAlone.cs new file mode 100644 index 0000000..ec4b11a --- /dev/null +++ b/Microsoft/Zune/Shell/StandAlone.cs @@ -0,0 +1,151 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.StandAlone +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Win32; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace Microsoft.Zune.Shell +{ + internal class StandAlone + { + public static Hashtable Startup(string[] args, string defaultCommandLineSwitch) + { + WindowSize windowSize = new WindowSize(1012, 693); + string str = (string)null; + bool flag1 = false; + bool flag2 = false; + Hashtable hashtable = new Hashtable(); + bool flag3 = false; + if (args != null) + { + foreach (CommandLineArgument commandLineArgument in CommandLineArgument.ParseArgs(args, defaultCommandLineSwitch)) + { + switch (commandLineArgument.Name) + { + case "gdi": + Application.RenderingType = RenderingType.GDI; + flag3 = true; + break; + case "switchtogdi": + ClientConfiguration.GeneralSettings.RenderingType = 0; + break; + case "dx9": + Application.RenderingType = RenderingType.DX9; + flag3 = true; + break; + case "size": + try + { + windowSize = StandAlone.ParseSize(commandLineArgument.Value); + break; + } + catch (FormatException ex) + { + break; + } + catch (ArgumentException ex) + { + break; + } + case "minimized": + flag2 = true; + break; + case "nativeframe": + flag1 = true; + break; + case "animations": + try + { + Application.AnimationsEnabled = bool.Parse(commandLineArgument.Value); + break; + } + catch (FormatException ex) + { + break; + } + default: + hashtable[(object)commandLineArgument.Name] = (object)commandLineArgument.Value; + break; + } + } + } + if (ClientConfiguration.GeneralSettings.UseGDI) + { + ClientConfiguration.GeneralSettings.RenderingType = 0; + ClientConfiguration.GeneralSettings.UseGDI = false; + } + if (!flag3) + { + Application.RenderingType = (RenderingType)ClientConfiguration.GeneralSettings.RenderingType; + Application.RenderingQuality = (RenderingQuality)ClientConfiguration.GeneralSettings.RenderingQuality; + } + if (str != null) + { + if (str == "ltr") + Application.IsRTL = false; + else if (str == "rtl") + Application.IsRTL = true; + } + Application.AnimationsEnabled = ClientConfiguration.GeneralSettings.AnimationsEnabled; + Application.Initialize(); + Application.Window.InitialClientSize = windowSize; + object obj = Registry.GetValue(ZuneUI.Shell.SettingsRegistryPath, "WindowPosition", (object)null); + if (obj != null) + { + if (obj is string) + { + try + { + if (!flag2) + Application.Window.SetSavedInitialPosition((string)obj); + else + Application.Window.SetSavedInitialPosition((string)obj, WindowState.Minimized); + } + catch (ArgumentException ex) + { + } + } + } + Application.Window.RespectsStartupSettings = true; + Application.Window.InitialPositionPolicy = WindowPositionPolicy.CenterOnWorkArea | WindowPositionPolicy.ConstrainToWorkArea; + Application.Window.ShowWindowFrame = flag1; + Application.Window.SetBackgroundColor(ZuneUI.Shell.WindowColorFromRGB(ClientConfiguration.Shell.BackgroundColor)); + if (!flag2) + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + Windowing.ForceSetForegroundWindow(Application.Window.Handle); + }, DeferredInvokePriority.Low); + return hashtable; + } + + private static WindowSize ParseSize(string argument) + { + int width = 0; + int height = 0; + string[] strArray = argument.Split(','); + if (strArray.Length == 2) + { + width = int.Parse(strArray[0]); + height = int.Parse(strArray[1]); + } + return new WindowSize(width, height); + } + + public static void Run(DeferredInvokeHandler initialLoadComplete) + { + Application.Run(initialLoadComplete); + if (TaskbarPlayer.Instance.ToolbarVisible) + return; + Registry.SetValue(ZuneUI.Shell.SettingsRegistryPath, "WindowPosition", (object)Application.Window.GetSavedPosition(true)); + } + + public static void Shutdown() => Application.Shutdown(); + } +} diff --git a/Microsoft/Zune/Shell/TraceSwitches.cs b/Microsoft/Zune/Shell/TraceSwitches.cs new file mode 100644 index 0000000..56df552 --- /dev/null +++ b/Microsoft/Zune/Shell/TraceSwitches.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.TraceSwitches +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace Microsoft.Zune.Shell +{ + internal static class TraceSwitches + { + private static ZuneTraceSwitch collectionSwitch; + private static ZuneTraceSwitch shellSwitch; + private static ZuneTraceSwitch dataProviderSwitch; + + public static ZuneTraceSwitch CollectionSwitch + { + get + { + if (TraceSwitches.collectionSwitch == null) + TraceSwitches.collectionSwitch = new ZuneTraceSwitch("Collection", "Collection page traces"); + return TraceSwitches.collectionSwitch; + } + } + + public static ZuneTraceSwitch ShellSwitch + { + get + { + if (TraceSwitches.shellSwitch == null) + TraceSwitches.shellSwitch = new ZuneTraceSwitch("Shell", "Shell traces"); + return TraceSwitches.shellSwitch; + } + } + + public static ZuneTraceSwitch DataProviderSwitch + { + get + { + if (TraceSwitches.dataProviderSwitch == null) + TraceSwitches.dataProviderSwitch = new ZuneTraceSwitch("DataProvider", "Data provider traces"); + return TraceSwitches.dataProviderSwitch; + } + } + } +} diff --git a/Microsoft/Zune/Shell/ViewTimeLogger.cs b/Microsoft/Zune/Shell/ViewTimeLogger.cs new file mode 100644 index 0000000..4bf7207 --- /dev/null +++ b/Microsoft/Zune/Shell/ViewTimeLogger.cs @@ -0,0 +1,102 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.ViewTimeLogger +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; + +namespace Microsoft.Zune.Shell +{ + public class ViewTimeLogger + { + private bool _inCompactMode; + private bool _shutdown; + private ViewTimeLogger.LogHelper _compactModeLog = new ViewTimeLogger.LogHelper(SQMDataId.CompactModeViewTime); + private ViewTimeLogger.LogHelper _mixViewLog = new ViewTimeLogger.LogHelper(SQMDataId.MixViewTime); + private ViewTimeLogger.LogHelper _collectionViewLog; + private static ViewTimeLogger _viewTimeLogger; + + private ViewTimeLogger() + { + } + + public void Shutdown() + { + this._compactModeLog.Stop(); + this._mixViewLog.Stop(); + if (this._collectionViewLog != null) + this._collectionViewLog.Stop(); + this._shutdown = true; + } + + public static ViewTimeLogger Instance + { + get + { + if (ViewTimeLogger._viewTimeLogger == null) + ViewTimeLogger._viewTimeLogger = new ViewTimeLogger(); + return ViewTimeLogger._viewTimeLogger; + } + } + + public void ViewChanged(SQMDataId viewSQMId) + { + if (this._collectionViewLog != null && viewSQMId != this._collectionViewLog.LogId) + { + this._collectionViewLog.Stop(); + this._collectionViewLog = (ViewTimeLogger.LogHelper)null; + } + if (viewSQMId == SQMDataId.Invalid || this._collectionViewLog != null) + return; + this._collectionViewLog = new ViewTimeLogger.LogHelper(viewSQMId); + if (this._inCompactMode) + return; + this._collectionViewLog.Start(); + } + + public void InCompactMode(bool inCompactMode) + { + this._inCompactMode = inCompactMode; + if (this._inCompactMode) + { + this._compactModeLog.Start(); + if (this._collectionViewLog == null) + return; + this._collectionViewLog.Stop(); + } + else + { + this._compactModeLog.Stop(); + if (this._collectionViewLog == null) + return; + this._collectionViewLog.Start(); + } + } + + public void EnterMixView() => this._mixViewLog.Start(); + + public void LeaveMixView() => this._mixViewLog.Stop(); + + private class LogHelper + { + private readonly SQMDataId _logId; + private DateTime _start; + + public LogHelper(SQMDataId logId) => this._logId = logId; + + public void Start() => this._start = DateTime.Now; + + public void Stop() + { + if (!(this._start != DateTime.MinValue)) + return; + SQMLog.Log(this._logId, (int)DateTime.Now.Subtract(this._start).TotalSeconds); + this._start = DateTime.MinValue; + } + + public SQMDataId LogId => this._logId; + } + } +} diff --git a/Microsoft/Zune/Shell/ZuneApplication.cs b/Microsoft/Zune/Shell/ZuneApplication.cs new file mode 100644 index 0000000..f22dba3 --- /dev/null +++ b/Microsoft/Zune/Shell/ZuneApplication.cs @@ -0,0 +1,571 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.ZuneApplication +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Win32; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Messaging; +using Microsoft.Zune.Service; +using Microsoft.Zune.Subscription; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Globalization; +using System.IO; +using System.Text.RegularExpressions; +using System.Threading; +using UIXControls; +using ZuneUI; +using ZuneXml; + +namespace Microsoft.Zune.Shell +{ + public class ZuneApplication + { + private const string ResourceDllName = "ZuneShellResources.dll"; + private const int ApplicationIconResourceId = 1; + private static ZuneLibrary _zuneLibrary; + private static bool _desktopLocked = false; + private static bool _phase2InitComplete; + private static List _unprocessedAppArgs; + private static ManualResetEvent _transientTableCleanupComplete = new ManualResetEvent(false); + private static LaunchFromShellHelper _currentShellCommand; + private static InteropNotifications _interopNotifications; + private static IntPtr _hWndSplashScreen; + private static bool _dbRebuilt; + private static AppInitializationSequencer _appInitializationSequencer; + private static InitializationFailsafe _initializationFailsafe; + private static QuickMixProgress _quickMixProgress; + + public static double ZuneCurrentSettingsVersion => 2.0; + + public static void SetDesktopLockState(bool locked) => ZuneApplication._desktopLocked = locked; + + public static bool IsDesktopLocked => ZuneApplication._desktopLocked; + + public static string DefaultCommandLineParameterSwitch => "PlayMedia"; + + public static ZuneLibrary ZuneLibrary => ZuneApplication._zuneLibrary; + + public static Microsoft.Zune.Service.Service Service => Microsoft.Zune.Service.Service.Instance; + + public static event EventHandler Closing; + + public static SetupInstallContext InstallContext + { + get + { + SetupInstallContext setupInstallContext = SetupInstallContext.Zune; + try + { + RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Zune\\Setup"); + if (registryKey != null) + setupInstallContext = (SetupInstallContext)registryKey.GetValue("WindowsPhonePresent"); + } + catch (Exception ex) + { + } + return setupInstallContext; + } + } + + internal static IntPtr GetRenderWindow() => Application.Window.Handle; + + public static void PageLoadComplete() => ZuneApplication._initializationFailsafe.Complete(); + + private static void CorePhase3Ready(int hr, bool fSuc) + { + if (!fSuc) + { + ZuneUI.Shell.ShowErrorDialog(hr, StringId.IDS_ZUNELAUNCH_ERRORTITLE, StringId.IDS_ZUNELAUNCH_COMPONENT_ERROR); + ConfirmCloseDialog.ShowDefault(); + } + else + { + SingletonModelItem.Instance.Phase3Init(); + ZuneApplication.Service.Phase3Initialize(); + SignIn.Instance.Phase3Init(); + MetadataNotifications.Instance.Phase2Init(); + SingletonModelItem.Instance.Phase2Init(); + CDAccess.Phase2Catchup(); + SingletonModelItem.Instance.Phase2Init(); + SubscriptionEventsListener.Instance.StartListening(); + SoftwareUpdates.Instance.StartUp(); + ZuneApplication._interopNotifications = new InteropNotifications(); + if (ZuneApplication._interopNotifications != null) + ZuneApplication._interopNotifications.ShowErrorDialog += new OnShowErrorDialogHandler(ZuneApplication.OnShowErrorDialog); + Download.Instance.Phase3Init(); + SyncControls.Instance.Phase3Init(); + PodcastCredentials.Instance.Phase2Init(); + ProxyCredentials.Instance.Phase2Init(); + Win7ShellManager.Instance.SubprocWindow(Application.Window.Handle); + PhotoManager.Instance.SetWindowHandle(Application.Window.Handle); + if (OSVersion.IsWin7()) + { + SingletonModelItem.Instance.Phase3Init(); + SingletonModelItem.Instance.JumpListPinUpdateRequested.Invoke(); + } + if (!Microsoft.Zune.QuickMix.QuickMix.Instance.IsReady) + { + ZuneApplication._quickMixProgress = new QuickMixProgress(); + ZuneApplication._quickMixProgress.PropertyChanged += new PropertyChangedEventHandler(ZuneApplication.OnQuickMixPropertyChanged); + } + Telemetry.Instance.StartUpload(); + FeaturesChanged.Instance.StartUp(); + CultureHelper.CheckValidRegionAndLanguage(); + ((ZuneUI.Shell)ZuneShell.DefaultInstance).ApplicationInitializationIsComplete = true; + } + } + + private static void Phase2InitializationUIStage(object arg) + { + ZuneApplication._initializationFailsafe.Initialize((DeferredInvokeHandler)delegate + { + ZuneApplication._appInitializationSequencer.UIReady(); + }); + ZuneApplication.ProcessAppArgs(); + Download.Instance.Phase2Init(); + if (!ZuneShell.DefaultInstance.NavigationsPending && ZuneShell.DefaultInstance.CurrentPage is StartupPage) + ZuneUI.Shell.NavigateToHomePage(); + if (ZuneApplication._dbRebuilt) + { + string caption = ZuneLibrary.LoadStringFromResource(109U); + string text = ZuneLibrary.LoadStringFromResource(110U); + if (!string.IsNullOrEmpty(caption) && !string.IsNullOrEmpty(text)) + Win32MessageBox.Show(text, caption, Win32MessageBoxType.MB_ICONHAND, (DeferredInvokeHandler)null); + } + ZuneApplication._phase2InitComplete = true; + } + + private static void Phase2InitializationWorker(object arg) + { + Win32Window.Close(ZuneApplication._hWndSplashScreen); + int hr; + bool flag = ZuneApplication._zuneLibrary.Phase2Initialization(out hr); + Application.DeferredInvoke(new DeferredInvokeHandler(ZuneApplication.Phase2InitializationUIStage), (object)new object[2] + { + (object) hr, + (object) flag + }); + ZuneApplication.ZuneLibrary.CleanupTransientMedia(); + ZuneApplication._transientTableCleanupComplete.Set(); + SQMLog.Log(SQMDataId.GdiMode, Application.RenderingType == RenderingType.GDI ? 1 : 0); + } + + private static void Phase2Initialization(object arg) => ThreadPool.QueueUserWorkItem(new WaitCallback(ZuneApplication.Phase2InitializationWorker)); + + public static void ProcessMessageFromCommandLine(string strArgs) => Application.DeferredInvoke(new DeferredInvokeHandler(ZuneApplication.ProcessMessageFromCommandLineDeferred), (object)strArgs, DeferredInvokePriority.Low); + + private static void ProcessMessageFromCommandLineDeferred(object args) + { + string[] arArgs = ZuneApplication.SplitCommandLineArguments((string)args); + if (arArgs != null) + { + if (ZuneApplication._unprocessedAppArgs == null) + ZuneApplication._unprocessedAppArgs = new List(); + Hashtable hashtable = new Hashtable(); + foreach (CommandLineArgument commandLineArgument in CommandLineArgument.ParseArgs(arArgs, ZuneApplication.DefaultCommandLineParameterSwitch)) + hashtable[(object)commandLineArgument.Name] = (object)commandLineArgument.Value; + ZuneApplication._unprocessedAppArgs.Add(hashtable); + } + if (!ZuneApplication._phase2InitComplete) + return; + ZuneApplication.ProcessAppArgs(); + } + + private static void ProcessAppArgs() + { + if (ZuneApplication._unprocessedAppArgs == null) + return; + if (ClientConfiguration.FUE.SettingsVersion < ZuneApplication.ZuneCurrentSettingsVersion || Fue.Instance.IsFirstLaunch) + { + Fue.FUECompleted += new EventHandler(ZuneApplication.ProcessAppArgsAfterFUE); + } + else + { + for (int index = 0; index < ZuneApplication._unprocessedAppArgs.Count; ++index) + ZuneApplication.ProcessAppArgs(ZuneApplication._unprocessedAppArgs[index]); + ZuneApplication._unprocessedAppArgs = (List)null; + } + } + + private static void ProcessAppArgs(Hashtable args) + { + if (args[(object)"device"] is string str && !ZuneApplication._phase2InitComplete) + { + char[] chArray = new char[1] { '"' }; + SyncControls.Instance.SetCurrentDeviceByCanonicalName(str.Trim(chArray)); + } + if (args[(object)"link"] is string link && !ZuneUI.Shell.IgnoreAppNavigationsArgs) + ZuneUI.Shell.ProcessExternalLink(link); + if (args[(object)"ripcd"] is string path && !ZuneUI.Shell.IgnoreAppNavigationsArgs) + CDAccess.HandleDiskFromAutoplay(path, CDAction.Rip); + if (args[(object)"playcd"] is string path && !ZuneUI.Shell.IgnoreAppNavigationsArgs) + CDAccess.HandleDiskFromAutoplay(path, CDAction.Play); + if (args[(object)"playmedia"] is string initialUrl && !ZuneUI.Shell.IgnoreAppNavigationsArgs) + ZuneApplication.RegisterNewFileEnumeration(new LaunchFromShellHelper("play", initialUrl)); + if (args[(object)"shellhlp_v2"] is string taskName && !ZuneUI.Shell.IgnoreAppNavigationsArgs) + { + string marshalledDataObject = args[(object)"dataobject"] as string; + string eventName = args[(object)"event"] as string; + if (marshalledDataObject != null && eventName != null) + ZuneApplication.RegisterNewFileEnumeration(new LaunchFromShellHelper(taskName, marshalledDataObject, eventName)); + } + if (args.Contains((object)"refreshlicenses")) + ZuneApplication.ZuneLibrary.MarkAllDRMFilesAsNeedingLicenseRefresh(); + if (args.Contains((object)"update")) + SoftwareUpdates.Instance.InstallUpdates(); + if (args.Contains((object)"shuffleall") && !ZuneUI.Shell.IgnoreAppNavigationsArgs) + SingletonModelItem.Instance.ShuffleAllRequested = true; + if (args.Contains((object)"resumenowplaying") && !ZuneUI.Shell.IgnoreAppNavigationsArgs) + SingletonModelItem.Instance.ResumeLastNowPlayingHandler(); + if (args.Contains((object)"refreshcontentandexit")) + { + if (!ZuneApplication._phase2InitComplete) + { + HRESULT sOk = HRESULT._S_OK; + HRESULT hr = ContentRefreshTask.Instance.StartContentRefresh(new AsyncCompleteHandler(ZuneApplication.OnContentRefreshTaskComplete)); + if (hr.IsError) + ZuneApplication.OnContentRefreshTaskComplete(hr); + } + else + ZuneApplication.ZuneLibrary.MarkAllDRMFilesAsNeedingLicenseRefresh(); + } + if (!(args[(object)"playpin"] is string pinString) || ZuneUI.Shell.IgnoreAppNavigationsArgs) + return; + JumpListManager.PlayPin(JumpListPin.Parse(pinString)); + } + + private static void OnContentRefreshTaskComplete(HRESULT hr) => Application.DeferredInvoke(new DeferredInvokeHandler(ZuneApplication.DeferredClose), DeferredInvokePriority.Normal); + + public static void DeferredClose(object arg) => Application.Window.Close(); + + private static void ProcessAppArgsAfterFUE(object sender, EventArgs unused) + { + Fue.FUECompleted -= new EventHandler(ZuneApplication.ProcessAppArgsAfterFUE); + ZuneApplication.ProcessAppArgs(); + } + + private static void RegisterNewFileEnumeration(LaunchFromShellHelper helper) + { + if (ZuneApplication._currentShellCommand != null) + ZuneApplication._currentShellCommand.Cancel(); + ZuneApplication._currentShellCommand = helper; + ZuneApplication._currentShellCommand.Go(new DeferredInvokeHandler(ZuneApplication.DataObjectEnumerationComplete)); + } + + private static void DataObjectEnumerationComplete(object args) + { + if (args != ZuneApplication._currentShellCommand) + return; + string taskName = ZuneApplication._currentShellCommand.TaskName; + if (taskName == "play" || taskName == "playasplaylist") + { + List files = ZuneApplication._currentShellCommand.Files; + MediaType mediaType = ZuneApplication.FilterFiles(files); + if (files != null && files.Count > 0 && (mediaType == MediaType.Track || mediaType == MediaType.Video)) + { + PlaybackContext playbackContext = PlaybackContext.Music; + if (mediaType == MediaType.Video) + playbackContext = PlaybackContext.LibraryVideo; + SingletonModelItem.Instance.PlayItems((IList)files, playbackContext); + } + } + ZuneApplication._currentShellCommand = (LaunchFromShellHelper)null; + } + + private static MediaType FilterFiles(List enumeratedFiles) + { + MediaType mediaType = MediaType.Undefined; + if (enumeratedFiles != null && enumeratedFiles.Count > 0) + { + mediaType = (MediaType)enumeratedFiles[0].MediaType; + bool flag = false; + switch (mediaType) + { + case MediaType.Track: + flag = true; + break; + case MediaType.Video: + if (enumeratedFiles.Count > 1) + { + enumeratedFiles.RemoveRange(1, enumeratedFiles.Count - 1); + break; + } + break; + default: + mediaType = MediaType.Undefined; + enumeratedFiles.Clear(); + break; + } + if (flag) + { + for (int index = enumeratedFiles.Count - 1; index >= 0; --index) + { + if (enumeratedFiles[index].MediaType != (EMediaTypes)mediaType) + enumeratedFiles.RemoveAt(index); + } + } + } + return mediaType; + } + + private static string[] SplitCommandLineArguments(string arguments) + { + if (string.IsNullOrEmpty(arguments)) + return (string[])null; + string[] strArray = (string[])null; + MatchCollection matchCollection = new Regex("(\\S*?(\\\")([^\\\"])+(\\\"))|[^\\s\"]+").Matches(arguments); + if (matchCollection.Count > 0) + { + strArray = new string[matchCollection.Count]; + for (int i = 0; i < strArray.Length; ++i) + strArray[i] = matchCollection[i].Value; + } + return strArray; + } + + [STAThread] + public static int Launch(string strArgs, IntPtr hWndSplashScreen) + { + Microsoft.Zune.PerfTrace.PerfTrace.PERFTRACE_LAUNCHEVENT(Microsoft.Zune.PerfTrace.PerfTrace.LAUNCH_EVENT.IN_MANAGED_LAUNCH, 0U); + Application.ErrorReport += new Microsoft.Iris.ErrorReportHandler(ZuneApplication.ErrorReportHandler); + Hashtable hashtable = StandAlone.Startup(ZuneApplication.SplitCommandLineArguments(strArgs), ZuneApplication.DefaultCommandLineParameterSwitch); + if (hashtable != null) + { + ZuneApplication._unprocessedAppArgs = new List(); + ZuneApplication._unprocessedAppArgs.Add(hashtable); + } + DialogHelper.DialogCancel = ZuneUI.Shell.LoadString(StringId.IDS_DIALOG_CANCEL); + DialogHelper.DialogYes = ZuneUI.Shell.LoadString(StringId.IDS_DIALOG_YES); + DialogHelper.DialogNo = ZuneUI.Shell.LoadString(StringId.IDS_DIALOG_NO); + DialogHelper.DialogOk = ZuneUI.Shell.LoadString(StringId.IDS_DIALOG_OK); + XmlDataProviders.Register(); + LibraryDataProvider.Register(); + SubscriptionDataProvider.Register(); + StaticLibraryDataProvider.Register(); + AggregateDataProviderQuery.Register(); + ZuneUI.Shell.InitializeInstance(); + Application.Name = "Zune"; + Application.Window.Caption = "Zune"; + Application.Window.SetIcon("ZuneShellResources.dll", 1); + if (!hashtable.Contains((object)"noshadow")) + { + Image[] images = new Image[4]; + ImageInset imageInset1 = new ImageInset(26, 0, 30, 0); + ImageInset imageInset2 = new ImageInset(0, 10, 0, 0); + images[0] = new Image("res://ZuneShellResources.dll!activeshadowLeft.png", imageInset2); + images[1] = new Image("res://ZuneShellResources.dll!activeshadowTop.png", imageInset1); + images[2] = new Image("res://ZuneShellResources.dll!activeshadowRight.png", imageInset2); + images[3] = new Image("res://ZuneShellResources.dll!activeshadowBottom.png", imageInset1); + Application.Window.SetShadowEdgeImages(true, images); + imageInset1 = new ImageInset(23, 0, 29, 0); + imageInset2 = new ImageInset(0, 5, 0, 0); + images[0] = new Image("res://ZuneShellResources.dll!inactiveshadowLeft.png", imageInset2); + images[1] = new Image("res://ZuneShellResources.dll!inactiveshadowTop.png", imageInset1); + images[2] = new Image("res://ZuneShellResources.dll!inactiveshadowRight.png", imageInset2); + images[3] = new Image("res://ZuneShellResources.dll!inactiveshadowBottom.png", imageInset1); + Application.Window.SetShadowEdgeImages(false, images); + } + Application.Window.CloseRequested += new WindowCloseRequestedHandler(CodeDialogManager.Instance.OnWindowCloseRequested); + CodeDialogManager.Instance.WindowCloseNotBlocked += new EventHandler(ZuneApplication.OnWindowCloseNotBlocked); + Application.Window.SessionConnected += new SessionConnectedHandler(ZuneApplication.OnSessionConnected); + string source = "res://ZuneShellResources!Frame.uix#Frame"; + ZuneApplication._hWndSplashScreen = hWndSplashScreen; + ZuneApplication._initializationFailsafe = new InitializationFailsafe(); + Microsoft.Zune.PerfTrace.PerfTrace.PERFTRACE_LAUNCHEVENT(Microsoft.Zune.PerfTrace.PerfTrace.LAUNCH_EVENT.REQUEST_UI_LOAD, 0U); + Application.Window.RequestLoad(source); + Microsoft.Zune.PerfTrace.PerfTrace.PERFTRACE_LAUNCHEVENT(Microsoft.Zune.PerfTrace.PerfTrace.LAUNCH_EVENT.REQUEST_UI_LOAD_COMPLETE, 0U); + CallbackOnUIThread callbackOnUiThread = new CallbackOnUIThread(); + ZuneApplication._appInitializationSequencer = new AppInitializationSequencer(new CorePhase2ReadyCallback(ZuneApplication.CorePhase3Ready)); + ZuneApplication._zuneLibrary = new ZuneLibrary(); + int num = ZuneApplication._zuneLibrary.Initialize((string)null, out ZuneApplication._dbRebuilt); + if (num == 0) + { + StandAlone.Run(new DeferredInvokeHandler(ZuneApplication.Phase2Initialization)); + Application.Window.CloseRequested -= new WindowCloseRequestedHandler(CodeDialogManager.Instance.OnWindowCloseRequested); + CodeDialogManager.Instance.WindowCloseNotBlocked -= new EventHandler(ZuneApplication.OnWindowCloseNotBlocked); + Application.Window.SessionConnected -= new SessionConnectedHandler(ZuneApplication.OnSessionConnected); + if (Download.IsCreated) + Download.Instance.Dispose(); + ZuneShell.DefaultInstance?.Dispose(); + ViewTimeLogger.Instance.Shutdown(); + if (PodcastCredentials.HasInstance) + PodcastCredentials.Instance.Dispose(); + if (ProxyCredentials.HasInstance) + ProxyCredentials.Instance.Dispose(); + StandAlone.Shutdown(); + HttpWebRequest.Shutdown(); + WorkerQueue.ShutdownAll(); + if (ContentRefreshTask.HasInstance) + ContentRefreshTask.Instance.Dispose(); + if (ZuneApplication.Service != null) + ZuneApplication.Service.Dispose(); + if (ShellMessagingNotifier.HasInstance) + ShellMessagingNotifier.Instance.Dispose(); + if (MessagingService.HasInstance) + MessagingService.Instance.Dispose(); + if (FeaturesChangedApi.HasInstance) + FeaturesChangedApi.Instance.Dispose(); + CDAccess.Instance.Dispose(); + PlaylistManager.Instance.Dispose(); + if (ZuneApplication._interopNotifications != null) + { + ZuneApplication._interopNotifications.ShowErrorDialog -= new OnShowErrorDialogHandler(ZuneApplication.OnShowErrorDialog); + ZuneApplication._interopNotifications.Dispose(); + ZuneApplication._interopNotifications = (InteropNotifications)null; + } + } + ZuneApplication._zuneLibrary.Dispose(); + return num; + } + + private static void ErrorReportHandler(Error[] errors) + { + int num = 0; + string str = string.Empty; + foreach (Error error in errors) + { + if (!error.Warning) + { + str = str + error.ToString() + "\n"; + ++num; + } + } + if (num > 0) + throw new ZuneShellException("Internal Zune Shell error", string.Format("Scripting errors encountered (Process ID) = {0}\n\n{1}", (object)Process.GetCurrentProcess().Id.ToString((IFormatProvider)CultureInfo.InvariantCulture), (object)str)); + } + + internal static bool CanAddMedia(IList filenames, MediaType mediaType, CanAddMediaArgs args) + { + foreach (string filename in (IEnumerable)filenames) + { + if (args.Aborted) + return false; + if (ZuneApplication.CanAddMedia(filename, mediaType, args)) + return true; + } + return false; + } + + private static bool CanAddMedia(string filename, MediaType mediaType, CanAddMediaArgs args) + { + try + { + return Directory.Exists(filename) ? ZuneApplication.ZuneLibrary.CanAddFromFolder(filename) && (ZuneApplication.CanAddMedia((IList)Directory.GetFiles(filename), mediaType, args) || ZuneApplication.CanAddMedia((IList)Directory.GetDirectories(filename), mediaType, args)) : ZuneApplication.ZuneLibrary.CanAddMedia(filename, (EMediaTypes)mediaType); + } + catch (UnauthorizedAccessException ex) + { + return false; + } + catch (IOException ex) + { + return false; + } + } + + internal static bool AddMedia(IList filenames, MediaType mediaType) + { + bool flag = false; + foreach (string filename in (IEnumerable)filenames) + flag |= ZuneApplication.AddMedia(filename, mediaType); + return flag; + } + + private static bool AddMedia(string filename, MediaType mediaType) + { + bool flag = false; + try + { + if (Directory.Exists(filename)) + { + flag = ZuneApplication.AddMedia((IList)Directory.GetFiles(filename), mediaType); + flag |= ZuneApplication.AddMedia((IList)Directory.GetDirectories(filename), mediaType); + } + else if (ZuneApplication.ZuneLibrary.CanAddMedia(filename, (EMediaTypes)mediaType)) + flag = ZuneApplication.ZuneLibrary.AddMedia(filename) != -1; + } + catch (UnauthorizedAccessException ex) + { + } + catch (IOException ex) + { + } + return flag; + } + + internal static bool AddTransientMedia( + string filename, + MediaType mediaType, + out int libraryID, + out bool fFileAlreadyExists) + { + ZuneApplication._transientTableCleanupComplete.WaitOne(); + return ZuneApplication.ZuneLibrary.AddTransientMedia(filename, (EMediaTypes)mediaType, out libraryID, out fFileAlreadyExists); + } + + private static void OnWindowCloseNotBlocked(object sender, EventArgs args) + { + bool flag1 = SyncControls.Instance.CurrentDeviceOverride.UIFirmwareUpdater != null && SyncControls.Instance.CurrentDeviceOverride.UIFirmwareUpdater.UpdateInProgress; + bool flag2 = SyncControls.Instance.CurrentDeviceOverride.UIFirmwareRestorer != null && SyncControls.Instance.CurrentDeviceOverride.UIFirmwareRestorer.RestoreInProgress; + if (CDAccess.Instance.Notification != null || CDAccess.Instance.BurnNotification != null || Download.IsCreated && Download.Instance.Notification != null || (flag1 || flag2)) + { + if (Application.RenderingType == RenderingType.GDI && SingletonModelItem.Instance.PlayingVideo) + SingletonModelItem.Instance.Stop.Invoke(); + string ui = "res://ZuneShellResources!ConfirmClose.uix#ConfirmCloseContentUI"; + if (flag1) + ui = "res://ZuneShellResources!ConfirmClose.uix#ConfirmFirmwareUpdateCloseContentUI"; + else if (flag2) + ui = "res://ZuneShellResources!ConfirmClose.uix#ConfirmFirmwareRestoreCloseContentUI"; + ConfirmCloseDialog.Show(ui, (EventHandler)delegate + { + ZuneApplication.ForceClose(sender, args); + }); + } + else + ZuneApplication.ForceClose(sender, args); + } + + private static void ForceClose(object sender, EventArgs args) + { + if (ZuneApplication.Closing != null) + ZuneApplication.Closing(sender, args); + Application.Window.ForceClose(); + } + + private static void OnSessionConnected(object sender, bool fIsConnected) + { + if (fIsConnected) + return; + SingletonModelItem.Instance.CloseCurrentSession(); + } + + public static void OnShowErrorDialog(int hr, uint uiStringId) => Application.DeferredInvoke(new DeferredInvokeHandler(ZuneApplication.DeferredShowErrorDialog), (object)new object[2] + { + (object) hr, + (object) uiStringId + }); + + public static void DeferredShowErrorDialog(object arg) + { + object[] objArray = (object[])arg; + ZuneUI.Shell.ShowErrorDialog(Convert.ToInt32(objArray[0]), ZuneUI.Shell.LoadString((StringId)Convert.ToUInt32(objArray[1]))); + } + + private static void OnQuickMixPropertyChanged(object Sender, PropertyChangedEventArgs e) + { + if (!(e.PropertyName == "Progress") || (double)ZuneApplication._quickMixProgress.Progress < 100.0) + return; + NotificationArea.Instance.Add((ZuneUI.Notification)new QuickMixNotification(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_BOOTSTRAP_READY_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_BOOTSTRAP_READY_TEXT), NotificationState.Completed, true, 10000)); + ZuneApplication._quickMixProgress.PropertyChanged -= new PropertyChangedEventHandler(ZuneApplication.OnQuickMixPropertyChanged); + ZuneApplication._quickMixProgress = (QuickMixProgress)null; + } + } +} diff --git a/Microsoft/Zune/Shell/ZuneShellException.cs b/Microsoft/Zune/Shell/ZuneShellException.cs new file mode 100644 index 0000000..79c6b27 --- /dev/null +++ b/Microsoft/Zune/Shell/ZuneShellException.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.ZuneShellException +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.Serialization; + +namespace Microsoft.Zune.Shell +{ + [Serializable] + internal class ZuneShellException : InvalidOperationException + { + private string _context; + + public ZuneShellException(string message) + : this(message, (string)null) + { + } + + public ZuneShellException(string message, string context) + : base(ZuneShellException.PrepareMessage(message, context)) + => this._context = context; + + protected ZuneShellException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + + public string Context => this._context; + + private static string PrepareMessage(string message, string context) => message; + } +} diff --git a/Microsoft/Zune/Shell/ZuneTraceSwitch.cs b/Microsoft/Zune/Shell/ZuneTraceSwitch.cs new file mode 100644 index 0000000..5bd0afc --- /dev/null +++ b/Microsoft/Zune/Shell/ZuneTraceSwitch.cs @@ -0,0 +1,39 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Shell.ZuneTraceSwitch +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Diagnostics; + +namespace Microsoft.Zune.Shell +{ + internal class ZuneTraceSwitch : TraceSwitch + { + public ZuneTraceSwitch(string displayName, string description) + : base(displayName, description) + { + } + + protected override void OnValueChanged() + { + try + { + this.SwitchSetting = (int)Enum.Parse(typeof(TraceLevel), this.Value, true); + } + catch (ArgumentException ex) + { + this.SwitchSetting = 0; + } + catch (FormatException ex) + { + this.SwitchSetting = 0; + } + catch (OverflowException ex) + { + this.SwitchSetting = 0; + } + } + } +} diff --git a/Microsoft/Zune/Util/SQMLog.cs b/Microsoft/Zune/Util/SQMLog.cs new file mode 100644 index 0000000..d192df8 --- /dev/null +++ b/Microsoft/Zune/Util/SQMLog.cs @@ -0,0 +1,332 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.Zune.Util.SQMLog +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.InteropServices; +using ZuneUI; + +namespace Microsoft.Zune.Util +{ + public static class SQMLog + { + private static SQMStreamPositionType[] c_rgSPTArrayAllStrings = new SQMStreamPositionType[9] + { + SQMStreamPositionType.sptString, + SQMStreamPositionType.sptString, + SQMStreamPositionType.sptString, + SQMStreamPositionType.sptString, + SQMStreamPositionType.sptString, + SQMStreamPositionType.sptString, + SQMStreamPositionType.sptString, + SQMStreamPositionType.sptString, + SQMStreamPositionType.sptString + }; + + public static void Log(SQMDataId sqmDataId, int nData) + { + SQMDataPoint dataPoint = SQMLog.FindDataPoint(sqmDataId); + if (dataPoint.id == SQMDataId.Invalid) + return; + switch (dataPoint.action) + { + case SQMAction.Add: + SQMLog.SQMAddWrapper(dataPoint.GetName(), nData); + break; + case SQMAction.Inc: + SQMLog.SQMAddWrapper(dataPoint.GetName(), 1); + break; + case SQMAction.SetFlag: + SQMLog.SQMSetFlagWrapper(dataPoint.GetName(), nData != 0); + break; + case SQMAction.SetBits: + SQMLog.SQMSetBitsWrapper(dataPoint.GetName(), (uint)nData); + break; + default: + throw new ArgumentException("Datapoint " + dataPoint.GetName() + " is not a simple DWORD-type datapoint. Use LogToStream for stream-type datapoints."); + } + Telemetry.Instance.ReportEvent(dataPoint, nData); + } + + public static void LogToStream(SQMDataId sqmDataId, params string[] args) + { + SQMDataPoint dataPoint = SQMLog.FindDataPoint(sqmDataId); + if (dataPoint.id == SQMDataId.Invalid) + return; + if (dataPoint.action != SQMAction.MixedStream) + throw new ArgumentException("Datapoint " + dataPoint.GetName() + " is not a MixedStream-type datapoint. Error in parameters/paramtypes, or in datapoint declaration."); + if (args.Length > 9) + throw new ArgumentException("Too many (or too few) number params. SQM only allows up to 9 params. Datapoint: " + dataPoint.GetName(), "args.Length"); + if (args.Length != dataPoint.argCount) + throw new ArgumentException("Passed-in arg count doesn't match datapoint declaration: " + dataPoint.GetName(), "args.Length"); + if (args.Length == 1) + SQMLog.SQMAddToStream(dataPoint.GetName(), SQMLog.c_rgSPTArrayAllStrings, (uint)args.Length, args[0]); + else if (args.Length == 2) + SQMLog.SQMAddToStream(dataPoint.GetName(), SQMLog.c_rgSPTArrayAllStrings, (uint)args.Length, args[0], args[1]); + else if (args.Length == 3) + SQMLog.SQMAddToStream(dataPoint.GetName(), SQMLog.c_rgSPTArrayAllStrings, (uint)args.Length, args[0], args[1], args[2]); + else if (args.Length == 4) + SQMLog.SQMAddToStream(dataPoint.GetName(), SQMLog.c_rgSPTArrayAllStrings, (uint)args.Length, args[0], args[1], args[2], args[3]); + else if (args.Length == 5) + SQMLog.SQMAddToStream(dataPoint.GetName(), SQMLog.c_rgSPTArrayAllStrings, (uint)args.Length, args[0], args[1], args[2], args[3], args[4]); + else if (args.Length == 6) + SQMLog.SQMAddToStream(dataPoint.GetName(), SQMLog.c_rgSPTArrayAllStrings, (uint)args.Length, args[0], args[1], args[2], args[3], args[4], args[5]); + else if (args.Length == 7) + SQMLog.SQMAddToStream(dataPoint.GetName(), SQMLog.c_rgSPTArrayAllStrings, (uint)args.Length, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + else if (args.Length == 8) + { + SQMLog.SQMAddToStream(dataPoint.GetName(), SQMLog.c_rgSPTArrayAllStrings, (uint)args.Length, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); + } + else + { + if (args.Length != 9) + return; + SQMLog.SQMAddToStream(dataPoint.GetName(), SQMLog.c_rgSPTArrayAllStrings, (uint)args.Length, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); + } + } + + public static void LogToStream(SQMDataId sqmDataId, params uint[] args) + { + SQMDataPoint dataPoint = SQMLog.FindDataPoint(sqmDataId); + if (dataPoint.id == SQMDataId.Invalid) + return; + if (dataPoint.action != SQMAction.NumStream) + throw new ArgumentException("Datapoint " + dataPoint.GetName() + " is not a NumStream-type datapoint. Error in parameters or in datapoint declaration."); + if (args.Length < 1 || args.Length > 9) + throw new ArgumentException("Too many (or too few) number params. SQM only allows up to 9 params. Datapoint: " + dataPoint.GetName(), "args.Length"); + if (args.Length != dataPoint.argCount) + throw new ArgumentException("Passed-in arg count doesn't match datapoint declaration: " + dataPoint.GetName(), "args.Length"); + if (args.Length == 1) + SQMLog.SQMAddNumbersToStream(dataPoint.GetName(), (uint)args.Length, args[0]); + else if (args.Length == 2) + SQMLog.SQMAddNumbersToStream(dataPoint.GetName(), (uint)args.Length, args[0], args[1]); + else if (args.Length == 3) + SQMLog.SQMAddNumbersToStream(dataPoint.GetName(), (uint)args.Length, args[0], args[1], args[2]); + else if (args.Length == 4) + SQMLog.SQMAddNumbersToStream(dataPoint.GetName(), (uint)args.Length, args[0], args[1], args[2], args[3]); + else if (args.Length == 5) + SQMLog.SQMAddNumbersToStream(dataPoint.GetName(), (uint)args.Length, args[0], args[1], args[2], args[3], args[4]); + else if (args.Length == 6) + SQMLog.SQMAddNumbersToStream(dataPoint.GetName(), (uint)args.Length, args[0], args[1], args[2], args[3], args[4], args[5]); + else if (args.Length == 7) + SQMLog.SQMAddNumbersToStream(dataPoint.GetName(), (uint)args.Length, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + else if (args.Length == 8) + { + SQMLog.SQMAddNumbersToStream(dataPoint.GetName(), (uint)args.Length, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); + } + else + { + if (args.Length != 9) + return; + SQMLog.SQMAddNumbersToStream(dataPoint.GetName(), (uint)args.Length, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); + } + } + + private static SQMDataPoint FindDataPoint(SQMDataId sqmDataId) + { + foreach (SQMDataPoint rgSqmDataPoint in SQMData.s_rgSQMDataPoints) + { + if (rgSqmDataPoint.id == sqmDataId) + return rgSqmDataPoint; + } + return SQMData.s_sqmDataPointInvalid; + } + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode)] + private static extern void SQMAddWrapper(string sqmDataId, int nData); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode)] + private static extern void SQMSetFlagWrapper(string sqmDataId, bool fSet); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode)] + private static extern void SQMSetBitsWrapper(string sqmDataId, uint dwBits); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddNumbersToStream(string sqmDataId, uint countTotal, uint dw1); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddNumbersToStream( + string sqmDataId, + uint countTotal, + uint dw1, + uint dw2); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddNumbersToStream( + string sqmDataId, + uint countTotal, + uint dw1, + uint dw2, + uint dw3); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddNumbersToStream( + string sqmDataId, + uint countTotal, + uint dw1, + uint dw2, + uint dw3, + uint dw4); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddNumbersToStream( + string sqmDataId, + uint countTotal, + uint dw1, + uint dw2, + uint dw3, + uint dw4, + uint dw5); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddNumbersToStream( + string sqmDataId, + uint countTotal, + uint dw1, + uint dw2, + uint dw3, + uint dw4, + uint dw5, + uint dw6); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddNumbersToStream( + string sqmDataId, + uint countTotal, + uint dw1, + uint dw2, + uint dw3, + uint dw4, + uint dw5, + uint dw6, + uint dw7); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddNumbersToStream( + string sqmDataId, + uint countTotal, + uint dw1, + uint dw2, + uint dw3, + uint dw4, + uint dw5, + uint dw6, + uint dw7, + uint dw8); + + [DllImport("ZuneNativeLib", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddNumbersToStream( + string sqmDataId, + uint countTotal, + uint dw1, + uint dw2, + uint dw3, + uint dw4, + uint dw5, + uint dw6, + uint dw7, + uint dw8, + uint dw9); + + [DllImport("ZuneNativeLib", EntryPoint = "SQMAddToStreamWsz", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddToStream( + string sqmDataId, + [MarshalAs(UnmanagedType.LPArray)] SQMStreamPositionType[] sptTypes, + uint countTotal, + string s1); + + [DllImport("ZuneNativeLib", EntryPoint = "SQMAddToStreamWsz", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddToStream( + string sqmDataId, + [MarshalAs(UnmanagedType.LPArray)] SQMStreamPositionType[] sptTypes, + uint countTotal, + string s1, + string s2); + + [DllImport("ZuneNativeLib", EntryPoint = "SQMAddToStreamWsz", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddToStream( + string sqmDataId, + [MarshalAs(UnmanagedType.LPArray)] SQMStreamPositionType[] sptTypes, + uint countTotal, + string s1, + string s2, + string s3); + + [DllImport("ZuneNativeLib", EntryPoint = "SQMAddToStreamWsz", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddToStream( + string sqmDataId, + [MarshalAs(UnmanagedType.LPArray)] SQMStreamPositionType[] sptTypes, + uint countTotal, + string s1, + string s2, + string s3, + string s4); + + [DllImport("ZuneNativeLib", EntryPoint = "SQMAddToStreamWsz", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddToStream( + string sqmDataId, + [MarshalAs(UnmanagedType.LPArray)] SQMStreamPositionType[] sptTypes, + uint countTotal, + string s1, + string s2, + string s3, + string s4, + string s5); + + [DllImport("ZuneNativeLib", EntryPoint = "SQMAddToStreamWsz", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddToStream( + string sqmDataId, + [MarshalAs(UnmanagedType.LPArray)] SQMStreamPositionType[] sptTypes, + uint countTotal, + string s1, + string s2, + string s3, + string s4, + string s5, + string s6); + + [DllImport("ZuneNativeLib", EntryPoint = "SQMAddToStreamWsz", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddToStream( + string sqmDataId, + [MarshalAs(UnmanagedType.LPArray)] SQMStreamPositionType[] sptTypes, + uint countTotal, + string s1, + string s2, + string s3, + string s4, + string s5, + string s6, + string s7); + + [DllImport("ZuneNativeLib", EntryPoint = "SQMAddToStreamWsz", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddToStream( + string sqmDataId, + [MarshalAs(UnmanagedType.LPArray)] SQMStreamPositionType[] sptTypes, + uint countTotal, + string s1, + string s2, + string s3, + string s4, + string s5, + string s6, + string s7, + string s8); + + [DllImport("ZuneNativeLib", EntryPoint = "SQMAddToStreamWsz", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] + private static extern void SQMAddToStream( + string sqmDataId, + [MarshalAs(UnmanagedType.LPArray)] SQMStreamPositionType[] sptTypes, + uint countTotal, + string s1, + string s2, + string s3, + string s4, + string s5, + string s6, + string s7, + string s8, + string s9); + } +} diff --git a/ZuneShell.csproj b/ZuneShell.csproj new file mode 100644 index 0000000..6e733e7 --- /dev/null +++ b/ZuneShell.csproj @@ -0,0 +1,877 @@ + + + + + Debug + AnyCPU + {E93CFFA3-1EEB-4E71-9E83-7377C1422119} + Library + ZuneShell + v3.5 + 4.7.0.0 + 512 + + + + + 3.5 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + + + + + + lib\UIX.dll + + + lib\UIXControls.dll + + + lib\ZuneDBApi.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ZuneShell.sln b/ZuneShell.sln new file mode 100644 index 0000000..319ada1 --- /dev/null +++ b/ZuneShell.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30907.101 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZuneShell", "ZuneShell.csproj", "{E93CFFA3-1EEB-4E71-9E83-7377C1422119}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E93CFFA3-1EEB-4E71-9E83-7377C1422119}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E93CFFA3-1EEB-4E71-9E83-7377C1422119}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E93CFFA3-1EEB-4E71-9E83-7377C1422119}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E93CFFA3-1EEB-4E71-9E83-7377C1422119}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6B948258-B457-4B3D-955E-05ED3F03CF36} + EndGlobalSection +EndGlobal diff --git a/ZuneUI/AOClearWirelessSettings.cs b/ZuneUI/AOClearWirelessSettings.cs new file mode 100644 index 0000000..473f6ed --- /dev/null +++ b/ZuneUI/AOClearWirelessSettings.cs @@ -0,0 +1,125 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AOClearWirelessSettings +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + internal class AOClearWirelessSettings : AsyncOperation + { + private WirelessStates[] _clearWirelessSettingsStatesMethod1 = new WirelessStates[2] + { + WirelessStates.CommitProfileToDevice, + WirelessStates.UnassociateWlanDevice + }; + private WirelessStates[] _clearWirelessSettingsStatesMethod2 = new WirelessStates[2] + { + WirelessStates.UnassociateWlanDevice, + WirelessStates.UnassociateNetwork + }; + private bool _fIgnoreErrors; + + public WirelessStateResults StartOperation( + UIDevice device, + AsyncOperation.AOComplete completeFunc, + bool fIgnoreErrors) + { + this.ResetState(fIgnoreErrors); + WirelessStates[] states; + if (device.SupportsWirelessSetupMethod1) + states = this._clearWirelessSettingsStatesMethod1; + else if (device.SupportsWirelessSetupMethod2) + { + states = this._clearWirelessSettingsStatesMethod2; + } + else + { + ShipAssert.Assert(false); + return WirelessStateResults.Error; + } + return this.StartOperation(device, completeFunc, states); + } + + protected override WirelessStateResults DoStep(WirelessStates state) + { + HRESULT hr; + switch (state) + { + case WirelessStates.CommitProfileToDevice: + hr = this._device.SetWiFiProfileList(new WlanProfileList()); + if (hr.IsSuccess) + { + hr = this._device.SendWiFiProfiles(); + break; + } + break; + case WirelessStates.UnassociateWlanDevice: + hr = this._device.RemoveWiFiAssociation(); + break; + case WirelessStates.UnassociateNetwork: + hr = this._device.SetWifiMediaSyncSSID(string.Empty); + if (hr.IsSuccess || this._fIgnoreErrors) + { + ShipAssert.Assert(hr.IsSuccess); + this.StepComplete(WirelessStateResults.Success); + break; + } + break; + default: + hr = HRESULT._E_ABORT; + break; + } + if (hr.IsSuccess || this._fIgnoreErrors) + { + ShipAssert.Assert(hr.IsSuccess); + return WirelessStateResults.Success; + } + this.SetResult(hr); + return WirelessStateResults.Error; + } + + protected override void AddListeners() + { + this._device.WiFiProfilesSentEvent += new FallibleEventHandler(this.Device_SetDeviceWlanProfilesCompleteEvent); + this._device.WiFiRemovalCompletedEvent += new FallibleEventHandler(this.Device_UnassociateWlanDeviceCompleteEvent); + } + + protected override void RemoveListeners() + { + this._device.WiFiProfilesSentEvent -= new FallibleEventHandler(this.Device_SetDeviceWlanProfilesCompleteEvent); + this._device.WiFiRemovalCompletedEvent -= new FallibleEventHandler(this.Device_UnassociateWlanDeviceCompleteEvent); + } + + private void ResetState(bool fIgnoreErrors) => this._fIgnoreErrors = fIgnoreErrors; + + private void Device_SetDeviceWlanProfilesCompleteEvent(object sender, FallibleEventArgs args) + { + if (args.HR.IsSuccess || this._fIgnoreErrors) + { + this.StepComplete(WirelessStateResults.Success); + } + else + { + this.SetResult(args.HR); + this.StepComplete(WirelessStateResults.Error); + } + } + + private void Device_UnassociateWlanDeviceCompleteEvent(object sender, FallibleEventArgs args) + { + if (args.HR.IsSuccess || this._fIgnoreErrors) + { + this.StepComplete(WirelessStateResults.Success); + } + else + { + this.SetResult(args.HR); + this.StepComplete(WirelessStateResults.Error); + } + } + } +} diff --git a/ZuneUI/AOGetConnectedNetwork.cs b/ZuneUI/AOGetConnectedNetwork.cs new file mode 100644 index 0000000..497baba --- /dev/null +++ b/ZuneUI/AOGetConnectedNetwork.cs @@ -0,0 +1,79 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AOGetConnectedNetwork +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; +using System.Collections.Generic; + +namespace ZuneUI +{ + internal class AOGetConnectedNetwork : AsyncOperation + { + private WirelessStates[] _getConnectedNetworkStates = new WirelessStates[1] + { + WirelessStates.GetComputerProfiles + }; + private WlanProfileList _computerProfiles; + private WlanProfile _connectedNetwork; + + public WlanProfile ConnectedNetwork => this.Finished ? this._connectedNetwork : (WlanProfile)null; + + private void ResetState() + { + if (!this.Idle && !this.Finished) + return; + this._computerProfiles = new WlanProfileList(); + this._connectedNetwork = (WlanProfile)null; + } + + public WirelessStateResults StartOperation( + UIDevice device, + AsyncOperation.AOComplete completeFunc) + { + this.ResetState(); + return this.StartOperation(device, completeFunc, this._getConnectedNetworkStates); + } + + protected override WirelessStateResults DoStep(WirelessStates state) + { + HRESULT hr = state != WirelessStates.GetComputerProfiles ? HRESULT._E_ABORT : this._device.LoadComputerWiFiProfiles(); + if (hr.IsSuccess) + return WirelessStateResults.Success; + this.SetResult(hr); + return WirelessStateResults.Error; + } + + protected override void EndOperation(WirelessStateResults result) + { + this._connectedNetwork = (WlanProfile)null; + if (this._computerProfiles == null) + return; + foreach (WlanProfile computerProfile in (List)this._computerProfiles) + { + if (computerProfile.Connected) + { + this._connectedNetwork = computerProfile; + break; + } + } + } + + protected override void AddListeners() => this._device.ComputerWiFiProfilesLoadedEvent += new FallibleEventHandler(this.Device_GetWlanProfilesCompleteEvent); + + protected override void RemoveListeners() => this._device.ComputerWiFiProfilesLoadedEvent -= new FallibleEventHandler(this.Device_GetWlanProfilesCompleteEvent); + + private void Device_GetWlanProfilesCompleteEvent(object sender, FallibleEventArgs args) + { + HRESULT hr = args.HR; + this.SetResult(hr); + if (hr.IsSuccess) + hr = this._device.GetWiFiProfileList(ref this._computerProfiles); + if (hr.IsSuccess) + this.StepComplete(WirelessStateResults.Success); + else + this.StepComplete(WirelessStateResults.Error); + } + } +} diff --git a/ZuneUI/AOGetDeviceProfile.cs b/ZuneUI/AOGetDeviceProfile.cs new file mode 100644 index 0000000..5adcea0 --- /dev/null +++ b/ZuneUI/AOGetDeviceProfile.cs @@ -0,0 +1,61 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AOGetDeviceProfile +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + internal class AOGetDeviceProfile : AsyncOperation + { + private WirelessStates[] _getDeviceProfileStates = new WirelessStates[1] + { + WirelessStates.GetDeviceProfiles + }; + private WlanProfile _deviceProfile; + + public WlanProfile DeviceProfile => this.Finished ? this._deviceProfile : (WlanProfile)null; + + public WirelessStateResults StartOperation( + UIDevice device, + AsyncOperation.AOComplete completeFunc) + { + this.ResetState(); + return this.StartOperation(device, completeFunc, this._getDeviceProfileStates); + } + + protected override WirelessStateResults DoStep(WirelessStates state) + { + HRESULT hr = state != WirelessStates.GetDeviceProfiles ? HRESULT._E_ABORT : this._device.ReceiveWiFiProfiles(); + if (hr.IsSuccess) + return WirelessStateResults.Success; + this.SetResult(hr); + return WirelessStateResults.Error; + } + + protected override void AddListeners() => this._device.WiFiProfilesReceivedEvent += new FallibleEventHandler(this.Device_GetDeviceWlanProfilesCompleteEvent); + + protected override void RemoveListeners() => this._device.WiFiProfilesReceivedEvent -= new FallibleEventHandler(this.Device_GetDeviceWlanProfilesCompleteEvent); + + private void ResetState() => this._deviceProfile = (WlanProfile)null; + + private void Device_GetDeviceWlanProfilesCompleteEvent(object sender, FallibleEventArgs args) + { + WlanProfileList list = new WlanProfileList(); + HRESULT hr = args.HR; + this.SetResult(hr); + if (hr.IsSuccess) + { + hr = this._device.GetWiFiProfileList(ref list); + if (hr.IsSuccess && list.Count > 0) + this._deviceProfile = list[0]; + } + if (hr.IsSuccess) + this.StepComplete(WirelessStateResults.Success); + else + this.StepComplete(WirelessStateResults.Error); + } + } +} diff --git a/ZuneUI/AOGetNetworkList.cs b/ZuneUI/AOGetNetworkList.cs new file mode 100644 index 0000000..7b64305 --- /dev/null +++ b/ZuneUI/AOGetNetworkList.cs @@ -0,0 +1,124 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AOGetNetworkList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; +using System.Collections.Generic; + +namespace ZuneUI +{ + internal class AOGetNetworkList : AsyncOperation + { + private WlanProfileList _deviceNetworks; + private WlanProfileList _computerNetworks; + private WlanProfileList _networkList; + private WirelessStates[] _getNetworkListStates = new WirelessStates[2] + { + WirelessStates.GetComputerProfiles, + WirelessStates.SniffNetworks + }; + + public WlanProfileList NetworkList => this.Finished ? this._networkList : (WlanProfileList)null; + + private void ResetState() + { + if (!this.Idle && !this.Finished) + return; + this._computerNetworks = new WlanProfileList(); + this._deviceNetworks = new WlanProfileList(); + this._networkList = new WlanProfileList(); + } + + public WirelessStateResults StartOperation( + UIDevice device, + AsyncOperation.AOComplete completeFunc) + { + this.ResetState(); + return this.StartOperation(device, completeFunc, this._getNetworkListStates); + } + + protected override WirelessStateResults DoStep(WirelessStates state) + { + HRESULT hr; + switch (state) + { + case WirelessStates.SniffNetworks: + hr = this._device.ScanForWiFiNetworks(); + break; + case WirelessStates.GetComputerProfiles: + hr = this._device.LoadComputerWiFiProfiles(); + break; + default: + hr = HRESULT._E_ABORT; + break; + } + if (hr.IsSuccess) + return WirelessStateResults.Success; + this.SetResult(hr); + return WirelessStateResults.Error; + } + + protected override void EndOperation(WirelessStateResults result) + { + Dictionary dictionary = new Dictionary(); + if (this._deviceNetworks != null) + { + foreach (WlanProfile deviceNetwork in (List)this._deviceNetworks) + { + if (!dictionary.ContainsKey(deviceNetwork.SSID)) + { + WlanProfile wlanProfile = deviceNetwork; + foreach (WlanProfile computerNetwork in (List)this._computerNetworks) + { + if (computerNetwork.SSID == deviceNetwork.SSID) + { + wlanProfile = computerNetwork; + break; + } + } + if (!wlanProfile.Connected) + wlanProfile.Key = string.Empty; + dictionary.Add(wlanProfile.SSID, wlanProfile); + this._networkList.Add(wlanProfile); + } + } + } + this._networkList.Sort((IComparer)new WlanSignalStrenghComparer()); + } + + protected override void AddListeners() + { + this._device.WiFiScanCompletedEvent += new FallibleEventHandler(this.Device_GetDeviceWlanNetworksCompleteEvent); + this._device.ComputerWiFiProfilesLoadedEvent += new FallibleEventHandler(this.Device_GetWlanProfilesCompleteEvent); + } + + protected override void RemoveListeners() + { + this._device.WiFiScanCompletedEvent -= new FallibleEventHandler(this.Device_GetDeviceWlanNetworksCompleteEvent); + this._device.ComputerWiFiProfilesLoadedEvent -= new FallibleEventHandler(this.Device_GetWlanProfilesCompleteEvent); + } + + private void Device_GetWlanProfilesCompleteEvent(object sender, FallibleEventArgs args) + { + HRESULT hr = args.HR; + this.SetResult(hr); + if (hr.IsSuccess) + this._device.GetWiFiProfileList(ref this._computerNetworks); + this.StepComplete(WirelessStateResults.Success); + } + + private void Device_GetDeviceWlanNetworksCompleteEvent(object sender, FallibleEventArgs args) + { + HRESULT hr = args.HR; + this.SetResult(hr); + if (hr.IsSuccess) + hr = this._device.GetWiFiProfileList(ref this._deviceNetworks); + if (hr.IsSuccess) + this.StepComplete(WirelessStateResults.Success); + else + this.StepComplete(WirelessStateResults.Error); + } + } +} diff --git a/ZuneUI/AOSetProfile.cs b/ZuneUI/AOSetProfile.cs new file mode 100644 index 0000000..9b57a07 --- /dev/null +++ b/ZuneUI/AOSetProfile.cs @@ -0,0 +1,221 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AOSetProfile +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System.Threading; + +namespace ZuneUI +{ + internal class AOSetProfile : AsyncOperation + { + private WirelessStates[] _setProfileStates = new WirelessStates[4] + { + WirelessStates.GetDeviceProfiles, + WirelessStates.AssociateWlanDevice, + WirelessStates.CommitProfileToDevice, + WirelessStates.TestDeviceProfile + }; + private WlanProfile _deviceProfile; + private WlanProfile _attemptingProfile; + private AutoResetEvent _restore = new AutoResetEvent(false); + private string _attemptingName = string.Empty; + private bool _fProfileSaved; + private string _wlanTestResult; + private HRESULT _wlanTestResultCode; + + public string AttemptingName => this._attemptingName; + + public bool WlanTestSucceeded => this.Finished && string.IsNullOrEmpty(this._wlanTestResult); + + public override void Cancel() + { + base.Cancel(); + if (this.Idle || this.Finished || this._setProfileStates[AsyncOperation._iCurrentState] != WirelessStates.TestDeviceProfile) + return; + this._device.CancelWiFiTest(); + } + + private void ResetState(WlanProfile profile) + { + if (!this.Idle && !this.Finished) + return; + this._attemptingName = profile.SSID; + this._attemptingProfile = profile; + this._deviceProfile = (WlanProfile)null; + this._fProfileSaved = false; + this._wlanTestResult = (string)null; + this._wlanTestResultCode = HRESULT._S_OK; + this._restore.Reset(); + } + + public WirelessStateResults StartOperation( + UIDevice device, + AsyncOperation.AOComplete completeFunc, + WlanProfile newProfile) + { + if (newProfile == null) + return WirelessStateResults.Error; + this.ResetState(newProfile); + return this.StartOperation(device, completeFunc, this._setProfileStates); + } + + protected override WirelessStateResults DoStep(WirelessStates state) + { + HRESULT hr; + switch (state) + { + case WirelessStates.CommitProfileToDevice: + WlanProfileList list = new WlanProfileList(); + list.Add(this._attemptingProfile); + hr = this._device.SetWiFiProfileList(list); + if (hr.IsSuccess) + { + hr = this._device.SendWiFiProfiles(); + break; + } + break; + case WirelessStates.TestDeviceProfile: + hr = this._device.TestWiFi(); + break; + case WirelessStates.GetDeviceProfiles: + hr = this._device.ReceiveWiFiProfiles(); + break; + case WirelessStates.AssociateWlanDevice: + hr = this._device.AssociateWiFi(); + break; + default: + hr = HRESULT._E_ABORT; + break; + } + if (hr.IsSuccess) + return WirelessStateResults.Success; + this.SetResult(hr); + return WirelessStateResults.Error; + } + + protected override void EndOperation(WirelessStateResults result) + { + if (result != WirelessStateResults.Finished) + { + if (this._fProfileSaved) + this.RestoreProfile(); + if (result == WirelessStateResults.Canceled) + { + this._error = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_SETUP_CANCELED); + this._detailedError = (string)null; + this._hr = HRESULT._S_OK; + } + else if (this._attemptingProfile != null) + this._error = string.Format(Shell.LoadString(StringId.IDS_WIRELESS_SYNC_SETUP_FAILED), (object)this._attemptingProfile.SSID); + else + this._error = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_SETUP_FAILED_GENERIC); + } + else if (!string.IsNullOrEmpty(this._wlanTestResult)) + { + this._error = string.Format(Shell.LoadString(StringId.IDS_WIRELESS_SYNC_TEST_FAILED), (object)this._attemptingProfile.SSID); + this._detailedError = this._wlanTestResult; + this._hr = this._wlanTestResultCode; + } + else + SQMLog.Log(SQMDataId.DeviceWirelessSetup, 1); + } + + protected override void AddListeners() + { + this._device.WiFiProfilesReceivedEvent += new FallibleEventHandler(this.Device_GetDeviceWlanProfilesCompleteEvent); + this._device.WiFiTestCompletedEvent += new FallibleEventHandler(this.Device_TestDeviceWlanCompleteEvent); + this._device.WiFiProfilesSentEvent += new FallibleEventHandler(this.Device_SetDeviceWlanProfilesCompleteEvent); + this._device.WiFiAssociationCompletedEvent += new FallibleEventHandler(this.Device_AssociateWlanDeviceCompleteEvent); + } + + protected override void RemoveListeners() + { + this._device.WiFiProfilesReceivedEvent -= new FallibleEventHandler(this.Device_GetDeviceWlanProfilesCompleteEvent); + this._device.WiFiTestCompletedEvent -= new FallibleEventHandler(this.Device_TestDeviceWlanCompleteEvent); + this._device.WiFiProfilesSentEvent -= new FallibleEventHandler(this.Device_SetDeviceWlanProfilesCompleteEvent); + this._device.WiFiAssociationCompletedEvent -= new FallibleEventHandler(this.Device_AssociateWlanDeviceCompleteEvent); + } + + private bool IsWirelessTestFailure(HRESULT hr) => hr == HRESULT._NS_E_MTPZ_WLAN_TEST_FAIL_NO_CONFIG || hr == HRESULT._NS_E_MTPZ_WLAN_TEST_FAIL_ASSOCIATE || (hr == HRESULT._NS_E_MTPZ_WLAN_TEST_FAIL_DHCP || hr == HRESULT._NS_E_MTPZ_WLAN_TEST_FAIL_TIMEOUT) || (hr == HRESULT._NS_E_MTPZ_WLAN_TEST_FAIL_INTERNAL || hr == HRESULT._NS_E_MTPZ_WLAN_TEST_RUNNING || hr == HRESULT._NS_E_MTPZ_WLAN_TEST_UNKNOWN); + + private void RestoreProfile() + { + WlanProfileList list = new WlanProfileList(); + this._device.WiFiProfilesSentEvent += new FallibleEventHandler(this.Device_RestoreDeviceWlanProfilesCompleteEvent); + if (this._deviceProfile != null) + list.Add(this._deviceProfile); + if (this._device.SetWiFiProfileList(list).IsSuccess) + this._device.SendWiFiProfiles(); + this._restore.WaitOne(5000, false); + this._device.WiFiProfilesSentEvent -= new FallibleEventHandler(this.Device_RestoreDeviceWlanProfilesCompleteEvent); + } + + private void Device_GetDeviceWlanProfilesCompleteEvent(object sender, FallibleEventArgs args) + { + HRESULT hr = args.HR; + this.SetResult(hr); + if (hr.IsSuccess) + { + WlanProfileList list = new WlanProfileList(); + hr = this._device.GetWiFiProfileList(ref list); + this._deviceProfile = list.Count <= 0 ? (WlanProfile)null : list[0]; + } + if (hr.IsSuccess) + this.StepComplete(WirelessStateResults.Success); + else + this.StepComplete(WirelessStateResults.Error); + } + + private void Device_AssociateWlanDeviceCompleteEvent(object sender, FallibleEventArgs args) + { + this.SetResult(args.HR); + if (args.HR.IsSuccess) + this.StepComplete(WirelessStateResults.Success); + else + this.StepComplete(WirelessStateResults.Error); + } + + private void Device_SetDeviceWlanProfilesCompleteEvent(object sender, FallibleEventArgs args) + { + this.SetResult(args.HR); + if (args.HR.IsSuccess && this._attemptingProfile != null) + { + this._fProfileSaved = true; + this.StepComplete(WirelessStateResults.Success); + } + else + this.StepComplete(WirelessStateResults.Error); + } + + private void Device_RestoreDeviceWlanProfilesCompleteEvent( + object sender, + FallibleEventArgs args) + { + this._restore.Set(); + } + + private void Device_TestDeviceWlanCompleteEvent(object sender, FallibleEventArgs args) + { + HRESULT hr = args.HR; + bool flag = HRESULT._NS_E_MTPZ_WLAN_TEST_FAIL_CANCELLED == hr; + this.SetResult(hr); + if (this.IsWirelessTestFailure(hr)) + { + this._wlanTestResult = this._detailedError; + this._wlanTestResultCode = this._hr; + hr = HRESULT._S_OK; + this.ClearResult(); + } + if (hr.IsSuccess && this._attemptingProfile != null) + this.StepComplete(WirelessStateResults.Success); + else if (flag) + this.StepComplete(WirelessStateResults.Canceled); + else + this.StepComplete(WirelessStateResults.Error); + } + } +} diff --git a/ZuneUI/AccountCountry.cs b/ZuneUI/AccountCountry.cs new file mode 100644 index 0000000..8e390a1 --- /dev/null +++ b/ZuneUI/AccountCountry.cs @@ -0,0 +1,176 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountCountry +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class AccountCountry : CountryBaseDetails + { + private IDictionary m_states; + private string m_localizedStates; + private static Hashtable m_countryFieldValidatorLookup; + + private AccountCountry( + string abbreviation, + string[] languageAbbreviations, + int teenagerAge, + int adultAge, + bool showAccountSettings, + bool usageCollection, + CountryFieldValidator[] validators, + string localizedStates) + : base(abbreviation, languageAbbreviations, teenagerAge, adultAge, showAccountSettings, usageCollection, validators) + { + this.m_localizedStates = localizedStates; + } + + public IList States + { + get + { + this.LoadStateData(); + ArrayList arrayList = (ArrayList)null; + if (this.m_states != null) + { + arrayList = new ArrayList(this.m_states.Values.Count); + arrayList.AddRange((ICollection)this.m_states.Values); + arrayList.Sort((IComparer)StringComparer.CurrentCultureIgnoreCase); + } + return (IList)arrayList; + } + } + + public CountryFieldValidator GetValidator(CountryFieldValidatorType type) + { + CountryFieldValidator countryFieldValidator = (CountryFieldValidator)null; + if (this.Validators != null && AccountCountry.CountryFieldValidatorLookup.ContainsKey((object)type)) + { + for (int index = 0; index < this.Validators.Length; ++index) + { + CountryFieldValidator validator = this.Validators[index]; + if (validator.Name == (string)AccountCountry.CountryFieldValidatorLookup[(object)type]) + { + countryFieldValidator = validator; + break; + } + } + } + return countryFieldValidator; + } + + public IList StatesAbbreviations + { + get + { + this.LoadStateData(); + string[] array = (string[])null; + if (this.m_states != null) + { + array = new string[this.m_states.Keys.Count]; + this.m_states.Keys.CopyTo(array, 0); + } + return (IList)array; + } + } + + public static AccountCountry Create(CountryBaseDetails details) + { + AccountCountry accountCountry = (AccountCountry)null; + if (details != null) + { + string[] languageAbbreviations = details.LanguageAbbreviations; + if (languageAbbreviations != null) + Array.Sort(languageAbbreviations, LanguageNameComparer.Instance); + string localizedStates = (string)null; + if (details.Abbreviation.Equals("US", StringComparison.InvariantCultureIgnoreCase)) + localizedStates = Shell.LoadString(StringId.IDS_BILLING_USA_STATES); + else if (details.Abbreviation.Equals("CA", StringComparison.InvariantCultureIgnoreCase)) + localizedStates = Shell.LoadString(StringId.IDS_BILLING_CA_PROVINCES); + accountCountry = new AccountCountry(details.Abbreviation, details.LanguageAbbreviations, details.TeenagerAge, details.AdultAge, details.ShowNewsletterOptions, details.UsageCollection, details.Validators, localizedStates); + } + return accountCountry; + } + + public static Hashtable CountryFieldValidatorLookup + { + get + { + if (AccountCountry.m_countryFieldValidatorLookup == null) + { + AccountCountry.m_countryFieldValidatorLookup = new Hashtable(); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.FirstName, (object)"firstName"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.LastName, (object)"lastName"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.AccountHolderName, (object)"accountHolderName"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.Street1, (object)"street1"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.Street2, (object)"street2"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.City, (object)"city"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.State, (object)"state"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.PostalCode, (object)"postalCode"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.District, (object)"district"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.Country, (object)"country"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.PhoneType, (object)"phoneType"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.PhonePrefix, (object)"phonePrefix"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.PhoneNumber, (object)"phoneNumber"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.PhoneCountryCode, (object)"phoneCountryCode"); + AccountCountry.m_countryFieldValidatorLookup.Add((object)CountryFieldValidatorType.PhoneExtension, (object)"phoneExtension"); + } + return AccountCountry.m_countryFieldValidatorLookup; + } + } + + private void LoadStateData() + { + if (this.m_states != null || this.m_localizedStates == null) + return; + string[] strArray = this.m_localizedStates.Split(new char[1] + { + ';' + }, StringSplitOptions.RemoveEmptyEntries); + int capacity = strArray.Length / 2; + this.m_states = (IDictionary)new Dictionary(capacity); + int index1 = 0; + int index2 = 1; + for (int index3 = 0; index3 < capacity; ++index3) + { + if (!this.m_states.ContainsKey(strArray[index1])) + this.m_states.Add(strArray[index1], strArray[index2]); + index1 += 2; + index2 += 2; + } + } + + public string GetStateAbbreviation(string stateName) + { + this.LoadStateData(); + string str = (string)null; + if (this.m_states != null && stateName != null) + { + foreach (KeyValuePair state in (IEnumerable>)this.m_states) + { + if (state.Value.Equals(stateName, StringComparison.InvariantCultureIgnoreCase)) + { + str = state.Key; + break; + } + } + } + return str; + } + + public string GetState(string stateAbbreviation) + { + this.LoadStateData(); + string str = (string)null; + if (this.m_states != null && stateAbbreviation != null && this.m_states.ContainsKey(stateAbbreviation)) + str = this.m_states[stateAbbreviation]; + return str; + } + } +} diff --git a/ZuneUI/AccountCountryList.cs b/ZuneUI/AccountCountryList.cs new file mode 100644 index 0000000..4be0a0a --- /dev/null +++ b/ZuneUI/AccountCountryList.cs @@ -0,0 +1,91 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountCountryList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using System.Collections; +using System.Collections.Generic; +using System.Threading; + +namespace ZuneUI +{ + public class AccountCountryList : NotifyPropertyChangedImpl + { + private static AccountCountryList s_instance; + private IDictionary _countries; + + private AccountCountryList() + { + } + + public static AccountCountryList Instance + { + get + { + if (AccountCountryList.s_instance == null) + AccountCountryList.s_instance = new AccountCountryList(); + return AccountCountryList.s_instance; + } + } + + public IList CountryAbbreviations + { + get + { + string[] array = (string[])null; + if (this._countries != null) + { + array = new string[this._countries.Keys.Count]; + this._countries.Keys.CopyTo(array, 0); + } + return (IList)array; + } + } + + public bool Loaded => this._countries != null; + + public AccountCountry GetCountry(string abbreviation) + { + AccountCountry accountCountry = (AccountCountry)null; + if (this._countries != null && abbreviation != null && this._countries.ContainsKey(abbreviation)) + accountCountry = this._countries[abbreviation]; + return accountCountry; + } + + public void LoadCountryData() => ThreadPool.QueueUserWorkItem(new WaitCallback(this.LoadDataOnWorkerThread)); + + private void LoadDataOnWorkerThread(object state) => this.LoadDataOnWorkerThread(); + + internal bool LoadDataOnWorkerThread() + { + bool flag = true; + if (this._countries == null) + { + CountryBaseDetails[] countryDetails = Microsoft.Zune.Service.Service.Instance.GetCountryDetails(); + SortedDictionary sortedDictionary = (SortedDictionary)null; + if (countryDetails != null && countryDetails.Length > 0) + { + sortedDictionary = new SortedDictionary(CountryNameComparer.Instance); + foreach (CountryBaseDetails details in countryDetails) + sortedDictionary[details.Abbreviation] = AccountCountry.Create(details); + } + if (sortedDictionary == null || sortedDictionary.Count == 0) + flag = false; + else + this._countries = (IDictionary)sortedDictionary; + } + if (flag) + Application.DeferredInvoke(new DeferredInvokeHandler(this.NotifyLoaded), (object)null); + return flag; + } + + private void NotifyLoaded(object args) + { + this.FirePropertyChanged("CountryAbbreviations"); + this.FirePropertyChanged("Loaded"); + } + } +} diff --git a/ZuneUI/AccountCreationFinishStep.cs b/ZuneUI/AccountCreationFinishStep.cs new file mode 100644 index 0000000..2dee91e --- /dev/null +++ b/ZuneUI/AccountCreationFinishStep.cs @@ -0,0 +1,68 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountCreationFinishStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class AccountCreationFinishStep : AccountManagementFinishStep + { + private AccountCreationNextSteps _nextSteps = AccountCreationNextSteps.EditTile; + + public AccountCreationFinishStep(Wizard owner, AccountManagementWizardState state) + : base(owner, state, Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_FINISH)) + { + } + + public override string UI => "res://ZuneShellResources!AccountCreation.uix#AccountCreationFinishStep"; + + internal AccountCreationNextSteps NextSteps + { + get => this._nextSteps; + set + { + if (this._nextSteps == value) + return; + this._nextSteps = value; + this.FirePropertyChanged(nameof(NextSteps)); + this.FireNextStepChanges(); + } + } + + public bool ShowPurchaseZunePass => this.CommittSucceeded && !this.ShowPurchaseZunePassTrial && FeatureEnablement.IsFeatureEnabled(Features.eSubscription) && (this.NextSteps & AccountCreationNextSteps.PurchaseZunePass) == AccountCreationNextSteps.PurchaseZunePass; + + public bool ShowPurchaseZunePassTrial => this.CommittSucceeded && FeatureEnablement.IsFeatureEnabled(Features.eSubscriptionTrial) && (this.NextSteps & AccountCreationNextSteps.PurchaseZunePassTrial) == AccountCreationNextSteps.PurchaseZunePassTrial; + + public bool ShowPurchaseEditTile => this.CommittSucceeded && FeatureEnablement.IsFeatureEnabled(Features.eSocial) && (this.NextSteps & AccountCreationNextSteps.EditTile) == AccountCreationNextSteps.EditTile; + + private void FireNextStepChanges() + { + this.FirePropertyChanged("ShowPurchaseZunePassTrial"); + this.FirePropertyChanged("ShowPurchaseZunePass"); + this.FirePropertyChanged("ShowPurchaseEditTile"); + } + + protected override void OnActivate() + { + if (this.State.PassportPasswordStep.CanCreateAccount || this.State.PassportPasswordStep.IsUpgradeNeeded) + this.LoadStatus = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_STATUS_CREATION); + else + this.LoadStatus = (string)null; + base.OnActivate(); + } + + protected override bool OnCommitChanges() + { + bool flag = !this.State.PassportPasswordStep.CanCreateAccount ? (!this.State.PassportPasswordStep.IsUpgradeNeeded ? this.State.PassportPasswordStep.IsZuneAccount : this.State.UpgradeZuneAccount(true)) : this.State.CreateZuneAccount(); + if (flag) + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredFireNextStepChanges), (object)null); + return flag; + } + + private void DeferredFireNextStepChanges(object unused) => this.FireNextStepChanges(); + } +} diff --git a/ZuneUI/AccountCreationNextSteps.cs b/ZuneUI/AccountCreationNextSteps.cs new file mode 100644 index 0000000..5e19095 --- /dev/null +++ b/ZuneUI/AccountCreationNextSteps.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountCreationNextSteps +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum AccountCreationNextSteps + { + None = 0, + PurchaseZunePass = 1, + PurchaseZunePassTrial = 2, + Default = 3, + EditTile = 3, + } +} diff --git a/ZuneUI/AccountCreationWizard.cs b/ZuneUI/AccountCreationWizard.cs new file mode 100644 index 0000000..2e27bd9 --- /dev/null +++ b/ZuneUI/AccountCreationWizard.cs @@ -0,0 +1,126 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountCreationWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class AccountCreationWizard : AccountManagementWizard + { + private AccountCreationFinishStep _finishStep; + private AccountManagementErrorPage _errorStep; + private static bool _inProgress; + + public AccountCreationWizard() + { + this.RequiresSignIn = false; + this.AddPage((WizardPage)this.State.EmailSelectionStep); + this.AddPage((WizardPage)this.State.PassportPasswordStep); + this.AddPage((WizardPage)this.State.BasicAccountInfoStep); + this.AddPage((WizardPage)this.State.CreatePassportStep); + this.AddPage((WizardPage)this.State.HipPassportStep); + this.AddPage((WizardPage)this.State.EmailSelectionParentStep); + this.AddPage((WizardPage)this.State.PassportPasswordParentStep); + this.AddPage((WizardPage)this.State.CreatePassportParentStep); + this.AddPage((WizardPage)this.State.HipPassportParentStep); + this.AddPage((WizardPage)this.State.ContactInfoParentStep); + this.AddPage((WizardPage)this.State.PaymentInstrumentParentStep); + this.AddPage((WizardPage)this.State.PrivacyInfoParentStep); + this.AddPage((WizardPage)this.State.PrivacyInfoStep); + this.AddPage((WizardPage)this.State.ZuneTagStep); + this._finishStep = new AccountCreationFinishStep((Wizard)this, this.State); + this.AddPage((WizardPage)this._finishStep); + this._errorStep = new AccountManagementErrorPage((Wizard)this, Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ERROR_TITLE), Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ERROR_DESC)); + this.AddPage((WizardPage)this._errorStep); + } + + public void InitializeDefaults( + string defaultUsername, + string defaultPassword, + bool lockUsername) + { + if (string.IsNullOrEmpty(defaultUsername) || string.IsNullOrEmpty(defaultPassword)) + return; + this.State.EmailSelectionStep.PageLocked = lockUsername; + this.State.EmailSelectionStep.SkipOnce = !lockUsername; + this.State.EmailSelectionStep.HasEmail = true; + this.State.EmailSelectionStep.Email = defaultUsername; + this.State.PassportPasswordStep.SkipOnce = true; + this.State.PassportPasswordStep.CommittedEmail = defaultUsername; + this.State.PassportPasswordStep.CommittedPassword = defaultPassword; + this.State.PassportPasswordStep.LockEmail = lockUsername; + } + + public bool ShowNextSteps + { + get => this._finishStep.NextSteps != AccountCreationNextSteps.None; + set + { + AccountCreationNextSteps creationNextSteps = AccountCreationNextSteps.EditTile; + if (!value) + creationNextSteps = AccountCreationNextSteps.None; + if (this._finishStep.NextSteps == creationNextSteps) + return; + this._finishStep.NextSteps = creationNextSteps; + this.FirePropertyChanged(nameof(ShowNextSteps)); + } + } + + public bool HideOnComplete + { + get => this._finishStep.HideOnComplete; + set + { + if (this._finishStep.HideOnComplete == value) + return; + this._finishStep.HideOnComplete = value; + this.FirePropertyChanged(nameof(HideOnComplete)); + } + } + + protected override bool OnStart() + { + this.CurrentPageIndex = -1; + AccountCreationWizard.AccountCreationInProgress = true; + return base.OnStart(); + } + + protected override void OnAsyncCommitCompleted(bool success) + { + base.OnAsyncCommitCompleted(success); + if (!this.CommitSucceeded) + return; + if (this.State.PassportPasswordStep.IsZuneAccount) + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_SUCCESS_EXISTING); + else + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_SUCCESS_NEW); + } + + public override void Cancel() + { + AccountCreationWizard.WizardClosed(true); + base.Cancel(); + } + + public static bool AccountCreationInProgress + { + get => AccountCreationWizard._inProgress; + private set => AccountCreationWizard._inProgress = value; + } + + public static void WizardClosed(bool isCancelled) + { + if (!AccountCreationWizard.AccountCreationInProgress) + return; + AccountCreationWizard.AccountCreationInProgress = false; + if (isCancelled || AccountCreationWizard.CreationCompleted == null) + return; + AccountCreationWizard.CreationCompleted((object)null, (EventArgs)null); + } + + public static event EventHandler CreationCompleted; + } +} diff --git a/ZuneUI/AccountManagementErrorPage.cs b/ZuneUI/AccountManagementErrorPage.cs new file mode 100644 index 0000000..e87cdca --- /dev/null +++ b/ZuneUI/AccountManagementErrorPage.cs @@ -0,0 +1,42 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountManagementErrorPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + public class AccountManagementErrorPage : AccountManagementStep + { + private HRESULT hr = HRESULT._S_OK; + private ServiceError serviceError; + + public AccountManagementErrorPage(Wizard owner, string description, string detailedDescription) + : base(owner, (AccountManagementWizardState)null, false) + { + this.Description = description; + this.DetailDescription = detailedDescription; + } + + public override bool IsEnabled => this.hr.IsError || this.serviceError != null && this.serviceError.RootError.IsError; + + public HRESULT Hr => this.serviceError == null || !this.serviceError.RootError.IsError ? this.hr : this.serviceError.RootError; + + public override string UI => "res://ZuneShellResources!AccountCreation.uix#AccountManagementErrorPage"; + + internal override bool HandleError(HRESULT hr, AccountManagementErrorState errorState) + { + bool flag = false; + if (hr.IsError || errorState != null && errorState.ServiceError != null && errorState.ServiceError.RootError.IsError) + { + flag = true; + this.hr = hr; + if (errorState != null) + this.serviceError = errorState.ServiceError; + } + return flag; + } + } +} diff --git a/ZuneUI/AccountManagementErrorState.cs b/ZuneUI/AccountManagementErrorState.cs new file mode 100644 index 0000000..b6e4e4f --- /dev/null +++ b/ZuneUI/AccountManagementErrorState.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountManagementErrorState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + public class AccountManagementErrorState + { + private bool _parentAccount; + private ServiceError _serviceError; + + internal AccountManagementErrorState(bool parentAccount, ServiceError serviceError) + { + this._parentAccount = parentAccount; + this._serviceError = serviceError; + } + + public bool ParentAccount => this._parentAccount; + + public ServiceError ServiceError => this._serviceError; + } +} diff --git a/ZuneUI/AccountManagementFinishStep.cs b/ZuneUI/AccountManagementFinishStep.cs new file mode 100644 index 0000000..2771106 --- /dev/null +++ b/ZuneUI/AccountManagementFinishStep.cs @@ -0,0 +1,89 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountManagementFinishStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class AccountManagementFinishStep : AccountManagementStep + { + private string _closingMessage; + private bool _hideOnComplete; + private string _oldDescription; + + public AccountManagementFinishStep(Wizard owner, AccountManagementWizardState state) + : this(owner, state, (string)null) + { + } + + public AccountManagementFinishStep( + Wizard owner, + AccountManagementWizardState state, + string description) + : this(owner, state, description, (string)null) + { + this.Description = description; + } + + public AccountManagementFinishStep( + Wizard owner, + AccountManagementWizardState state, + string description, + string detailDescription) + : base(owner, state, false) + { + this.Description = description; + this.DetailDescription = detailDescription; + } + + public override string UI => "res://ZuneShellResources!AccountCreation.uix#AccountManagementFinishStep"; + + public string ClosingMessage + { + get => this._closingMessage; + set + { + if (!(this._closingMessage != value)) + return; + this._closingMessage = value; + this.FirePropertyChanged(nameof(ClosingMessage)); + } + } + + public bool HideOnComplete + { + get => this._hideOnComplete; + set + { + if (this._hideOnComplete == value) + return; + this._hideOnComplete = value; + this.FirePropertyChanged(nameof(HideOnComplete)); + this.UpdateDescription(); + } + } + + internal bool CommittSucceeded + { + get + { + bool flag = false; + if (this._owner is AccountManagementWizard) + flag = ((AccountManagementWizard)this._owner).CommitSucceeded; + return flag; + } + } + + private void UpdateDescription() + { + if (this.HideOnComplete) + { + this._oldDescription = this.Description; + this.Description = Shell.LoadString(StringId.IDS_PLEASE_WAIT_TITLE); + } + else + this.Description = this._oldDescription; + } + } +} diff --git a/ZuneUI/AccountManagementHelper.cs b/ZuneUI/AccountManagementHelper.cs new file mode 100644 index 0000000..5a6cb0a --- /dev/null +++ b/ZuneUI/AccountManagementHelper.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountManagementHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + internal static class AccountManagementHelper + { + internal static HRESULT GetPassportIdentity( + string username, + string password, + out PassportIdentity passportIdentity) + { + return Microsoft.Zune.Service.Service.Instance.AuthenticatePassport(username, password, EPassportPolicyId.MBI_SSL, out passportIdentity); + } + } +} diff --git a/ZuneUI/AccountManagementStep.cs b/ZuneUI/AccountManagementStep.cs new file mode 100644 index 0000000..d43a0b4 --- /dev/null +++ b/ZuneUI/AccountManagementStep.cs @@ -0,0 +1,285 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountManagementStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.ErrorMapperApi; +using Microsoft.Zune.Service; +using System.Collections.Generic; +using System.Threading; + +namespace ZuneUI +{ + public abstract class AccountManagementStep : WizardPropertyEditorPage + { + private AccountManagementWizardState _state; + private bool _parentAccount; + private bool _serviceActivationRequestsDone; + private bool _serviceDeactivationRequestsDone; + private bool _serviceRequestsWorking; + private bool _requireSignIn; + private string _nextTextOverride; + private string _finishTextOverride; + + public AccountManagementStep( + Wizard owner, + AccountManagementWizardState state, + bool parentAccount) + : base(owner) + { + this._parentAccount = parentAccount; + this._state = state; + this._serviceActivationRequestsDone = true; + this._serviceDeactivationRequestsDone = true; + this._serviceRequestsWorking = false; + this.EnableVerticalScrolling = true; + } + + public override bool IsEnabled => (!this.RequireSignIn || SignIn.Instance.SignedIn) && (this._owner.CurrentPage != this || !this.ServiceRequestWorking); + + protected bool RequireSignIn + { + get => this._requireSignIn; + set + { + if (this._requireSignIn == value) + return; + this._requireSignIn = value; + this.FirePropertyChanged(nameof(RequireSignIn)); + this.FirePropertyChanged("IsEnabled"); + } + } + + public AccountManagementWizardState State => this._state; + + public string NextTextOverride + { + get => this._nextTextOverride; + set + { + if (!(this._nextTextOverride != value)) + return; + this._nextTextOverride = value; + this.FirePropertyChanged(nameof(NextTextOverride)); + } + } + + public string FinishTextOverride + { + get => this._finishTextOverride; + set + { + if (!(this._finishTextOverride != value)) + return; + this._finishTextOverride = value; + this.FirePropertyChanged(nameof(FinishTextOverride)); + } + } + + public bool ServiceActivationRequestsDone + { + get => this._serviceActivationRequestsDone; + protected set + { + if (this._serviceActivationRequestsDone == value) + return; + this._serviceActivationRequestsDone = value; + this.FirePropertyChanged("ServiceDeactivationRequestsDone"); + } + } + + public bool ServiceDeactivationRequestsDone + { + get => this._serviceDeactivationRequestsDone; + protected set + { + if (this._serviceDeactivationRequestsDone == value) + return; + this._serviceDeactivationRequestsDone = value; + this.FirePropertyChanged(nameof(ServiceDeactivationRequestsDone)); + } + } + + public bool ServiceRequestWorking + { + get => this._serviceRequestsWorking; + private set + { + if (this._serviceRequestsWorking == value) + return; + this._serviceRequestsWorking = value; + this.FirePropertyChanged(nameof(ServiceRequestWorking)); + if (this._owner.CurrentPage != this) + return; + this.FirePropertyChanged("IsEnabled"); + } + } + + public bool ParentAccount => this._parentAccount; + + internal virtual Dictionary ErrorPropertyMappings => (Dictionary)null; + + internal virtual ErrorMapperResult GetMappedErrorDescriptionAndUrl(HRESULT hr) => Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int, eErrorCondition.eEC_None); + + internal void SetError(HRESULT hr, ServiceError serviceError) => this._owner.SetError(hr, (object)new AccountManagementErrorState(this.ParentAccount, serviceError)); + + internal bool HandleError() + { + HRESULT error = this._owner.Error; + AccountManagementErrorState errorState = (AccountManagementErrorState)null; + if (this._owner is AccountManagementWizard) + errorState = ((AccountManagementWizard)this._owner).LastErrorState; + bool flag = error.IsSuccess && errorState == null; + if (!flag) + { + flag = this.HandleError(error, errorState); + if (flag) + this._owner.ResetError(); + } + return flag; + } + + internal virtual bool HandleError(HRESULT hr, AccountManagementErrorState errorState) + { + bool flag1 = hr.IsSuccess && errorState == null; + bool flag2 = (errorState == null || errorState.ParentAccount == this.ParentAccount) && this.IsEnabled; + if (!flag1 && flag2) + { + if (this.SetExternalPropertyError(hr, (string)null)) + flag1 = true; + if (errorState != null && errorState.ServiceError != null) + { + if (this.SetExternalPropertyError(errorState.ServiceError.RootError, (string)null)) + flag1 = true; + if (errorState.ServiceError.PropertyErrors != null) + { + foreach (PropertyError propertyError in (IEnumerable)errorState.ServiceError.PropertyErrors) + { + if (this.SetExternalPropertyError(propertyError.Hr, propertyError.Name)) + flag1 = true; + } + } + } + if (flag1) + { + this.ShowGenericErrorStatus(); + this.ShowValidation(); + } + } + return flag1; + } + + internal bool NavigateToErrorHandler() + { + bool flag = false; + if (this._owner is AccountManagementWizard) + { + ((AccountManagementWizard)this._owner).NavigateToErrorHandler(); + flag = true; + } + return flag; + } + + internal override sealed void Activate() + { + base.Activate(); + if (!this.HandleError() && this.NavigateToErrorHandler()) + return; + this.OnActivate(); + } + + internal override bool OnMovingNext() + { + if (this.ServiceDeactivationRequestsDone) + { + this.StatusMessage = (string)null; + return base.OnMovingNext(); + } + this.StartDeactivationRequests((object)null); + return false; + } + + protected bool SetExternalPropertyError(HRESULT hr, string propertyName) + { + string str = (string)null; + bool flag = false; + if (hr.IsError && this.ErrorPropertyMappings != null) + { + ErrorMapperResult descriptionAndUrl = this.GetMappedErrorDescriptionAndUrl(hr); + if (descriptionAndUrl != null && this.ErrorPropertyMappings.ContainsKey(descriptionAndUrl.Hr)) + { + flag = true; + PropertyDescriptor errorPropertyMapping = this.ErrorPropertyMappings[descriptionAndUrl.Hr]; + if (errorPropertyMapping == null || !this.SetExternalError(errorPropertyMapping, new HRESULT(descriptionAndUrl.Hr))) + str = descriptionAndUrl.Description; + } + else if (!string.IsNullOrEmpty(propertyName) && descriptionAndUrl != null) + flag = this.SetExternalError(propertyName, new HRESULT(descriptionAndUrl.Hr)); + } + if (flag) + this.StatusMessage = str; + return flag; + } + + protected virtual void OnActivate() + { + if (this.ServiceActivationRequestsDone) + return; + this.StartActivationRequests((object)null); + } + + protected void StartActivationRequests(object state) + { + if (this.ServiceRequestWorking) + return; + this.ServiceRequestWorking = true; + ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncStartActivationRequests), state); + } + + private void AsyncStartActivationRequests(object state) => this.OnStartActivationRequests(state); + + protected virtual void OnStartActivationRequests(object state) => this.EndActivationRequests((object)null); + + protected void EndActivationRequests(object args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredEndActivationRequests), args); + + private void DeferredEndActivationRequests(object args) + { + this.OnEndActivationRequests(args); + this.ServiceActivationRequestsDone = true; + this.ServiceRequestWorking = false; + } + + protected virtual void OnEndActivationRequests(object args) + { + } + + protected void StartDeactivationRequests(object state) + { + if (this.ServiceRequestWorking) + return; + this.StatusMessage = (string)null; + this.ServiceRequestWorking = true; + ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncStartDeactivationRequests), state); + } + + private void AsyncStartDeactivationRequests(object state) => this.OnStartDeactivationRequests(state); + + protected virtual void OnStartDeactivationRequests(object state) => this.EndDeactivationRequests((object)null); + + protected void EndDeactivationRequests(object args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DerferredEndDeactivationRequests), args); + + private void DerferredEndDeactivationRequests(object args) + { + this.ServiceDeactivationRequestsDone = true; + this.ServiceRequestWorking = false; + this.OnEndDeactivationRequests(args); + this._owner.MoveNext(); + } + + protected virtual void OnEndDeactivationRequests(object args) + { + } + } +} diff --git a/ZuneUI/AccountManagementWizard.cs b/ZuneUI/AccountManagementWizard.cs new file mode 100644 index 0000000..2165d08 --- /dev/null +++ b/ZuneUI/AccountManagementWizard.cs @@ -0,0 +1,114 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountManagementWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class AccountManagementWizard : Wizard + { + private bool _commitSucceeded; + private bool _commitFailed; + private bool _requiresSignIn = true; + private AccountManagementWizardState _state; + private AccountManagementErrorState _lastErrorState; + + protected AccountManagementWizard() + { + } + + public AccountManagementWizardState State + { + get + { + if (this._state == null) + this._state = new AccountManagementWizardState(this); + return this._state; + } + } + + public override bool CanStart => !this.RequiresSignIn || SignIn.Instance.SignedIn; + + public bool RequiresSignIn + { + get => this._requiresSignIn; + set + { + if (this._requiresSignIn == value) + return; + this._requiresSignIn = value; + this.FirePropertyChanged(nameof(RequiresSignIn)); + } + } + + public bool CommitSucceeded + { + get => this._commitSucceeded; + private set + { + if (this._commitSucceeded == value) + return; + this._commitSucceeded = value; + this.FirePropertyChanged(nameof(CommitSucceeded)); + } + } + + public bool CommitFailed + { + get => this._commitFailed; + private set + { + if (this._commitFailed == value) + return; + this._commitFailed = value; + this.FirePropertyChanged(nameof(CommitFailed)); + } + } + + public AccountManagementErrorState LastErrorState + { + get => this._lastErrorState; + private set + { + if (this._lastErrorState == value) + return; + this._lastErrorState = value; + this.FirePropertyChanged("LastServiceError"); + } + } + + public void NavigateToErrorHandler() => this.NavigateToErrorHandler(this.Error, this.LastErrorState); + + public void NavigateToErrorHandler(HRESULT hr, AccountManagementErrorState errorState) + { + int num = -1; + IList pages = this.Pages; + int currentPageIndex = this.CurrentPageIndex; + for (int index1 = 0; index1 < pages.Count; ++index1) + { + int index2 = (currentPageIndex + index1) % pages.Count; + if (num == -1 && pages[index2] is AccountManagementErrorPage) + num = index2; + else if (pages[index2] is AccountManagementStep && ((AccountManagementStep)pages[index2]).HandleError(hr, errorState)) + { + num = index2; + break; + } + } + if (num < 0) + return; + this.CurrentPageIndex = num; + } + + protected override void OnAsyncCommitCompleted(bool success) + { + this.CommitSucceeded = success; + this.CommitFailed = !success; + } + + protected override void OnSetError(HRESULT hr, object state) => this.LastErrorState = state as AccountManagementErrorState; + } +} diff --git a/ZuneUI/AccountManagementWizardState.cs b/ZuneUI/AccountManagementWizardState.cs new file mode 100644 index 0000000..eb8b82f --- /dev/null +++ b/ZuneUI/AccountManagementWizardState.cs @@ -0,0 +1,421 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AccountManagementWizardState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public class AccountManagementWizardState + { + private AccountManagementWizard _wizard; + private BasicAccountInfoStep _basicAccountInfoStep; + private EditContactInfoStep _contactInfoStep; + private ContactInfoParentStep _contactInfoParentStep; + private CreatePassportStep _createPassportStep; + private CreatePassportStep _createPassportParentStep; + private EmailSelectionStep _emailSelectionStep; + private EmailSelectionStep _emailSelectionParentStep; + private PassportPasswordStep _passportPasswordStep; + private PassportPasswordStep _passportPasswordParentStep; + private PaymentInstrumentStep _paymentInstrumentStep; + private ParentPaymentIntrumentStep _paymentInstrumentParentStep; + private HipPassportStep _hipPassportStep; + private HipPassportStep _hipPassportParentStep; + private PrivacyInfoStep _privacyInfoStep; + private PrivacyInfoStep _privacyInfoParentStep; + private TermsOfServiceStep _termsOfServiceStep; + private ZuneTagStep _zuneTagStep; + private SelectBillingOfferStep _selectBillingOfferStep; + private SelectPaymentInstrumentStep _selectPaymentInstrumentStep; + private ConfirmationStep _confirmationStep; + private ListAndAddPaymentInstrumentStep _listAndAddPaymentInstrumentStep; + private RedeemCodeStep _redeemCodeStep; + private WinLiveSignup _winLiveSignup; + private AccountManagement _accountManagment; + + public AccountManagementWizardState(AccountManagementWizard wizard) => this._wizard = wizard; + + public BasicAccountInfoStep BasicAccountInfoStep + { + get + { + if (this._basicAccountInfoStep == null) + this._basicAccountInfoStep = new BasicAccountInfoStep((Wizard)this._wizard, this, false); + return this._basicAccountInfoStep; + } + } + + public EditContactInfoStep ContactInfoStep + { + get + { + if (this._contactInfoStep == null) + this._contactInfoStep = new EditContactInfoStep((Wizard)this._wizard, this); + return this._contactInfoStep; + } + } + + public ContactInfoParentStep ContactInfoParentStep + { + get + { + if (this._contactInfoParentStep == null) + this._contactInfoParentStep = new ContactInfoParentStep((Wizard)this._wizard, this); + return this._contactInfoParentStep; + } + } + + public CreatePassportStep CreatePassportStep + { + get + { + if (this._createPassportStep == null) + this._createPassportStep = new CreatePassportStep((Wizard)this._wizard, this, false); + return this._createPassportStep; + } + } + + public CreatePassportStep CreatePassportParentStep + { + get + { + if (this._createPassportParentStep == null) + this._createPassportParentStep = new CreatePassportStep((Wizard)this._wizard, this, true); + return this._createPassportParentStep; + } + } + + public EmailSelectionStep EmailSelectionStep + { + get + { + if (this._emailSelectionStep == null) + this._emailSelectionStep = new EmailSelectionStep((Wizard)this._wizard, this, false); + return this._emailSelectionStep; + } + } + + public EmailSelectionStep EmailSelectionParentStep + { + get + { + if (this._emailSelectionParentStep == null) + this._emailSelectionParentStep = new EmailSelectionStep((Wizard)this._wizard, this, true); + return this._emailSelectionParentStep; + } + } + + public HipPassportStep HipPassportStep + { + get + { + if (this._hipPassportStep == null) + this._hipPassportStep = new HipPassportStep((Wizard)this._wizard, this, false); + return this._hipPassportStep; + } + } + + public HipPassportStep HipPassportParentStep + { + get + { + if (this._hipPassportParentStep == null) + this._hipPassportParentStep = new HipPassportStep((Wizard)this._wizard, this, true); + return this._hipPassportParentStep; + } + } + + public PassportPasswordStep PassportPasswordStep + { + get + { + if (this._passportPasswordStep == null) + this._passportPasswordStep = new PassportPasswordStep((Wizard)this._wizard, this, false); + return this._passportPasswordStep; + } + } + + public PassportPasswordStep PassportPasswordParentStep + { + get + { + if (this._passportPasswordParentStep == null) + this._passportPasswordParentStep = new PassportPasswordStep((Wizard)this._wizard, this, true); + return this._passportPasswordParentStep; + } + } + + public PaymentInstrumentStep PaymentInstrumentStep + { + get + { + if (this._paymentInstrumentStep == null) + this._paymentInstrumentStep = new PaymentInstrumentStep((Wizard)this._wizard, this, false); + return this._paymentInstrumentStep; + } + } + + public ParentPaymentIntrumentStep PaymentInstrumentParentStep + { + get + { + if (this._paymentInstrumentParentStep == null) + this._paymentInstrumentParentStep = new ParentPaymentIntrumentStep((Wizard)this._wizard, this); + return this._paymentInstrumentParentStep; + } + } + + public PrivacyInfoStep PrivacyInfoStep + { + get + { + if (this._privacyInfoStep == null) + this._privacyInfoStep = new PrivacyInfoStep((Wizard)this._wizard, this, false, PrivacyInfoSettings.None); + return this._privacyInfoStep; + } + } + + public PrivacyInfoStep PrivacyInfoParentStep + { + get + { + if (this._privacyInfoParentStep == null) + this._privacyInfoParentStep = new PrivacyInfoStep((Wizard)this._wizard, this, true, PrivacyInfoSettings.None); + return this._privacyInfoParentStep; + } + } + + public TermsOfServiceStep TermsOfServiceStep + { + get + { + if (this._termsOfServiceStep == null) + this._termsOfServiceStep = new TermsOfServiceStep((Wizard)this._wizard, this, false); + return this._termsOfServiceStep; + } + } + + public ZuneTagStep ZuneTagStep + { + get + { + if (this._zuneTagStep == null) + this._zuneTagStep = new ZuneTagStep((Wizard)this._wizard, this, false); + return this._zuneTagStep; + } + } + + public SelectBillingOfferStep SelectBillingOfferStep + { + get + { + if (this._selectBillingOfferStep == null) + this._selectBillingOfferStep = new SelectBillingOfferStep((Wizard)this._wizard, this); + return this._selectBillingOfferStep; + } + } + + public SelectPaymentInstrumentStep SelectPaymentInstrumentStep + { + get + { + if (this._selectPaymentInstrumentStep == null) + this._selectPaymentInstrumentStep = new SelectPaymentInstrumentStep((Wizard)this._wizard, this, false); + return this._selectPaymentInstrumentStep; + } + } + + public ConfirmationStep ConfirmationStep + { + get + { + if (this._confirmationStep == null) + this._confirmationStep = new ConfirmationStep((Wizard)this._wizard, this, false); + return this._confirmationStep; + } + } + + public ListAndAddPaymentInstrumentStep ListAndAddPaymentInstrumentStep + { + get + { + if (this._listAndAddPaymentInstrumentStep == null) + this._listAndAddPaymentInstrumentStep = new ListAndAddPaymentInstrumentStep((Wizard)this._wizard, this, false); + return this._listAndAddPaymentInstrumentStep; + } + } + + public RedeemCodeStep RedeemCodeStep + { + get + { + if (this._redeemCodeStep == null) + this._redeemCodeStep = new RedeemCodeStep((Wizard)this._wizard, this); + return this._redeemCodeStep; + } + } + + public WinLiveSignup WinLiveSignup + { + get + { + if (this._winLiveSignup == null) + this._winLiveSignup = new WinLiveSignup(); + return this._winLiveSignup; + } + } + + public AccountManagement AccountManagement + { + get + { + if (this._accountManagment == null) + this._accountManagment = new AccountManagement(); + return this._accountManagment; + } + } + + internal void SetPrivacySettings(AccountUserType type) + { + if (type == AccountUserType.Adult) + { + this.PrivacyInfoStep.ShowSettings = FeatureEnablement.IsFeatureEnabled(Features.eSocial) ? PrivacyInfoSettings.CreateNewAccountWithSocial : PrivacyInfoSettings.CreateNewAccount; + this.PrivacyInfoParentStep.ShowSettings = PrivacyInfoSettings.None; + } + else + { + this.PrivacyInfoStep.ShowSettings = PrivacyInfoSettings.AllowMicrosoftCommunications; + if (type == AccountUserType.ChildWithSocial) + this.PrivacyInfoParentStep.ShowSettings = FeatureEnablement.IsFeatureEnabled(Features.eSocial) ? PrivacyInfoSettings.CreateChildAccountWithSocial : PrivacyInfoSettings.CreateChildAccount; + else + this.PrivacyInfoParentStep.ShowSettings = PrivacyInfoSettings.CreateChildAccount; + } + } + + internal bool AcceptTermsOfService() => this.UpgradeZuneAccount(true, this.TermsOfServiceStep.PassportIdentity); + + internal bool UpgradeZuneAccount(bool includeAccountSettings) + { + PassportIdentity passportIdentity = this.GetPassportIdentity(); + return this.UpgradeZuneAccount(includeAccountSettings, passportIdentity); + } + + public void SaveFamilySettings() + { + if (!SignIn.Instance.SignedIn || !this.PrivacyInfoParentStep.IsEnabled || this.PrivacyInfoParentStep.FamilySettings == null) + return; + this.PrivacyInfoParentStep.FamilySettings.UserId = SignIn.Instance.LastSignedInUserId; + this.PrivacyInfoParentStep.FamilySettings.CommitSettings(); + SignIn.Instance.FamilySettings.ReloadSettings(); + } + + internal bool UpgradeZuneAccount(bool includeAccountSettings, PassportIdentity passportIdentity) + { + PassportIdentity passportIdentity1 = this.GetParentPassportIdentity(); + AccountSettings accountSettings = (AccountSettings)null; + if (includeAccountSettings) + { + if (this.PrivacyInfoParentStep.IsEnabled) + { + accountSettings = this.PrivacyInfoParentStep.CommittedSettings; + accountSettings.AllowPartnerEmails = this.PrivacyInfoStep.CommittedSettings.AllowPartnerEmails; + accountSettings.AllowZuneEmails = this.PrivacyInfoStep.CommittedSettings.AllowZuneEmails; + } + else + accountSettings = this.PrivacyInfoStep.CommittedSettings; + } + ServiceError serviceError = (ServiceError)null; + HRESULT hr = this.AccountManagement.UpgradeAccount(passportIdentity, accountSettings, passportIdentity1, out serviceError); + bool isSuccess = hr.IsSuccess; + if (!isSuccess) + this._wizard.SetError(hr, (object)new AccountManagementErrorState(false, serviceError)); + return isSuccess; + } + + internal string GetEmailAddress() + { + string empty = string.Empty; + return this.CreatePassportStep.IsEnabled || this.CreatePassportStep.CreatedPassport ? this.CreatePassportStep.Email : this.PassportPasswordStep.CommittedEmail; + } + + internal bool CreateZuneAccount() + { + PassportIdentity passportIdentity1 = this.GetPassportIdentity(); + string committedValue1 = this.ZuneTagStep.GetCommittedValue(ZuneTagPropertyEditor.ZuneTag) as string; + string emailAddress = this.GetEmailAddress(); + string selectedLocale = this.BasicAccountInfoStep.SelectedLocale; + DateTime? committedValue2 = (DateTime?)this.BasicAccountInfoStep.GetCommittedValue(BasicAccountInfoPropertyEditor.Birthday); + PassportIdentity passportIdentity2 = this.GetParentPassportIdentity(); + CreditCard parentCreditCard = (CreditCard)null; + AccountSettings committedSettings; + if (this.BasicAccountInfoStep.IsParentAccountNeeded || this.PassportPasswordStep.IsParentAccountNeeded) + { + committedSettings = this.PrivacyInfoParentStep.CommittedSettings; + committedSettings.AllowPartnerEmails = this.PrivacyInfoStep.CommittedSettings != null && this.PrivacyInfoStep.CommittedSettings.AllowPartnerEmails; + committedSettings.AllowZuneEmails = this.PrivacyInfoStep.CommittedSettings != null && this.PrivacyInfoStep.CommittedSettings.AllowZuneEmails; + parentCreditCard = this.PaymentInstrumentParentStep.CommittedCreditCard; + } + else + committedSettings = this.PrivacyInfoStep.CommittedSettings; + Address address = new Address(); + address.PostalCode = this.BasicAccountInfoStep.GetCommittedValue(BasicAccountInfoPropertyEditor.PostalCode) as string; + ServiceError serviceError = (ServiceError)null; + HRESULT account = this.AccountManagement.CreateAccount(passportIdentity1, committedValue1, selectedLocale, committedValue2.Value, string.Empty, string.Empty, emailAddress, address, committedSettings, passportIdentity2, parentCreditCard, out serviceError); + bool isSuccess = account.IsSuccess; + if (!isSuccess) + this._wizard.SetError(account, (object)new AccountManagementErrorState(false, serviceError)); + return isSuccess; + } + + internal bool PurchaseBillingOffer( + BillingOffer billingOffer, + PaymentInstrument paymentInstrument) + { + HRESULT hr = (HRESULT)Microsoft.Zune.Service.Service.Instance.PurchaseBillingOffer(billingOffer, paymentInstrument); + if (hr.IsError) + this._wizard.SetError(hr, (object)null); + else if (billingOffer.OfferType == Microsoft.Zune.Service.EBillingOfferType.Subscription || billingOffer.OfferType == Microsoft.Zune.Service.EBillingOfferType.Trial || billingOffer.OfferType == Microsoft.Zune.Service.EBillingOfferType.Renewal) + SignIn.Instance.RefreshAccount(); + return hr.IsSuccess; + } + + internal bool RedeemCode() => this.PurchaseBillingOffer(this.RedeemCodeStep.MatchingBillingOffer, (PaymentInstrument)this.RedeemCodeStep.TokenDetails); + + private PassportIdentity GetPassportIdentity() + { + PassportIdentity passportIdentity = (PassportIdentity)null; + if (this.PassportPasswordStep.IsEnabled) + passportIdentity = this.PassportPasswordStep.PassportIdentity; + else + AccountManagementHelper.GetPassportIdentity(this.CreatePassportStep.Email, this.CreatePassportStep.GetCommittedValue(CreatePassportPropertyEditor.Password1) as string, out passportIdentity); + return passportIdentity; + } + + private PassportIdentity GetParentPassportIdentity() + { + PassportIdentity passportIdentity = (PassportIdentity)null; + if (this.PassportPasswordParentStep.IsEnabled) + passportIdentity = this.PassportPasswordParentStep.PassportIdentity; + else if (this.CreatePassportParentStep.CreatedPassport) + AccountManagementHelper.GetPassportIdentity(this.CreatePassportParentStep.Email, this.CreatePassportParentStep.GetCommittedValue(CreatePassportPropertyEditor.Password1) as string, out passportIdentity); + return passportIdentity; + } + + public void SignInNewUser() + { + string emailAddress = this.GetEmailAddress(); + string committedValue = this.PassportPasswordStep.GetCommittedValue(PassportPasswordPropertyEditor.Password) as string; + if (string.IsNullOrEmpty(committedValue)) + committedValue = this.CreatePassportStep.GetCommittedValue(CreatePassportPropertyEditor.Password1) as string; + SignIn.Instance.SignOut(); + SignIn.Instance.SignInUser(emailAddress, committedValue, true, false, false); + } + + public bool IsPurchaseConfirmationNeeded => FeatureEnablement.IsFeatureEnabled(Features.eSubscriptionConfirmation); + } +} diff --git a/ZuneUI/AddCreditCardToAccountWizard.cs b/ZuneUI/AddCreditCardToAccountWizard.cs new file mode 100644 index 0000000..a6843bc --- /dev/null +++ b/ZuneUI/AddCreditCardToAccountWizard.cs @@ -0,0 +1,49 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AddCreditCardToAccountWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class AddCreditCardToAccountWizard : AccountManagementWizard + { + private AccountManagementFinishStep _finishStep; + private AccountManagementErrorPage _errorStep; + + public AddCreditCardToAccountWizard() + { + this.State.ContactInfoStep.LightWeightOnly = true; + this._finishStep = new AccountManagementFinishStep((Wizard)this, this.State, Shell.LoadString(StringId.IDS_ACCOUNT_FINISHED_DESCRIPTION)); + this._errorStep = new AccountManagementErrorPage((Wizard)this, Shell.LoadString(StringId.IDS_ACCOUNT_ADD_CC_TO_ACCOUNT_ERROR_TITLE), Shell.LoadString(StringId.IDS_ACCOUNT_ADD_CC_TO_ACCOUNT_ERROR_DESC)); + PaymentInstrumentStep paymentInstrumentStep = this.State.PaymentInstrumentStep; + paymentInstrumentStep.NextTextOverride = Shell.LoadString(StringId.IDS_OK_BUTTON); + paymentInstrumentStep.DetailDescription = Shell.LoadString(StringId.IDS_BILLING_ADD_CC_TO_ACCOUNT_DESC); + this.AddPage((WizardPage)this.State.ContactInfoStep); + this.AddPage((WizardPage)this.State.ListAndAddPaymentInstrumentStep); + this.AddPage((WizardPage)paymentInstrumentStep); + this.AddPage((WizardPage)this._finishStep); + this.AddPage((WizardPage)this._errorStep); + } + + public bool HideOnComplete + { + get => this._finishStep.HideOnComplete; + set + { + if (this._finishStep.HideOnComplete == value) + return; + this._finishStep.HideOnComplete = value; + this.FirePropertyChanged(nameof(HideOnComplete)); + } + } + + protected override void OnAsyncCommitCompleted(bool success) + { + base.OnAsyncCommitCompleted(success); + if (!success) + return; + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_ACCOUNT_ADD_CC_TO_ACCOUNT_SUCCESS_DESC); + } + } +} diff --git a/ZuneUI/AddTransientMediaTask.cs b/ZuneUI/AddTransientMediaTask.cs new file mode 100644 index 0000000..7d683d7 --- /dev/null +++ b/ZuneUI/AddTransientMediaTask.cs @@ -0,0 +1,87 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AddTransientMediaTask +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Shell; +using System; +using System.Threading; + +namespace ZuneUI +{ + internal class AddTransientMediaTask + { + private string _filePath; + private MediaType _mediaType; + private int _dbMediaId; + private bool _fFileAlreadyExists; + private bool _fAddSuccessful; + private ManualResetEvent _event; + + private AddTransientMediaTask(string filePath, MediaType mediaType) + { + this._filePath = filePath; + this._mediaType = mediaType; + } + + private void TaskFunction(object obj) + { + this._dbMediaId = -1; + this._fFileAlreadyExists = false; + this._fAddSuccessful = false; + if (!string.IsNullOrEmpty(this._filePath)) + this._fAddSuccessful = ZuneApplication.AddTransientMedia(this._filePath, this._mediaType, out this._dbMediaId, out this._fFileAlreadyExists); + if (this._event == null) + return; + this._event.Set(); + } + + private bool RunSyncTask( + TimeSpan timeout, + out int dbMediaId, + out bool fFileAlreadyExists, + out bool fTimedout) + { + dbMediaId = -1; + fFileAlreadyExists = false; + fTimedout = false; + bool flag = false; + if (!string.IsNullOrEmpty(this._filePath)) + { + if (timeout.TotalSeconds > 0.0) + { + this._event = new ManualResetEvent(false); + ThreadPool.QueueUserWorkItem(new WaitCallback(this.TaskFunction)); + if (this._event.WaitOne(timeout, false)) + { + dbMediaId = this._dbMediaId; + fFileAlreadyExists = this._fFileAlreadyExists; + flag = this._fAddSuccessful; + } + else + fTimedout = true; + } + else + { + this.TaskFunction((object)null); + dbMediaId = this._dbMediaId; + fFileAlreadyExists = this._fFileAlreadyExists; + flag = this._fAddSuccessful; + } + } + return flag; + } + + public static bool AddTransientMediaWithTimeout( + string filePath, + MediaType mediaType, + TimeSpan timeout, + out int dbMediaId, + out bool fFileAlreadyExists, + out bool fTimedout) + { + return new AddTransientMediaTask(filePath, mediaType).RunSyncTask(timeout, out dbMediaId, out fFileAlreadyExists, out fTimedout); + } + } +} diff --git a/ZuneUI/AlbumArtUpdateHandler.cs b/ZuneUI/AlbumArtUpdateHandler.cs new file mode 100644 index 0000000..4fe2810 --- /dev/null +++ b/ZuneUI/AlbumArtUpdateHandler.cs @@ -0,0 +1,183 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AlbumArtUpdateHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections.Specialized; +using UIXControls; + +namespace ZuneUI +{ + public class AlbumArtUpdateHandler : ModelItem + { + private const string _supportedExtensionsFilter = "*.bmp;*.jpg;*.jpeg;*.gif;*.png;*.dib"; + private object _album; + private string _path; + private bool _done; + private Image _image; + private BooleanChoice _neverShowPasteMessage; + private static string[] _supportedExtensions = new string[6] + { + ".bmp", + ".jpg", + ".jpeg", + ".gif", + ".png", + ".dib" + }; + + public AlbumArtUpdateHandler(object album) => this._album = album; + + protected override void OnDispose(bool disposing) + { + if (this._neverShowPasteMessage != null) + { + this._neverShowPasteMessage.Dispose(); + this._neverShowPasteMessage = (BooleanChoice)null; + } + base.OnDispose(disposing); + } + + public object Album => this._album; + + public string Path + { + get => this._path; + private set + { + if (!(value != this._path)) + return; + this._path = value; + this.FirePropertyChanged(nameof(Path)); + this.Image = (Image)null; + } + } + + public bool Done + { + get => this._done; + private set + { + if (value == this._done) + return; + this._done = value; + this.FirePropertyChanged(nameof(Done)); + } + } + + public Image Image + { + get + { + if (this._image == null && !string.IsNullOrEmpty(this._path)) + this._image = new Image("file://" + this._path); + return this._image; + } + private set + { + if (value == this._image) + return; + this._image = value; + this.FirePropertyChanged(nameof(Image)); + } + } + + public void Start() => this.Start(true); + + public void Start(bool allowPaste) + { + this.Done = false; + this.Path = (string)null; + if (allowPaste && AlbumArtUpdateHandler.CanPaste()) + { + if (ZuneShell.DefaultInstance.Management.ConfirmPasteAlbumArt) + { + if (this._neverShowPasteMessage == null) + this._neverShowPasteMessage = new BooleanChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_DONT_SHOW_THIS_MESSAGE_AGAIN)); + string str = (string)null; + if (this.Album is DataProviderObject album) + str = album.GetProperty("Title") as string; + string message = !string.IsNullOrEmpty(str) ? string.Format(Shell.LoadString(StringId.IDS_CONFIRM_PASTE_ALBUM_ART), (object)str) : Shell.LoadString(StringId.IDS_CONFIRM_PASTE_ALBUM_ART_NO_NAME); + this._neverShowPasteMessage.Value = false; + MessageBox.Show(Shell.LoadString(StringId.IDS_CONFIRM_PASTE_ALBUM_ART_TITLE), message, (EventHandler)null, new EventHandler(this.ConfirmPaste), (EventHandler)null, (EventHandler)null, this._neverShowPasteMessage); + } + else + this.ConfirmPaste((object)this, (EventArgs)null); + } + else + this.BrowseForArt(); + } + + public static bool CanPaste() + { + bool flag = Clipboard.ContainsData(ClipboardDataType.Image); + if (!flag && Clipboard.ContainsData(ClipboardDataType.FileDropList)) + flag = AlbumArtUpdateHandler.GetClipboardFile() != null; + return flag; + } + + private void BrowseForArt() => FileOpenDialog.Show(Shell.LoadString(StringId.IDS_CHOOSE_ALBUM_ART), FileOpenDialog.MyPicturesPath, new string[2] + { + Shell.LoadString(StringId.IDS_ALBUM_ART_DIALOG_ALL_PICTURES), + "*.bmp;*.jpg;*.jpeg;*.gif;*.png;*.dib" + }, (DeferredInvokeHandler)(args => + { + this.Path = (string)args; + this.Done = true; + })); + + private void ConfirmPaste(object sender, EventArgs args) + { + if (this._neverShowPasteMessage != null) + ZuneShell.DefaultInstance.Management.ConfirmPasteAlbumArt = !this._neverShowPasteMessage.Value; + if (this.Paste()) + this.Done = true; + else + this.BrowseForArt(); + } + + private bool Paste() + { + bool flag = false; + if (this._album is LibraryDataProviderListItem) + { + LibraryDataProviderListItem album = (LibraryDataProviderListItem)this._album; + SafeBitmap image = Clipboard.GetImage(); + if (image != null) + flag = album.SetNewThumbnail(image); + if (!flag) + { + string clipboardFile = AlbumArtUpdateHandler.GetClipboardFile(); + if (clipboardFile != null) + { + this.Path = clipboardFile; + flag = true; + } + } + } + return flag; + } + + private static string GetClipboardFile() + { + StringCollection fileDropList = Clipboard.GetFileDropList(); + if (fileDropList != null) + { + foreach (string str in fileDropList) + { + foreach (string supportedExtension in AlbumArtUpdateHandler._supportedExtensions) + { + if (str.EndsWith(supportedExtension, StringComparison.InvariantCultureIgnoreCase)) + return str; + } + } + } + return (string)null; + } + } +} diff --git a/ZuneUI/AlbumAttachment.cs b/ZuneUI/AlbumAttachment.cs new file mode 100644 index 0000000..848eb42 --- /dev/null +++ b/ZuneUI/AlbumAttachment.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AlbumAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public class AlbumAttachment : Attachment + { + public const string RequestTypeString = "album"; + + public AlbumAttachment(Guid id, string title, string artist, string imageUri, Guid imageId) + : base(id, title, artist, UrlHelper.MakeCatalogImageUri(imageId)) + { + this.AttachmentUI = "res://ZuneShellResources!SocialComposer.uix#AlbumAttachmentUI"; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_ALBUM_ATTACHMENT); + } + + public override MediaType MediaType => MediaType.Album; + + public override string RequestType => "album"; + + public override void LogSend() => SQMLog.Log(SQMDataId.InboxMessageSendAlbum, 1); + } +} diff --git a/ZuneUI/AlbumMetadataPropertySource.cs b/ZuneUI/AlbumMetadataPropertySource.cs new file mode 100644 index 0000000..1a32400 --- /dev/null +++ b/ZuneUI/AlbumMetadataPropertySource.cs @@ -0,0 +1,90 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AlbumMetadataPropertySource +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Shell; +using MicrosoftZuneLibrary; +using System; +using UIXControls; + +namespace ZuneUI +{ + public class AlbumMetadataPropertySource : PropertySource + { + private static PropertySource _instance; + + protected AlbumMetadataPropertySource() + { + } + + public static PropertySource Instance + { + get + { + if (AlbumMetadataPropertySource._instance == null) + AlbumMetadataPropertySource._instance = (PropertySource)new AlbumMetadataPropertySource(); + return AlbumMetadataPropertySource._instance; + } + } + + public override object Get(object media, PropertyDescriptor property) + { + AlbumMetadata albumMetadata = media as AlbumMetadata; + string descriptorName = property.DescriptorName; + if (descriptorName == MetadataEditMedia.s_Title.DescriptorName) + return (object)albumMetadata.AlbumTitle; + if (descriptorName == MetadataEditMedia.s_AlbumTitleYomi.DescriptorName) + return (object)albumMetadata.AlbumTitleYomi; + if (descriptorName == MetadataEditMedia.s_Artist.DescriptorName) + return (object)albumMetadata.AlbumArtist; + if (descriptorName == MetadataEditMedia.s_AlbumArtistYomi.DescriptorName) + return (object)albumMetadata.AlbumArtistYomi; + if (descriptorName == MetadataEditMedia.s_TrackCount.DescriptorName) + return (object)albumMetadata.TrackCount; + if (descriptorName == MetadataEditMedia.s_CoverUrl.DescriptorName) + return (object)albumMetadata.CoverUrl; + return descriptorName == MetadataEditMedia.s_ReleaseYear.DescriptorName ? (object)albumMetadata.ReleaseYear : (object)null; + } + + public override void Set(object media, PropertyDescriptor property, object value) + { + AlbumMetadata albumMetadata = media as AlbumMetadata; + string descriptorName = property.DescriptorName; + if (descriptorName == MetadataEditMedia.s_Title.DescriptorName) + albumMetadata.AlbumTitle = (string)value; + else if (descriptorName == MetadataEditMedia.s_AlbumTitleYomi.DescriptorName) + albumMetadata.AlbumTitleYomi = (string)value; + else if (descriptorName == MetadataEditMedia.s_Artist.DescriptorName) + albumMetadata.AlbumArtist = (string)value; + else if (descriptorName == MetadataEditMedia.s_AlbumArtistYomi.DescriptorName) + albumMetadata.AlbumArtistYomi = (string)value; + else if (descriptorName == MetadataEditMedia.s_CoverUrl.DescriptorName) + { + albumMetadata.CoverUrl = (string)value; + } + else + { + if (!(descriptorName == MetadataEditMedia.s_ReleaseYear.DescriptorName)) + return; + albumMetadata.ReleaseYear = (int)value; + } + } + + public override void Commit(object media) + { + AlbumMetadata albumMetadata = media as AlbumMetadata; + try + { + ZuneApplication.ZuneLibrary.UpdateAlbumMetadata(albumMetadata.MediaId, albumMetadata); + } + catch (Exception ex) + { + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_EMI_UPDATEFAILED_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_EMI_UPDATEFAILED), (EventHandler)null); + } + } + + public override bool NeedsCommit => true; + } +} diff --git a/ZuneUI/AlbumsPanel.cs b/ZuneUI/AlbumsPanel.cs new file mode 100644 index 0000000..87419c1 --- /dev/null +++ b/ZuneUI/AlbumsPanel.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AlbumsPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class AlbumsPanel : MusicLibraryListPanelBase + { + internal AlbumsPanel(MusicLibraryPage libraryPage) + : base(libraryPage) + { + } + + public override MediaType MediaType => MediaType.Album; + + public override IList SelectedLibraryIds + { + get => this.LibraryPage.SelectedAlbumIds; + set => this.LibraryPage.SelectedAlbumIds = value; + } + } +} diff --git a/ZuneUI/AppReviewHelper.cs b/ZuneUI/AppReviewHelper.cs new file mode 100644 index 0000000..02ef05d --- /dev/null +++ b/ZuneUI/AppReviewHelper.cs @@ -0,0 +1,123 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AppReviewHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public class AppReviewHelper : NotifyPropertyChangedImpl + { + private static float s_maxRating = 10f; + private static float s_minRating = 0.0f; + private HRESULT _lastError; + private string _lastAuthor; + private AccountManagement _accountManagement; + + public AppReviewHelper() => this.Reset(); + + public event EventHandler ReviewPosted; + + public event EventHandler ReviewPostFailed; + + public static float MaxRating => AppReviewHelper.s_maxRating; + + public static float MinRating => AppReviewHelper.s_minRating; + + public HRESULT LastError + { + get => this._lastError; + private set + { + if (!(this._lastError != value)) + return; + this._lastError = value; + this.FirePropertyChanged(nameof(LastError)); + } + } + + public string LastAuthor + { + get => this._lastAuthor; + private set + { + if (!(this._lastAuthor != value)) + return; + this._lastAuthor = value; + this.FirePropertyChanged(nameof(LastAuthor)); + } + } + + public void AddReview(Guid mediaId, float rating, string title, string text) + { + if (mediaId == Guid.Empty || (double)rating < (double)AppReviewHelper.MinRating || (double)rating > (double)AppReviewHelper.MaxRating) + this.OnReviewPostFailed(HRESULT._ZUNE_E_ADD_REVIEW_FAILED); + else + Microsoft.Zune.Service.Service.Instance.PostAppReview(mediaId, title, text, (int)rating, new AsyncCompleteHandler(this.OnPostAddReviewComplete)); + } + + private void OnPostAddReviewComplete(HRESULT hr) => Application.DeferredInvoke(new DeferredInvokeHandler(this.HandleAddReviewResponse), (object)hr, DeferredInvokePriority.Normal); + + private void Reset() + { + this.LastAuthor = string.Empty; + this.LastError = HRESULT._S_OK; + } + + private void HandleAddReviewResponse(object args) + { + HRESULT? nullable = (HRESULT?)args; + if (!nullable.HasValue) + this.OnReviewPostFailed(HRESULT._ZUNE_E_ADD_REVIEW_FAILED); + else if (nullable.Value.IsSuccess) + this.GetAuthorName(); + else + this.OnReviewPostFailed(nullable.Value); + } + + private void GetAuthorName() + { + if (this._accountManagement == null) + this._accountManagement = new AccountManagement(); + if (!this._accountManagement.GetAccount((PassportIdentity)null, new GetAccountCompleteCallback(this.OnGetAccountSuccess), new AccountManagementErrorCallback(this.OnGetAccountError)).IsError) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.HandleGetAccountComplete), (object)string.Empty, DeferredInvokePriority.Normal); + } + + private void OnGetAccountSuccess(AccountUser accountUser) + { + string str = string.Empty; + if (accountUser != null) + str = string.Format(Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_NAME_FORMAT), (object)accountUser.FirstName, (object)accountUser.LastName); + Application.DeferredInvoke(new DeferredInvokeHandler(this.HandleGetAccountComplete), (object)str, DeferredInvokePriority.Normal); + } + + private void OnGetAccountError(HRESULT hr, ServiceError serviceError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.HandleGetAccountComplete), (object)string.Empty, DeferredInvokePriority.Normal); + + private void HandleGetAccountComplete(object args) + { + this.LastAuthor = args as string; + this.OnReviewPosted(); + } + + private void OnReviewPosted() + { + if (this.ReviewPosted != null) + this.ReviewPosted((object)this, (EventArgs)null); + this.FirePropertyChanged("ReviewPosted"); + } + + private void OnReviewPostFailed(HRESULT hr) + { + this.LastError = hr; + if (this.ReviewPostFailed != null) + this.ReviewPostFailed((object)this, (EventArgs)null); + this.FirePropertyChanged("ReviewPostFailed"); + } + } +} diff --git a/ZuneUI/ApplicationDetails.cs b/ZuneUI/ApplicationDetails.cs new file mode 100644 index 0000000..1e0e0f0 --- /dev/null +++ b/ZuneUI/ApplicationDetails.cs @@ -0,0 +1,58 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ApplicationDetails +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class ApplicationDetails + { + private static int[] ColumnIndices = new int[8] + { + 344, + 181, + 317, + 175, + 176, + 68, + 24, + 376 + }; + private static string[] DataProperties = new string[8] + { + "Title", + "FolderName", + "FilePath", + "FileName", + "FileSize", + "Copyright", + "Author", + "Version" + }; + private static object[] DefaultFieldValues = new object[8] + { + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) 0L, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty + }; + + public static void Populate(object dataContainer, int libraryId) + { + DataProviderObject dataProviderObject = (DataProviderObject)dataContainer; + object[] fieldValues = (object[])ApplicationDetails.DefaultFieldValues.Clone(); + bool[] isEmptyValues = new bool[fieldValues.Length]; + ZuneLibrary.GetFieldValues(libraryId, EListType.eAppList, ApplicationDetails.ColumnIndices.Length, ApplicationDetails.ColumnIndices, fieldValues, isEmptyValues, PlaylistManager.Instance.QueryContext); + for (int index = 0; index < ApplicationDetails.ColumnIndices.Length; ++index) + dataProviderObject.SetProperty(ApplicationDetails.DataProperties[index], fieldValues[index]); + } + } +} diff --git a/ZuneUI/ApplicationLibraryPage.cs b/ZuneUI/ApplicationLibraryPage.cs new file mode 100644 index 0000000..cb9dd9a --- /dev/null +++ b/ZuneUI/ApplicationLibraryPage.cs @@ -0,0 +1,149 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ApplicationLibraryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + public class ApplicationLibraryPage : LibraryPage + { + private ApplicationsPanel _applicationsPanel; + private object _selectedApplication; + private IList _selectedApplicationIDs; + + public ApplicationLibraryPage() + : this(false) + { + } + + protected override void OnDispose(bool disposing) => base.OnDispose(disposing); + + public ApplicationLibraryPage(bool showDevice) + : base(showDevice, MediaType.Application) + { + this.UI = ApplicationLibraryPage.LibraryTemplate; + if (showDevice) + { + this.UIPath = "Device\\Applications"; + this.PivotPreference = Shell.MainFrame.Device.Applications; + Deviceland.InitDevicePage((ZunePage)this); + } + else + { + this.UIPath = "Collection\\Applications"; + this.PivotPreference = Shell.MainFrame.Collection.Applications; + } + this.IsRootPage = true; + this.ShowPlaylistIcon = false; + this.ShowCDIcon = false; + this.TransportControlStyle = TransportControlStyle.None; + this._applicationsPanel = new ApplicationsPanel(this); + } + + public ApplicationsPanel ApplicationsPanel => this._applicationsPanel; + + public object SelectedApplication + { + get => this._selectedApplication; + set + { + if (this._selectedApplication == value) + return; + this._selectedApplication = value; + this.FirePropertyChanged(nameof(SelectedApplication)); + } + } + + public IList SelectedApplicationIDs + { + get => this._selectedApplicationIDs; + set + { + if (this._selectedApplicationIDs == value) + return; + this._selectedApplicationIDs = value; + this.FirePropertyChanged(nameof(SelectedApplicationIDs)); + } + } + + protected override void OnNavigatedToWorker() + { + if (this.NavigationArguments != null) + { + if (this.NavigationArguments.Contains((object)"ApplicationLibraryId")) + this._selectedApplicationIDs = (IList)new int[1] + { + (int) this.NavigationArguments[(object) "ApplicationLibraryId"] + }; + this.NavigationArguments = (IDictionary)null; + } + base.OnNavigatedToWorker(); + } + + protected override void OnNavigatedAwayWorker(IPage destination) + { + base.OnNavigatedAwayWorker(destination); + this.SelectedApplication = (object)null; + } + + public static void FindInCollection(int applicationId) => ZuneShell.DefaultInstance.Execute("Collection\\Applications", (IDictionary)new Hashtable() + { + { + (object) "ApplicationLibraryId", + (object) applicationId + } + }); + + public static bool DoesApplicationNeedUpdate(int applicationId, string serviceVersionString) + { + if (string.IsNullOrEmpty(serviceVersionString)) + return false; + Version version = (Version)null; + return ApplicationLibraryPage.TryParseVersion(serviceVersionString, out version) && ApplicationLibraryPage.DoesApplicationNeedUpdate(applicationId, version); + } + + public static bool DoesApplicationNeedUpdate(int applicationId, Version serviceVersion) + { + if ((Version)null == serviceVersion) + return false; + bool flag = false; + string fieldValue = PlaylistManager.GetFieldValue(applicationId, EListType.eAppList, 376, (string)null); + if (!string.IsNullOrEmpty(fieldValue)) + { + Version version = (Version)null; + if (ApplicationLibraryPage.TryParseVersion(fieldValue, out version) && version < serviceVersion) + flag = true; + } + return flag; + } + + private static bool TryParseVersion(string versionString, out Version version) + { + bool flag = false; + version = (Version)null; + try + { + version = new Version(versionString); + flag = true; + } + catch (ArgumentException ex) + { + } + catch (FormatException ex) + { + } + catch (OverflowException ex) + { + } + return flag; + } + + public override IPageState SaveAndRelease() => (IPageState)new ApplicationPageState(this); + + private static string LibraryTemplate => "res://ZuneShellResources!ApplicationLibrary.uix#ApplicationLibrary"; + } +} diff --git a/ZuneUI/ApplicationMarketplaceHelper.cs b/ZuneUI/ApplicationMarketplaceHelper.cs new file mode 100644 index 0000000..5a595a6 --- /dev/null +++ b/ZuneUI/ApplicationMarketplaceHelper.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ApplicationMarketplaceHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public static class ApplicationMarketplaceHelper + { + public static UIDevice FindAppDevice() + { + UIDevice uiDevice1 = UIDeviceList.NullDevice; + if (SyncControls.Instance.CurrentDevice.SupportsStoreApplications) + { + uiDevice1 = SyncControls.Instance.CurrentDevice; + } + else + { + DateTime minValue = DateTime.MinValue; + foreach (UIDevice uiDevice2 in SingletonModelItem.Instance) + { + if (uiDevice2.SupportsStoreApplications && uiDevice2.LastConnectTime > minValue) + uiDevice1 = uiDevice2; + } + } + return uiDevice1; + } + + public static void ForceAppUpdateOnAll() + { + foreach (UIDevice uiDevice in SingletonModelItem.Instance) + { + if (uiDevice.SupportsPaidApplications && uiDevice.IsConnectedToClient) + uiDevice.ForceAppUpdate(); + } + } + + public static UIDevice FindConnectedPaidAppDevice() + { + UIDevice uiDevice1 = UIDeviceList.NullDevice; + if (SyncControls.Instance.CurrentDevice.SupportsPaidApplications && SyncControls.Instance.CurrentDevice.IsConnectedToClient) + { + uiDevice1 = SyncControls.Instance.CurrentDevice; + } + else + { + DateTime minValue = DateTime.MinValue; + foreach (UIDevice uiDevice2 in SingletonModelItem.Instance) + { + if (uiDevice2.SupportsPaidApplications && uiDevice2.IsConnectedToClient && uiDevice2.LastConnectTime > minValue) + uiDevice1 = uiDevice2; + } + } + return uiDevice1; + } + } +} diff --git a/ZuneUI/ApplicationNavigationCommandHandler.cs b/ZuneUI/ApplicationNavigationCommandHandler.cs new file mode 100644 index 0000000..a1d0dac --- /dev/null +++ b/ZuneUI/ApplicationNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ApplicationNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class ApplicationNavigationCommandHandler : DeviceAwareNavigationHandler + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new ApplicationLibraryPage(this.ShowDeviceContents); + } +} diff --git a/ZuneUI/ApplicationPageState.cs b/ZuneUI/ApplicationPageState.cs new file mode 100644 index 0000000..083ffcd --- /dev/null +++ b/ZuneUI/ApplicationPageState.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ApplicationPageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ApplicationPageState : DevicePivotManagingPageState + { + public ApplicationPageState(ApplicationLibraryPage page) + : base((IDeviceContentsPage)page) + { + } + + public override IPage RestoreAndRelease() + { + IPage page = (IPage)null; + if (!this.Page.ShowDeviceContents || SyncControls.Instance.CurrentDevice.SupportsSyncApplications) + page = base.RestoreAndRelease(); + return page; + } + } +} diff --git a/ZuneUI/ApplicationsPanel.cs b/ZuneUI/ApplicationsPanel.cs new file mode 100644 index 0000000..c63a9ae --- /dev/null +++ b/ZuneUI/ApplicationsPanel.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ApplicationsPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class ApplicationsPanel : ListPanel + { + internal ApplicationsPanel(ApplicationLibraryPage library) + : base((IModelItemOwner)library) + { + } + + protected ApplicationLibraryPage LibraryPage => base.LibraryPage as ApplicationLibraryPage; + + public override IList SelectedLibraryIds + { + get => this.LibraryPage.SelectedApplicationIDs; + set => this.LibraryPage.SelectedApplicationIDs = value; + } + } +} diff --git a/ZuneUI/ArtistChooserWizard.cs b/ZuneUI/ArtistChooserWizard.cs new file mode 100644 index 0000000..a2e7d2d --- /dev/null +++ b/ZuneUI/ArtistChooserWizard.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ArtistChooserWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ArtistChooserWizard : Wizard + { + private bool _errorOccurred; + + public ArtistChooserWizard() => this.AddPage((WizardPage)new ArtistChooserWizardPage(this)); + + public bool ErrorOccurred + { + get => this._errorOccurred; + set + { + if (this._errorOccurred == value) + return; + this._errorOccurred = value; + this.FirePropertyChanged(nameof(ErrorOccurred)); + } + } + } +} diff --git a/ZuneUI/ArtistChooserWizardPage.cs b/ZuneUI/ArtistChooserWizardPage.cs new file mode 100644 index 0000000..dd57c17 --- /dev/null +++ b/ZuneUI/ArtistChooserWizardPage.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ArtistChooserWizardPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ArtistChooserWizardPage : WizardPage + { + internal ArtistChooserWizardPage(ArtistChooserWizard wizard) + : base((ZuneUI.Wizard)wizard) + => this.Description = Shell.LoadString(StringId.IDS_ArtistChooserTitle); + + protected ArtistChooserWizard Wizard => (ArtistChooserWizard)this._owner; + + public override string UI => "res://ZuneShellResources!ArtistChooser.uix#ArtistChooserWizardPage"; + } +} diff --git a/ZuneUI/ArtistHelper.cs b/ZuneUI/ArtistHelper.cs new file mode 100644 index 0000000..b8b9c1d --- /dev/null +++ b/ZuneUI/ArtistHelper.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ArtistHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; + +namespace ZuneUI +{ + public static class ArtistHelper + { + public static int InCollection(Guid serviceMediaId) + { + int dbMediaId = -1; + bool fHidden = false; + return !ZuneApplication.Service.InCompleteCollection(serviceMediaId, EContentType.Artist, out dbMediaId, out fHidden) ? -1 : dbMediaId; + } + } +} diff --git a/ZuneUI/ArtistsPanel.cs b/ZuneUI/ArtistsPanel.cs new file mode 100644 index 0000000..b287ee0 --- /dev/null +++ b/ZuneUI/ArtistsPanel.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ArtistsPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class ArtistsPanel : MusicLibraryListPanelBase + { + internal ArtistsPanel(MusicLibraryPage libraryPage) + : base(libraryPage) + { + } + + public override MediaType MediaType => MediaType.Artist; + + public override IList SelectedLibraryIds + { + get => this.LibraryPage.SelectedArtistIds; + set => this.LibraryPage.SelectedArtistIds = value; + } + } +} diff --git a/ZuneUI/AsyncOperation.cs b/ZuneUI/AsyncOperation.cs new file mode 100644 index 0000000..80e735c --- /dev/null +++ b/ZuneUI/AsyncOperation.cs @@ -0,0 +1,165 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AsyncOperation +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.ErrorMapperApi; + +namespace ZuneUI +{ + internal abstract class AsyncOperation + { + protected const int IdleState = -1; + protected const int FinishedState = -2; + protected UIDevice _device; + protected string _error; + protected string _detailedError; + protected HRESULT _hr; + private AsyncOperation.AOComplete _completeFunc; + private WirelessStates[] _states; + private bool _fListening; + private bool _fTryToCancel; + private bool _fCanceled; + protected static int _iCurrentState = -1; + + public string Error => this.Finished ? this._error : (string)null; + + public string DetailedError => this.Finished ? this._detailedError : (string)null; + + public HRESULT Hr => this.Finished ? this._hr : HRESULT._E_PENDING; + + public bool Canceled => this.Finished && this._fCanceled; + + protected abstract WirelessStateResults DoStep(WirelessStates state); + + public virtual void Cancel() + { + if (this.Idle || this.Finished) + return; + this._fTryToCancel = true; + } + + protected virtual void EndOperation(WirelessStateResults result) + { + } + + protected virtual void AddListeners() + { + } + + protected virtual void RemoveListeners() + { + } + + protected bool Idle => AsyncOperation._iCurrentState == -1; + + protected bool Finished => AsyncOperation._iCurrentState == -2; + + protected WirelessStateResults StartOperation( + UIDevice device, + AsyncOperation.AOComplete completeFunc, + WirelessStates[] states) + { + WirelessStateResults result = WirelessStateResults.Error; + if (!this.Idle) + return WirelessStateResults.NotAvailable; + this.ResetState(); + this._device = device; + this._states = states; + this._completeFunc = completeFunc; + AsyncOperation._iCurrentState = 0; + if (device.IsConnectedToClient) + { + this.AddListenersInternal(); + result = this.DoNextStep(); + } + if (result != WirelessStateResults.Success) + this.EndOperationInternal(result); + return WirelessStateResults.Success; + } + + protected void StepComplete(WirelessStateResults result) + { + ++AsyncOperation._iCurrentState; + if (result == WirelessStateResults.Success) + result = this.DoNextStep(); + if (result == WirelessStateResults.Success) + return; + this.EndOperationInternal(result); + } + + protected void ClearResult() + { + this._hr = HRESULT._S_OK; + this._detailedError = (string)null; + } + + protected void SetResult(HRESULT hr) + { + this._hr = hr; + if (!hr.IsError) + return; + ErrorMapperResult descriptionAndUrl = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int); + if ((long)descriptionAndUrl.Hr == (long)(uint)HRESULT._E_FAIL.Int || (long)descriptionAndUrl.Hr == (long)(uint)HRESULT._NS_E_WMP_UNKNOWN_ERROR.Int) + return; + this._detailedError = descriptionAndUrl.Description; + } + + private void EndOperationInternal(WirelessStateResults result) + { + this.RemoveListenersInternal(); + if (result == WirelessStateResults.Canceled) + this._fCanceled = true; + this.EndOperation(result); + AsyncOperation._iCurrentState = -2; + if (this._completeFunc != null) + this._completeFunc(result == WirelessStateResults.Finished); + AsyncOperation._iCurrentState = -1; + } + + private WirelessStateResults DoNextStep() + { + if (AsyncOperation._iCurrentState == this._states.Length) + return WirelessStateResults.Finished; + if (AsyncOperation._iCurrentState > this._states.Length) + return WirelessStateResults.Error; + if (this._fTryToCancel) + return WirelessStateResults.Canceled; + WirelessStateResults result = this.DoStep(this._states[AsyncOperation._iCurrentState]); + if (result != WirelessStateResults.Success) + this.EndOperationInternal(result); + return result; + } + + private void ResetState() + { + if (!this.Idle && !this.Finished) + return; + this._error = (string)null; + this._detailedError = (string)null; + this._fTryToCancel = false; + this._fCanceled = false; + this._fListening = false; + this._hr = HRESULT._S_OK; + } + + private void AddListenersInternal() + { + if (this._fListening) + return; + this.AddListeners(); + this._fListening = true; + } + + private void RemoveListenersInternal() + { + if (!this._fListening) + return; + this.RemoveListeners(); + this._fListening = false; + } + + public delegate void AOComplete(bool success); + } +} diff --git a/ZuneUI/Attachment.cs b/ZuneUI/Attachment.cs new file mode 100644 index 0000000..c31923d --- /dev/null +++ b/ZuneUI/Attachment.cs @@ -0,0 +1,444 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Attachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Playlist; +using System; +using System.Collections; +using ZuneXml; + +namespace ZuneUI +{ + public abstract class Attachment : NotifyPropertyChangedImpl + { + private string _attachmentUI; + private string _description; + private string _title; + private string _subtitle; + private string _imageUri; + private Guid _imageId; + private Guid _id; + private bool _wishlist; + private bool _allowEmailRecipients; + + protected Attachment(Guid id, string title, string subtitle, string imageUri) + { + this._attachmentUI = "res://ZuneShellResources!SocialComposer.uix#AttachmentUI"; + this._id = id; + this._title = title; + this._subtitle = subtitle; + this._description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_DEFAULT_ATTACHMENT); + this._imageUri = imageUri; + this._allowEmailRecipients = true; + } + + public virtual void LogSend() + { + } + + public static bool CanCreateAttachment(object obj) + { + MediaType mediaType = MediaType.Undefined; + Guid guid = Guid.Empty; + int num = -1; + bool flag = false; + switch (obj) + { + case DataProviderObject dataProviderObject: + object property1 = dataProviderObject.GetProperty("ZuneMediaId"); + if (property1 != null) + guid = (Guid)property1; + object property2 = dataProviderObject.GetProperty("LibraryId"); + if (property2 != null) + num = (int)property2; + if (dataProviderObject.GetProperty("Type") is string property3) + { + mediaType = ZuneShell.MapStringToMediaType(property3); + break; + } + break; + case PlaybackTrack _: + PlaybackTrack playbackTrack = (PlaybackTrack)obj; + guid = playbackTrack.ZuneMediaId; + mediaType = playbackTrack.MediaType; + break; + } + switch (mediaType) + { + case MediaType.Track: + case MediaType.Album: + flag = guid != Guid.Empty; + break; + case MediaType.Video: + if (dataProviderObject != null && guid != Guid.Empty) + { + object property3 = dataProviderObject.GetProperty("CategoryId"); + if (property3 != null) + { + VideoCategory videoCategory = (VideoCategory)property3; + flag = videoCategory == VideoCategory.TV || videoCategory == VideoCategory.Movies; + break; + } + break; + } + break; + case MediaType.Playlist: + if (dataProviderObject != null && (guid != Guid.Empty || num != -1)) + { + object property3 = dataProviderObject.GetProperty("PlaylistType"); + if (property3 != null) + { + PlaylistType playlistType = (PlaylistType)property3; + flag = playlistType != PlaylistType.Channel && playlistType != PlaylistType.PersonalChannel; + break; + } + break; + } + break; + case MediaType.PodcastEpisode: + if (dataProviderObject != null) + { + object property3 = dataProviderObject.GetProperty("SeriesId"); + if (property3 != null) + { + flag = PodcastLibraryPage.GetZuneMediaId((int)property3) != Guid.Empty || !string.IsNullOrEmpty(dataProviderObject.GetProperty("SeriesFeedUrl") as string); + break; + } + break; + } + break; + case MediaType.Podcast: + flag = guid != Guid.Empty; + if (!flag && dataProviderObject != null) + { + flag = !string.IsNullOrEmpty(dataProviderObject.GetProperty("FeedUrl") as string); + break; + } + break; + } + return flag; + } + + public static Attachment CreateAttachment(object obj) + { + DataProviderObject dataProviderObject = obj as DataProviderObject; + MediaType mediaType = MediaType.Undefined; + Guid zuneMediaId = Guid.Empty; + VideoCategory videoCategory = VideoCategory.Other; + string title = (string)null; + string url = (string)null; + int num = -1; + if (dataProviderObject != null) + { + object property1 = dataProviderObject.GetProperty("ZuneMediaId"); + if (property1 != null) + zuneMediaId = (Guid)property1; + if (dataProviderObject.GetProperty("Type") is string property) + mediaType = ZuneShell.MapStringToMediaType(property); + object property3 = dataProviderObject.GetProperty("LibraryId"); + if (property3 != null) + num = (int)property3; + object property4 = dataProviderObject.GetProperty("CategoryId"); + if (property4 != null) + videoCategory = (VideoCategory)property4; + title = dataProviderObject.GetProperty("Title") as string; + switch (mediaType) + { + case MediaType.PodcastEpisode: + object property5 = dataProviderObject.GetProperty("SeriesId"); + if (property5 != null) + num = (int)property5; + zuneMediaId = PodcastLibraryPage.GetZuneMediaId(num); + mediaType = MediaType.Podcast; + title = dataProviderObject.GetProperty("SeriesTitle") as string; + url = dataProviderObject.GetProperty("SeriesFeedUrl") as string; + break; + case MediaType.Podcast: + url = dataProviderObject.GetProperty("FeedUrl") as string; + break; + } + } + return Attachment.CreateAttachment(zuneMediaId, mediaType, num, title, url, videoCategory, MovieType.Other); + } + + public static Attachment CreateAttachment(Guid zuneMediaId, MediaType mediaType) => Attachment.CreateAttachment(zuneMediaId, mediaType, -1, (string)null); + + public static Attachment CreateAttachment( + Guid zuneMediaId, + MediaType mediaType, + int libraryId, + string title) + { + return Attachment.CreateAttachment(zuneMediaId, mediaType, libraryId, title, (string)null, VideoCategory.Other, MovieType.Other); + } + + public static Attachment CreateAttachment( + Guid zuneMediaId, + MediaType mediaType, + string title, + VideoCategory videoCategory, + MovieType movieType) + { + return Attachment.CreateAttachment(zuneMediaId, mediaType, -1, title, (string)null, videoCategory, movieType); + } + + private static Attachment CreateAttachment( + Guid zuneMediaId, + MediaType mediaType, + int libraryId, + string title, + string url, + VideoCategory videoCategory, + MovieType movieType) + { + Attachment attachment = (Attachment)null; + if (libraryId != -1 && mediaType == MediaType.Playlist) + { + attachment = (Attachment)new CollectionPlaylistAttachment((string)null, title, (string)null, libraryId, (IList)null); + } + else + { + switch (mediaType) + { + case MediaType.Track: + if (zuneMediaId != Guid.Empty) + { + attachment = (Attachment)new TrackAttachment(zuneMediaId, title, (string)null, (string)null); + break; + } + break; + case MediaType.Video: + if (zuneMediaId != Guid.Empty) + { + switch (videoCategory) + { + case VideoCategory.TV: + attachment = (Attachment)new EpisodeAttachment(zuneMediaId, title, (string)null, (string)null); + break; + case VideoCategory.Movies: + attachment = movieType != MovieType.Trailer ? (Attachment)new MovieAttachment(zuneMediaId, title, (string)null) : (Attachment)new TrailerAttachment(zuneMediaId, title, (string)null); + break; + } + } + else + break; + break; + case MediaType.Playlist: + if (zuneMediaId != Guid.Empty) + { + attachment = (Attachment)new PlaylistAttachment(zuneMediaId, title, (string)null); + break; + } + break; + case MediaType.Album: + if (zuneMediaId != Guid.Empty) + { + attachment = (Attachment)new AlbumAttachment(zuneMediaId, title, (string)null, (string)null, Guid.Empty); + break; + } + break; + case MediaType.Podcast: + if (zuneMediaId != Guid.Empty || !string.IsNullOrEmpty(url)) + { + attachment = (Attachment)new PodcastAttachment(zuneMediaId, title, (string)null, url, (string)null); + break; + } + break; + } + } + return attachment; + } + + public static Attachment CreateAttachmentFromMessage( + object message, + object messageDetails) + { + return Attachment.CreateAttachmentFromMessage(message as MessageRoot, messageDetails as MessageDetails); + } + + private static Attachment CreateAttachmentFromMessage( + MessageRoot message, + MessageDetails messageDetails) + { + Attachment attachment = (Attachment)null; + if (message != null) + { + string type = message.Type; + if (message.MediaId != Guid.Empty) + { + switch (type) + { + case "album": + attachment = (Attachment)new AlbumAttachment(message.MediaId, (string)null, (string)null, (string)null, Guid.Empty); + break; + case "playlist": + attachment = (Attachment)new PlaylistAttachment(message.MediaId, (string)null, (string)null); + break; + case "podcast": + attachment = (Attachment)new PodcastAttachment(message.MediaId, (string)null, (string)null, (string)null, (string)null); + break; + case "song": + attachment = (Attachment)new TrackAttachment(message.MediaId, (string)null, (string)null, (string)null); + break; + case "video": + attachment = (Attachment)new EpisodeAttachment(message.MediaId, (string)null, (string)null, (string)null); + break; + case "movie": + attachment = (Attachment)new MovieAttachment(message.MediaId, (string)null, (string)null); + break; + case "movietrailer": + attachment = (Attachment)new TrailerAttachment(message.MediaId, (string)null, (string)null); + break; + } + } + else if (messageDetails != null) + { + if (messageDetails.PodcastMediaId != Guid.Empty) + { + if (type == "podcast") + attachment = (Attachment)new PodcastAttachment(messageDetails.PodcastMediaId, (string)null, (string)null, (string)null, (string)null); + } + else if (!string.IsNullOrEmpty(messageDetails.ZuneTag) && type == "card") + attachment = (Attachment)new ProfileAttachment(messageDetails.ZuneTag, (string)null, (string)null); + } + } + return attachment; + } + + public static Attachment CreateAttachment( + Guid id, + MediaType mediaType, + bool wishlist) + { + Attachment attachment = Attachment.CreateAttachment(id, mediaType); + if (attachment != null) + attachment.Wishlist = wishlist; + return attachment; + } + + public string AttachmentUI + { + get => this._attachmentUI; + set + { + if (!(this._attachmentUI != value)) + return; + this._attachmentUI = value; + this.FirePropertyChanged(nameof(AttachmentUI)); + } + } + + public string Description + { + get => this._description; + set + { + if (this._description == null) + return; + this._description = value; + this.FirePropertyChanged(nameof(Description)); + } + } + + public string ImageUri + { + get => this._imageUri; + set + { + if (!(this._imageUri != value)) + return; + this._imageUri = value; + this.FirePropertyChanged(nameof(ImageUri)); + } + } + + public Guid ImageId + { + get => this._imageId; + set + { + if (!(this._imageId != value)) + return; + this._imageId = value; + this.FirePropertyChanged(nameof(ImageId)); + } + } + + public string Title + { + get => this._title; + set + { + if (!(this._title != value)) + return; + this._title = value; + this.FirePropertyChanged(nameof(Title)); + } + } + + public string Subtitle + { + get => this._subtitle; + set + { + if (!(this._subtitle != value)) + return; + this._subtitle = value; + this.FirePropertyChanged(nameof(Subtitle)); + } + } + + public Guid Id => this._id; + + public bool Wishlist + { + get => this._wishlist; + set + { + if (this._wishlist == value) + return; + this._wishlist = value; + this.FirePropertyChanged(nameof(Wishlist)); + } + } + + public bool AllowEmailRecipients + { + get => this._allowEmailRecipients; + set + { + if (this._allowEmailRecipients == value) + return; + this._allowEmailRecipients = value; + this.FirePropertyChanged(nameof(AllowEmailRecipients)); + } + } + + public abstract MediaType MediaType { get; } + + public abstract string RequestType { get; } + + public virtual string[] Properties => new string[6] + { + "type", + this.RequestType, + "mediaid", + this.Id.ToString(), + "wishlist", + this.Wishlist.ToString() + }; + + public virtual bool IsReady => true; + + public bool ContainsImage() => !string.IsNullOrEmpty(this._imageUri) || this._imageId != Guid.Empty; + + public virtual bool IsValid(out string errorMessage) + { + errorMessage = (string)null; + return true; + } + } +} diff --git a/ZuneUI/AutoCompleteHelper.cs b/ZuneUI/AutoCompleteHelper.cs new file mode 100644 index 0000000..9cfe2eb --- /dev/null +++ b/ZuneUI/AutoCompleteHelper.cs @@ -0,0 +1,187 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AutoCompleteHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class AutoCompleteHelper : ModelItem + { + private IList _options; + private IList _filteredOptions; + private string _entry; + private int _cursorPosition; + private bool _useEntrySeparator = true; + private bool _applyfilter = true; + protected static char[] s_entrySeparators = new char[2] + { + ';', + ',' + }; + private static char[] s_entryTrimmers = new char[3] + { + ';', + ',', + ' ' + }; + + public AutoCompleteHelper() + { + this._entry = string.Empty; + this._cursorPosition = 0; + } + + public string InsertAtCursor(string insert) + { + insert = insert ?? string.Empty; + string filterString = this.GetFilterString(); + if (this._cursorPosition > 0 && filterString.Length > 0) + { + insert = this._entry.Substring(0, this._cursorPosition - filterString.Length) + insert; + if (this._cursorPosition < this._entry.Length) + insert += this._entry.Substring(this._cursorPosition - filterString.Length); + else if (this._useEntrySeparator) + insert = string.Format("{0}{1} ", (object)insert, (object)AutoCompleteHelper.s_entrySeparators[0]); + this.Entry = insert; + } + else + this.InsertAtEnd(insert); + return this.Entry; + } + + public string InsertAtEnd(string insert) + { + if (this.Entry == null || !this._useEntrySeparator) + this.Entry = insert; + else if (!string.IsNullOrEmpty(insert)) + { + string str = this.Entry.TrimEnd(AutoCompleteHelper.s_entryTrimmers); + if (str.Length > 0) + insert = string.Format("{0} {1}{2} ", (object)AutoCompleteHelper.s_entrySeparators[0], (object)insert, (object)AutoCompleteHelper.s_entrySeparators[0]); + else if (this._useEntrySeparator) + insert = string.Format("{0}{1} ", (object)insert, (object)AutoCompleteHelper.s_entrySeparators[0]); + this.Entry = str + insert; + } + return this.Entry; + } + + public IList Options + { + get => this._options; + set + { + if (this._options == value) + return; + this._options = value; + this.FirePropertyChanged(nameof(Options)); + } + } + + public string Entry + { + get => this._entry; + set + { + if (!(this._entry != value)) + return; + this._cursorPosition = this._entry == null || value == null || !value.StartsWith(this._entry, StringComparison.CurrentCultureIgnoreCase) ? -1 : value.Length; + this._entry = value; + if (this.Applyfilter) + this.Filter(); + else + this.FilteredOptions = this._options; + this.FirePropertyChanged(nameof(Entry)); + } + } + + public IList FilteredOptions + { + get => this._filteredOptions; + set + { + if (this._filteredOptions == value) + return; + this._filteredOptions = value; + this.FirePropertyChanged(nameof(FilteredOptions)); + } + } + + public bool UseEntrySeparator + { + get => this._useEntrySeparator; + set + { + if (this._useEntrySeparator == value) + return; + this._useEntrySeparator = value; + this.FirePropertyChanged(nameof(UseEntrySeparator)); + } + } + + public bool Applyfilter + { + get => this._applyfilter; + set + { + if (this._applyfilter == value) + return; + this._applyfilter = value; + this.FirePropertyChanged(nameof(Applyfilter)); + } + } + + private void Filter() + { + List stringList = new List(); + string filterString = this.GetFilterString(); + if (this._options != null && !string.IsNullOrEmpty(filterString)) + { + int index; + if (this._options is ISearchableList) + index = ((ISearchableList)this._options).SearchForString(filterString); + else if (this._options is List) + { + index = ((List)this._options).BinarySearch(filterString, (IComparer)StringComparer.CurrentCultureIgnoreCase); + if (index < 0) + index = ~index; + } + else + index = -1; + if (index >= 0) + { + for (; index < this._options.Count; ++index) + { + string option = (string)this._options[index]; + if (ZuneLibrary.CompareWithoutArticles(filterString, option) == 0) + stringList.Add(option); + else + break; + } + } + } + this.FilteredOptions = (IList)stringList; + } + + private string GetFilterString() + { + string str = string.Empty; + if (this._cursorPosition > 0 && this._entry != null) + { + int num1 = this._entry.LastIndexOfAny(AutoCompleteHelper.s_entrySeparators, this._cursorPosition - 1) + 1; + while (num1 < this._entry.Length && char.IsWhiteSpace(this._entry, num1)) + ++num1; + int num2 = this._entry.IndexOfAny(AutoCompleteHelper.s_entrySeparators, num1); + int length = num2 <= 0 ? this._entry.Length - num1 : num2 - num1; + str = this._entry.Substring(num1, length); + } + return str.Normalize(); + } + } +} diff --git a/ZuneUI/AutoRestoreLandPage.cs b/ZuneUI/AutoRestoreLandPage.cs new file mode 100644 index 0000000..e89312b --- /dev/null +++ b/ZuneUI/AutoRestoreLandPage.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.AutoRestoreLandPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class AutoRestoreLandPage : SetupLandPage + { + public AutoRestoreLandPage() => this.UI = "res://ZuneShellResources!SetupLand.uix#AutoRestore"; + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (UIDeviceList.IsSuitableForConnection(SyncControls.Instance.CurrentDeviceOverride)) + SyncControls.Instance.CurrentDeviceOverride.Enumerate(); + DeviceManagement.HandleSetupQueue(); + }, DeferredInvokePriority.Low); + } + } +} diff --git a/ZuneUI/BackgroundOption.cs b/ZuneUI/BackgroundOption.cs new file mode 100644 index 0000000..35bff97 --- /dev/null +++ b/ZuneUI/BackgroundOption.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BackgroundOption +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class BackgroundOption : NamedStringOption + { + private WindowColor _color; + + public WindowColor Color + { + get => this._color; + set => this._color = value; + } + } +} diff --git a/ZuneUI/BandwidthCapacity.cs b/ZuneUI/BandwidthCapacity.cs new file mode 100644 index 0000000..b218154 --- /dev/null +++ b/ZuneUI/BandwidthCapacity.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BandwidthCapacity +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum BandwidthCapacity + { + NotTested, + HDCapable, + SDCapable, + None, + } +} diff --git a/ZuneUI/BandwidthTest.cs b/ZuneUI/BandwidthTest.cs new file mode 100644 index 0000000..c70762e --- /dev/null +++ b/ZuneUI/BandwidthTest.cs @@ -0,0 +1,258 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BandwidthTest +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using MicrosoftZunePlayback; +using System.Collections; +using System.Threading; + +namespace ZuneUI +{ + public class BandwidthTest : ModelItem + { + private const int c_minHDRequirement = 2800000; + private const int c_minSDRequirement = 700000; + private const int WIN32ERRCODE_TIMEOUT = -2147023436; + private BandwidthTestInterop m_bandwidthTestInterop; + private int m_bandwidthTestProgressPercent; + private BandwidthCapacity m_bandwidthTestResult; + private IList m_videoOffers; + private string m_uri; + private bool m_fBandwidthTestRunning; + private bool m_fBandwidthTestCanceled; + private bool m_fBandwidthTestCompleted; + private bool m_fBandwidthTestErrFound; + private BandwidthCapacity m_lastTestResult; + private bool m_fIsRetried; + private bool m_fIsContentSDOnly; + private bool m_fIsContentHDOnly; + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing || this.m_bandwidthTestInterop == null) + return; + this.m_bandwidthTestInterop = (BandwidthTestInterop)null; + } + + public int BandwidthTestProgressPercent + { + get => this.m_bandwidthTestProgressPercent; + private set + { + this.m_bandwidthTestProgressPercent = value; + this.FirePropertyChanged(nameof(BandwidthTestProgressPercent)); + } + } + + public bool IsBandwidthTestErrFound + { + get => this.m_fBandwidthTestErrFound; + private set + { + this.m_fBandwidthTestErrFound = value; + this.FirePropertyChanged(nameof(IsBandwidthTestErrFound)); + } + } + + public bool IsBandwidthTestRunning + { + get => this.m_fBandwidthTestRunning; + private set + { + this.m_fBandwidthTestRunning = value; + this.FirePropertyChanged(nameof(IsBandwidthTestRunning)); + } + } + + public bool IsBandwidthTestCanceled + { + get => this.m_fBandwidthTestCanceled; + private set + { + this.m_fBandwidthTestCanceled = value; + this.FirePropertyChanged(nameof(IsBandwidthTestCanceled)); + } + } + + public bool IsBandwidthTestCompleted + { + get => this.m_fBandwidthTestCompleted; + private set + { + this.m_fBandwidthTestCompleted = value; + this.FirePropertyChanged(nameof(IsBandwidthTestCompleted)); + } + } + + public BandwidthCapacity BandwidthTestResult + { + get => this.m_bandwidthTestResult; + private set + { + this.m_bandwidthTestResult = value; + this.FirePropertyChanged(nameof(BandwidthTestResult)); + } + } + + public bool IsContentSDOnly + { + get => this.m_fIsContentSDOnly; + set + { + this.m_fIsContentSDOnly = value; + this.FirePropertyChanged(nameof(IsContentSDOnly)); + } + } + + public bool IsContentHDOnly + { + get => this.m_fIsContentHDOnly; + set + { + this.m_fIsContentHDOnly = value; + this.FirePropertyChanged(nameof(IsContentHDOnly)); + } + } + + public void StartBandwidthTest(IList videoOffers) + { + if (this.IsBandwidthTestRunning) + return; + this.m_videoOffers = videoOffers; + this.IsBandwidthTestRunning = true; + this.IsBandwidthTestCanceled = false; + this.IsBandwidthTestCompleted = false; + this.IsBandwidthTestErrFound = false; + this.StartGettingContentUri(); + } + + public void CancelBandwidthTest() + { + if (this.m_bandwidthTestInterop == null || !this.IsBandwidthTestRunning) + return; + this.m_bandwidthTestInterop.Cancel(); + this.m_bandwidthTestInterop = (BandwidthTestInterop)null; + this.IsBandwidthTestCanceled = true; + this.IsBandwidthTestRunning = false; + if (!DownloadManager.Instance.IsQueuePaused) + return; + DownloadManager.Instance.ResumeQueue(); + } + + public void RetryBandwidthTest() + { + if (this.m_videoOffers == null) + return; + this.m_fIsRetried = true; + this.StartBandwidthTest(this.m_videoOffers); + } + + public void LogHDSDChoice(int chosenHDSDChoice) + { + if (this.BandwidthTestResult == BandwidthCapacity.None) + return; + SQMLog.LogToStream(SQMDataId.BandwidthTestResultAndDecision, (uint)this.BandwidthTestResult, (uint)chosenHDSDChoice); + } + + private void StartGettingContentUri() => ThreadPool.QueueUserWorkItem((WaitCallback)(args => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnGotContentUri), (object)this.GetContentUri())), (object)null); + + private string GetContentUri() + { + string uriOut = (string)null; + if (this.m_videoOffers[0] is VideoOffer videoOffer) + { + if (!ZuneApplication.Service.InCompleteCollection(videoOffer.Id, EContentType.Video) && !string.IsNullOrEmpty(this.m_uri)) + uriOut = this.m_uri; + else + ZuneApplication.Service.GetContentUri(videoOffer.Id, EContentType.Video, EContentUriFlags.BypassLicense | EContentUriFlags.IgnoreCollection, videoOffer.IsHD, videoOffer.IsRental, out uriOut); + } + return uriOut; + } + + private void OnGotContentUri(object obj) + { + string str = (string)obj; + if (string.IsNullOrEmpty(str)) + { + this.IsBandwidthTestErrFound = true; + } + else + { + this.m_uri = str; + if (!DownloadManager.Instance.IsQueuePaused) + DownloadManager.Instance.PauseQueue(); + this.StartBandwidthTestCore(this.m_uri, ClientConfiguration.GeneralSettings.BandwidthTestTimeoutSec); + } + } + + private void StartBandwidthTestCore(string uri, int testTimeout) + { + if (string.IsNullOrEmpty(uri)) + return; + this.IsBandwidthTestErrFound = false; + this.m_bandwidthTestInterop = new BandwidthTestInterop(); + this.m_bandwidthTestInterop.BandwidthTestUpdate += new BandwidthTestUpdateEventHandler(this.OnBandwidthTestUpdate); + this.m_bandwidthTestInterop.BandwidthTestError += new BandwidthTestErrorEventHandler(this.OnBandwidthTestError); + this.m_bandwidthTestInterop.Start(uri, testTimeout); + } + + private void OnBandwidthTestUpdate(object sender, BandwidthUpdateArgs args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnBandwidthTestUpdateOnApp), (object)args); + + private void OnBandwidthTestError(object sender, BandwidthTestErrorArgs args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnBandwidthTestErrorOnApp), (object)args); + + private void OnBandwidthTestUpdateOnApp(object obj) + { + if (obj == null) + return; + BandwidthUpdateArgs bandwidthUpdateArgs = (BandwidthUpdateArgs)obj; + if (bandwidthUpdateArgs == null) + return; + switch (bandwidthUpdateArgs.currentState) + { + case MBRHeuristicState.Test_Start: + this.BandwidthTestProgressPercent = 5; + break; + case MBRHeuristicState.Test_Inprogress: + if (bandwidthUpdateArgs.PercentComplete <= 5) + break; + this.BandwidthTestProgressPercent = bandwidthUpdateArgs.PercentComplete; + break; + case MBRHeuristicState.Test_Completed: + if (DownloadManager.Instance.IsQueuePaused) + DownloadManager.Instance.ResumeQueue(); + this.BandwidthTestResult = bandwidthUpdateArgs.TotalAverageBandwidth < 2800000 ? (bandwidthUpdateArgs.TotalAverageBandwidth < 700000 ? BandwidthCapacity.None : BandwidthCapacity.SDCapable) : BandwidthCapacity.HDCapable; + this.BandwidthTestProgressPercent = 100; + this.IsBandwidthTestCompleted = true; + this.IsBandwidthTestRunning = false; + this.m_bandwidthTestInterop = (BandwidthTestInterop)null; + if (this.BandwidthTestResult == BandwidthCapacity.None) + SQMLog.Log(SQMDataId.BandwidthTestDoesnotMeetMin, 1); + if (this.m_fIsRetried && this.BandwidthTestResult != this.m_lastTestResult) + SQMLog.Log(SQMDataId.BandwidthTestRetryDifferentResult, 1); + this.m_lastTestResult = this.BandwidthTestResult; + break; + } + } + + private void OnBandwidthTestErrorOnApp(object obj) + { + this.IsBandwidthTestErrFound = true; + this.IsBandwidthTestRunning = false; + if (DownloadManager.Instance.IsQueuePaused) + DownloadManager.Instance.ResumeQueue(); + this.m_bandwidthTestInterop = (BandwidthTestInterop)null; + if (((BandwidthTestErrorArgs)obj).ErrorCode != -2147023436) + return; + ShipAssert.Assert(false); + SQMLog.Log(SQMDataId.BandwidthTestTimeout, 1); + } + } +} diff --git a/ZuneUI/BaseContactInfoPropertyEditor.cs b/ZuneUI/BaseContactInfoPropertyEditor.cs new file mode 100644 index 0000000..425d2f2 --- /dev/null +++ b/ZuneUI/BaseContactInfoPropertyEditor.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BaseContactInfoPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class BaseContactInfoPropertyEditor : WizardPropertyEditor + { + public static CountryFieldValidationPropertyDescriptor s_FirstName = new CountryFieldValidationPropertyDescriptor(nameof(FirstName), CountryFieldValidatorType.FirstName); + public static CountryFieldValidationPropertyDescriptor s_LastName = new CountryFieldValidationPropertyDescriptor(nameof(LastName), CountryFieldValidatorType.LastName); + public static PhoneNumberDescriptors s_PhoneNumber = new PhoneNumberDescriptors(nameof(PhoneNumber), CountryFieldValidatorType.PhoneNumber); + public static CountryFieldValidationPropertyDescriptor s_PhoneExtension = new CountryFieldValidationPropertyDescriptor(nameof(PhoneExtension), CountryFieldValidatorType.PhoneExtension); + public static EmailPropertyDescriptor s_Email = new EmailPropertyDescriptor(nameof(Email), string.Empty, string.Empty, true); + + public static PropertyDescriptor FirstName => (PropertyDescriptor)BaseContactInfoPropertyEditor.s_FirstName; + + public static PropertyDescriptor LastName => (PropertyDescriptor)BaseContactInfoPropertyEditor.s_LastName; + + public static PropertyDescriptor PhoneNumber => (PropertyDescriptor)BaseContactInfoPropertyEditor.s_PhoneNumber; + + public static PropertyDescriptor PhoneExtension => (PropertyDescriptor)BaseContactInfoPropertyEditor.s_PhoneExtension; + + public static PropertyDescriptor Email => (PropertyDescriptor)BaseContactInfoPropertyEditor.s_Email; + } +} diff --git a/ZuneUI/BasicAccountInfoPropertyEditor.cs b/ZuneUI/BasicAccountInfoPropertyEditor.cs new file mode 100644 index 0000000..16490d4 --- /dev/null +++ b/ZuneUI/BasicAccountInfoPropertyEditor.cs @@ -0,0 +1,41 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BasicAccountInfoPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class BasicAccountInfoPropertyEditor : WizardPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static CountryPropertyDescriptor s_Country = new CountryPropertyDescriptor("HomeAddress.Country", string.Empty, string.Empty, true); + public static LanguagePropertyDescriptor s_Language = new LanguagePropertyDescriptor("Personal.LanguagePreference", string.Empty, string.Empty, true); + public static BirthdayPropertyDescriptor s_Birthday = new BirthdayPropertyDescriptor("Personal.Birthday", string.Empty, string.Empty, true); + public static PostalCodeDescriptor s_PostalCode = new PostalCodeDescriptor(nameof(PostalCode)); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (BasicAccountInfoPropertyEditor.s_dataProviderProperties == null) + BasicAccountInfoPropertyEditor.s_dataProviderProperties = new PropertyDescriptor[4] + { + (PropertyDescriptor) BasicAccountInfoPropertyEditor.s_Country, + (PropertyDescriptor) BasicAccountInfoPropertyEditor.s_Language, + (PropertyDescriptor) BasicAccountInfoPropertyEditor.s_Birthday, + (PropertyDescriptor) BasicAccountInfoPropertyEditor.s_PostalCode + }; + return BasicAccountInfoPropertyEditor.s_dataProviderProperties; + } + } + + public static PropertyDescriptor Country => (PropertyDescriptor)BasicAccountInfoPropertyEditor.s_Country; + + public static PropertyDescriptor Language => (PropertyDescriptor)BasicAccountInfoPropertyEditor.s_Language; + + public static PropertyDescriptor Birthday => (PropertyDescriptor)BasicAccountInfoPropertyEditor.s_Birthday; + + public static PropertyDescriptor PostalCode => (PropertyDescriptor)BasicAccountInfoPropertyEditor.s_PostalCode; + } +} diff --git a/ZuneUI/BasicAccountInfoStep.cs b/ZuneUI/BasicAccountInfoStep.cs new file mode 100644 index 0000000..1d14d36 --- /dev/null +++ b/ZuneUI/BasicAccountInfoStep.cs @@ -0,0 +1,232 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BasicAccountInfoStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.ErrorMapperApi; +using Microsoft.Zune.Service; +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class BasicAccountInfoStep : RegionInfoStep + { + private AccountUserType _newAccountType; + private string _termsOfService; + private string _termsOfServiceUrl; + private string _privacyUrl; + private Dictionary _errorMappings; + + public BasicAccountInfoStep( + Wizard owner, + AccountManagementWizardState state, + bool parentAccount) + : base(owner, state, parentAccount) + { + this.EnableVerticalScrolling = false; + this.LoadLanguages = true; + this.NextTextOverride = Shell.LoadString(StringId.IDS_I_ACCEPT_BUTTON); + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ACCOUNT_INFO_STEP); + this.Initialize((WizardPropertyEditor)new BasicAccountInfoPropertyEditor()); + } + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled; + if (flag) + flag = ((this._owner.CurrentPage != this ? (true ? 1 : 0) : (this.TermsOfService != null ? 1 : 0)) & (this.State.CreatePassportStep.IsEnabled || this.State.PassportPasswordStep.CanCreateAccount ? 1 : (this.State.PassportPasswordStep.IsUpgradeNeeded ? 1 : 0))) != 0; + return flag; + } + } + + protected override PropertyDescriptor CountryDescriptor => BasicAccountInfoPropertyEditor.Country; + + protected override PropertyDescriptor LanguageDescriptor => BasicAccountInfoPropertyEditor.Language; + + public bool IsParentAccountNeeded => this._newAccountType != AccountUserType.Adult; + + public AccountUserType NewAccounType + { + get => this._newAccountType; + private set + { + if (this._newAccountType == value) + return; + this._newAccountType = value; + this.FirePropertyChanged(nameof(NewAccounType)); + this.FirePropertyChanged("IsParentAccountNeeded"); + } + } + + public string TermsOfService + { + get => this._termsOfService; + private set + { + if (!(this._termsOfService != value)) + return; + this._termsOfService = value; + this.FirePropertyChanged(nameof(TermsOfService)); + this.FirePropertyChanged("IsEnabled"); + } + } + + public string PrivacyUrl + { + get => this._privacyUrl; + private set + { + if (!(this._privacyUrl != value)) + return; + this._privacyUrl = value; + this.FirePropertyChanged(nameof(PrivacyUrl)); + } + } + + public string TermsOfServiceUrl + { + get => this._termsOfServiceUrl; + private set + { + if (!(this._termsOfServiceUrl != value)) + return; + this._termsOfServiceUrl = value; + this.FirePropertyChanged(nameof(TermsOfServiceUrl)); + } + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#BasicAccountInfoStep"; + + internal override Dictionary ErrorPropertyMappings + { + get + { + if (this._errorMappings == null) + { + this._errorMappings = new Dictionary(4); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_BIRTH_YEAR_INVALID.Int, BasicAccountInfoPropertyEditor.Birthday); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_BIRTH_DAY_INVALID.Int, BasicAccountInfoPropertyEditor.Birthday); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_BIRTH_MONTH_INVALID.Int, BasicAccountInfoPropertyEditor.Birthday); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_BIRTH_DATE_FUTURE.Int, BasicAccountInfoPropertyEditor.Birthday); + this._errorMappings.Add(HRESULT._ZEST_E_INVALID_ARG_LANGUAGE.Int, BasicAccountInfoPropertyEditor.Language); + } + return this._errorMappings; + } + } + + protected override void OnCountryChanged() + { + this.SetPropertyState(BasicAccountInfoPropertyEditor.PostalCode, (object)this.SelectedCountry); + this.SetPropertyState(BasicAccountInfoPropertyEditor.Birthday, (object)this.SelectedLocale); + this.TermsOfService = (string)null; + this.TermsOfServiceUrl = TermsOfServiceStep.GetTermsOfServiceUrl(this.SelectedLocale); + this.PrivacyUrl = TermsOfServiceStep.GetPrivacyUrl(this.SelectedLocale); + this.SetUncommittedValue(BasicAccountInfoPropertyEditor.Birthday, this.GetCommittedValue(BasicAccountInfoPropertyEditor.Birthday)); + if (!this.ServiceActivationRequestsDone) + return; + this.Activate(); + } + + protected override void OnLanguageChanged() + { + this.SetPropertyState(BasicAccountInfoPropertyEditor.Birthday, (object)this.SelectedLocale); + this.TermsOfService = (string)null; + this.TermsOfServiceUrl = TermsOfServiceStep.GetTermsOfServiceUrl(this.SelectedLocale); + this.PrivacyUrl = TermsOfServiceStep.GetPrivacyUrl(this.SelectedLocale); + this.SetUncommittedValue(BasicAccountInfoPropertyEditor.Birthday, this.GetCommittedValue(BasicAccountInfoPropertyEditor.Birthday)); + if (!this.ServiceActivationRequestsDone) + return; + this.Activate(); + } + + protected override void OnActivate() + { + this.ServiceDeactivationRequestsDone = false; + this.SetUncommittedValue(BasicAccountInfoPropertyEditor.Birthday, this.GetCommittedValue(BasicAccountInfoPropertyEditor.Birthday)); + this.ServiceActivationRequestsDone = this.TermsOfService != null; + base.OnActivate(); + } + + internal override bool OnMovingNext() + { + if (this.ServiceDeactivationRequestsDone) + return base.OnMovingNext(); + DateTime? uncommittedValue = (DateTime?)this.GetUncommittedValue(BasicAccountInfoPropertyEditor.Birthday); + this.StartDeactivationRequests((object)new BasicAccountInfoStep.WorkerThreadData() + { + Birthday = uncommittedValue.Value, + SelectedCountry = this.SelectedCountry + }); + return false; + } + + internal override ErrorMapperResult GetMappedErrorDescriptionAndUrl(HRESULT hr) => Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int, eErrorCondition.eEC_WinLive); + + protected override void OnStartActivationRequests(object state) + { + base.OnStartActivationRequests(state); + if (!(state is RegionInfoStep.RegionServiceData regionServiceData) || string.IsNullOrEmpty(regionServiceData.SelectedCountry)) + return; + this.EndActivationRequests((object)this.ObtainTermsOfService(regionServiceData.SelectedLanguage, regionServiceData.SelectedCountry)); + } + + protected override void OnEndActivationRequests(object args) + { + if (args == null) + this.NavigateToErrorHandler(); + else if (args is string) + this.TermsOfService = (string)args; + else + base.OnEndActivationRequests(args); + } + + protected override void OnStartDeactivationRequests(object state) => this.EndDeactivationRequests((object)this.ObtainNewAccountType((BasicAccountInfoStep.WorkerThreadData)state)); + + protected override void OnEndDeactivationRequests(object args) + { + this.NewAccounType = (AccountUserType)args; + this.State.SetPrivacySettings(this.NewAccounType); + } + + private AccountUserType ObtainNewAccountType( + BasicAccountInfoStep.WorkerThreadData data) + { + AccountUserType accountUserType = AccountUserType.Unknown; + AccountCountry country = AccountCountryList.Instance.GetCountry(data.SelectedCountry); + if (country != null) + { + int age = this.ObtainAge(data.Birthday); + accountUserType = age < country.AdultAge ? (age < country.TeenagerAge ? AccountUserType.ChildWithoutSocial : AccountUserType.ChildWithSocial) : AccountUserType.Adult; + } + return accountUserType; + } + + private int ObtainAge(DateTime birthday) + { + DateTime today = DateTime.Today; + int num = today.Year - birthday.Year; + if (today.Month < birthday.Month || today.Month == birthday.Month && today.Day < birthday.Day) + --num; + return num; + } + + private string ObtainTermsOfService(string language, string country) + { + string termsOfService1 = (string)null; + HRESULT termsOfService2 = this.State.AccountManagement.GetTermsOfService(language, country, out termsOfService1); + if (termsOfService2.IsError) + this.SetError(termsOfService2, (ServiceError)null); + return termsOfService1; + } + + public class WorkerThreadData + { + public DateTime Birthday; + public string SelectedCountry; + } + } +} diff --git a/ZuneUI/BillingOfferHelper.cs b/ZuneUI/BillingOfferHelper.cs new file mode 100644 index 0000000..c0c57a6 --- /dev/null +++ b/ZuneUI/BillingOfferHelper.cs @@ -0,0 +1,285 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BillingOfferHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.ErrorMapperApi; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class BillingOfferHelper : ModelItem + { + private BillingOfferCollection m_pointsOffers; + private BillingOfferCollection m_subscriptionOffers; + private HRESULT m_errorCode; + private BillingOffer m_currentSubscription; + private BillingOffer m_renewalSubscription; + + public event EventHandler PurchaseComplete; + + public event EventHandler PurchaseFailed; + + public void GetSubscriptionOffers() + { + this.ErrorCode = HRESULT._S_OK; + ZuneApplication.Service.GetSubscriptionOffers(new GetBillingOffersCompleteCallback(this.OnGetSubscriptionsComplete), new GetBillingOffersErrorCallback(this.OnGetSubscriptionsError)); + } + + public void GetPointsOffers() + { + this.ErrorCode = HRESULT._S_OK; + ZuneApplication.Service.GetPointsOffers(new GetBillingOffersCompleteCallback(this.OnGetPointsOffersComplete), new GetBillingOffersErrorCallback(this.OnGetPointsOffersError)); + } + + public void GetCurrentSubscription() + { + this.ErrorCode = HRESULT._S_OK; + if (SignIn.Instance.SignedInWithSubscription) + ZuneApplication.Service.GetSubscriptionDetails(SignIn.Instance.SubscriptionId, new GetBillingOffersCompleteCallback(this.OnGetCurrentSubscriptionComplete), new GetBillingOffersErrorCallback(this.OnGetCurrentSubscriptionError)); + else + this.CurrentSubscription = (BillingOffer)null; + } + + public void GetRenewalSubscription() + { + this.ErrorCode = HRESULT._S_OK; + ulong subscriptionRenewalId = SignIn.Instance.SubscriptionRenewalId; + if (SignIn.Instance.SignedInWithSubscription && subscriptionRenewalId != 0UL) + ZuneApplication.Service.GetSubscriptionDetails(subscriptionRenewalId, new GetBillingOffersCompleteCallback(this.OnGetRenewalSubscriptionComplete), new GetBillingOffersErrorCallback(this.OnGetRenewalSubscriptionError)); + else + this.RenewalSubscription = (BillingOffer)null; + } + + public void Purchase(BillingOffer billingOffer, PaymentInstrument paymentInstrument) + { + this.ErrorCode = HRESULT._S_OK; + if (billingOffer == null) + return; + AsyncCompleteHandler callback = billingOffer.OfferType != EBillingOfferType.Points ? new AsyncCompleteHandler(this.OnPurchaseSubscriptionComplete) : new AsyncCompleteHandler(this.OnPurchasePointsComplete); + ZuneApplication.Service.PurchaseBillingOffer(billingOffer, paymentInstrument, callback); + } + + public static bool IsSubscribed(BillingOffer offer) + { + bool flag = false; + if (offer != null && ZuneApplication.Service.IsSignedInWithSubscription()) + flag = (long)SignIn.Instance.SubscriptionId == (long)offer.Id; + return flag; + } + + public static bool IsSubscriptionChanging() + { + bool flag = false; + if (ZuneApplication.Service.IsSignedInWithSubscription()) + flag = (long)SignIn.Instance.SubscriptionRenewalId != (long)SignIn.Instance.SubscriptionId; + return flag; + } + + public static bool IsLightWeightError(HRESULT hr) + { + if (HRESULT._NS_E_BILLING_LIGHTWEIGHT_ACCOUNT == hr) + return true; + ErrorMapperResult descriptionAndUrl = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int); + return HRESULT._NS_E_BILLING_LIGHTWEIGHT_ACCOUNT.Int == descriptionAndUrl.Hr; + } + + public IList PointsOffers => this.m_pointsOffers == null ? (IList)null : this.m_pointsOffers.Items; + + public IList Subscriptions => this.m_subscriptionOffers == null ? (IList)null : this.m_subscriptionOffers.Items; + + public BillingOffer CurrentSubscription + { + get => this.m_currentSubscription; + private set + { + if (this.m_currentSubscription == value) + return; + this.m_currentSubscription = value; + this.FirePropertyChanged(nameof(CurrentSubscription)); + } + } + + public BillingOffer RenewalSubscription + { + get => this.m_renewalSubscription; + private set + { + if (this.m_renewalSubscription == value) + return; + this.m_renewalSubscription = value; + this.FirePropertyChanged(nameof(RenewalSubscription)); + } + } + + public HRESULT ErrorCode + { + get => this.m_errorCode; + set + { + if (!(this.m_errorCode != value)) + return; + this.m_errorCode = value; + this.FirePropertyChanged(nameof(ErrorCode)); + } + } + + private void SetError(HRESULT hrError) => this.ErrorCode = hrError; + + private void OnGetSubscriptionsComplete(BillingOfferCollection subscriptions) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetSubscriptionsComplete), (object)subscriptions); + + private void OnGetSubscriptionsError(HRESULT hrError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetError), (object)hrError); + + private void OnGetCurrentSubscriptionComplete(BillingOfferCollection subscriptions) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetSubsciptionComplete), (object)new object[3] + { + (object) EBillingOfferType.Subscription, + (object) SignIn.Instance.SubscriptionRenewalId, + (object) subscriptions + }); + + private void OnGetCurrentSubscriptionError(HRESULT hrError) + { + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetError), (object)hrError); + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetSubsciptionComplete), (object)new object[3] + { + (object) EBillingOfferType.Subscription, + (object) SignIn.Instance.SubscriptionRenewalId, + null + }); + } + + private void OnGetRenewalSubscriptionComplete(BillingOfferCollection subscriptions) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetSubsciptionComplete), (object)new object[3] + { + (object) EBillingOfferType.Renewal, + (object) SignIn.Instance.SubscriptionRenewalId, + (object) subscriptions + }); + + private void OnGetRenewalSubscriptionError(HRESULT hrError) + { + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetError), (object)hrError); + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetSubsciptionComplete), (object)new object[3] + { + (object) EBillingOfferType.Renewal, + (object) SignIn.Instance.SubscriptionRenewalId, + null + }); + } + + private void OnGetPointsOffersComplete(BillingOfferCollection pointsOffers) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetPointsOffersComplete), (object)pointsOffers); + + private void OnGetPointsOffersError(HRESULT hrError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetError), (object)hrError); + + private void OnPurchaseSubscriptionComplete(HRESULT hrError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredPurchaseComplete), (object)new object[2] + { + (object) hrError, + (object) true + }); + + private void OnPurchasePointsComplete(HRESULT hrError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredPurchaseComplete), (object)new object[2] + { + (object) hrError, + (object) false + }); + + private void DeferredGetSubscriptionsComplete(object args) + { + BillingOfferCollection billingOfferCollection = (BillingOfferCollection)args; + if (this.IsDisposed) + { + billingOfferCollection?.Dispose(); + } + else + { + if (this.m_subscriptionOffers != null) + this.m_subscriptionOffers.Dispose(); + this.m_subscriptionOffers = billingOfferCollection; + this.FirePropertyChanged("Subscriptions"); + } + } + + private void DeferredGetSubsciptionComplete(object args) + { + object[] objArray = (object[])args; + EBillingOfferType eBillingOfferType = (EBillingOfferType)objArray[0]; + ulong id = (ulong)objArray[1]; + BillingOfferCollection billingOfferCollection = objArray[2] as BillingOfferCollection; + BillingOffer billingOffer = (BillingOffer)null; + if (billingOfferCollection != null && billingOfferCollection.Items != null && billingOfferCollection.Items.Count > 0) + billingOffer = billingOfferCollection.Items[0] as BillingOffer; + if (billingOffer == null && SignIn.Instance.SignedInWithSubscription) + billingOffer = new BillingOffer(id, eBillingOfferType, string.Empty); + if (eBillingOfferType == EBillingOfferType.Subscription) + { + this.CurrentSubscription = billingOffer; + } + else + { + if (eBillingOfferType != EBillingOfferType.Renewal) + return; + this.RenewalSubscription = billingOffer; + } + } + + private void DeferredGetPointsOffersComplete(object args) + { + BillingOfferCollection billingOfferCollection = (BillingOfferCollection)args; + if (this.IsDisposed) + { + billingOfferCollection?.Dispose(); + } + else + { + if (this.m_pointsOffers != null) + this.m_pointsOffers.Dispose(); + this.m_pointsOffers = billingOfferCollection; + this.FirePropertyChanged("PointsOffers"); + } + } + + private void DeferredPurchaseComplete(object args) + { + HRESULT hrError = (HRESULT)((object[])args)[0]; + bool flag = (bool)((object[])args)[1]; + if (hrError.IsError) + { + this.SetError(hrError); + if (this.PurchaseFailed != null) + this.PurchaseFailed((object)this, (EventArgs)null); + this.FirePropertyChanged("PurchaseFailed"); + } + else + { + if (flag) + SignIn.Instance.RefreshAccount(); + if (this.PurchaseComplete != null) + this.PurchaseComplete((object)this, (EventArgs)null); + this.FirePropertyChanged("PurchaseComplete"); + } + } + + private void DeferredSetError(object args) => this.SetError((HRESULT)args); + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing) + return; + if (this.m_subscriptionOffers != null) + { + this.m_subscriptionOffers.Dispose(); + this.m_subscriptionOffers = (BillingOfferCollection)null; + } + if (this.m_pointsOffers == null) + return; + this.m_pointsOffers.Dispose(); + this.m_pointsOffers = (BillingOfferCollection)null; + } + } +} diff --git a/ZuneUI/BirthdayPropertyDescriptor.cs b/ZuneUI/BirthdayPropertyDescriptor.cs new file mode 100644 index 0000000..3d5ca1b --- /dev/null +++ b/ZuneUI/BirthdayPropertyDescriptor.cs @@ -0,0 +1,70 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BirthdayPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class BirthdayPropertyDescriptor : DatePropertyDescriptor + { + public BirthdayPropertyDescriptor(string name, string multiValueString, string unknownString) + : base(name, multiValueString, unknownString) + { + } + + public BirthdayPropertyDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : base(name, multiValueString, unknownString, required) + { + } + + public override bool IsValidInternal(string value) => this.IsValidInternal(value, (object)null); + + public override string ConvertToString(object value, object state) + { + string unknownString = this.UnknownString; + DateTime? nullable = (DateTime?)value; + if (nullable.HasValue && nullable.Value != DateTime.MinValue) + unknownString = DateTimeHelper.ToString((DateTime)value, state as string, DateTimeFormatType.ShortDate); + return unknownString; + } + + public override object ConvertFromString(string value, object state) + { + DateTime dateTime = DateTime.MinValue; + string cultureString = state as string; + DateTimeHelper.TryParse(value, cultureString, out dateTime); + return (object)dateTime; + } + + public override bool IsValidInternal(string value, object state) + { + string cultureString = state as string; + bool flag; + if (StringParserHelper.IsNullOrEmptyOrBlank(value)) + { + flag = !this.IsRequired(state); + } + else + { + DateTime dateTime; + flag = DateTimeHelper.TryParse(value, cultureString, out dateTime); + if (flag && dateTime > DateTime.Now) + flag = false; + } + return flag; + } + + internal override string GetOverlayString(object state) + { + string cultureString = state as string; + return !string.IsNullOrEmpty(cultureString) ? DateTimeHelper.GetDisplayPattern(cultureString) : (string)null; + } + } +} diff --git a/ZuneUI/BlockListUpdatesReason.cs b/ZuneUI/BlockListUpdatesReason.cs new file mode 100644 index 0000000..532dec9 --- /dev/null +++ b/ZuneUI/BlockListUpdatesReason.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BlockListUpdatesReason +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + [Flags] + public enum BlockListUpdatesReason + { + None = 0, + ModalUI = 1, + JumpInList = 2, + DragSelect = 4, + DragDrop = 8, + Edit = 16, // 0x00000010 + Focus = 32, // 0x00000020 + } +} diff --git a/ZuneUI/BoolDisposeHelper.cs b/ZuneUI/BoolDisposeHelper.cs new file mode 100644 index 0000000..2c54ceb --- /dev/null +++ b/ZuneUI/BoolDisposeHelper.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BoolDisposeHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class BoolDisposeHelper : ModelItem + { + private BooleanChoice _choice; + private bool _resetOnDispose; + + public BooleanChoice Choice + { + get => this._choice; + set + { + if (this._choice == value) + return; + this._choice = value; + this.FirePropertyChanged(nameof(Choice)); + } + } + + public bool ResetOnDispose + { + get => this._resetOnDispose; + set + { + if (this._resetOnDispose == value) + return; + this._resetOnDispose = value; + this.FirePropertyChanged(nameof(ResetOnDispose)); + } + } + + protected override void OnDispose(bool disposing) + { + if (disposing && this._choice != null && this._resetOnDispose) + this._choice.Value = false; + base.OnDispose(disposing); + } + } +} diff --git a/ZuneUI/BooleanInputChoice.cs b/ZuneUI/BooleanInputChoice.cs new file mode 100644 index 0000000..911dbee --- /dev/null +++ b/ZuneUI/BooleanInputChoice.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BooleanInputChoice +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class BooleanInputChoice : BooleanChoice + { + private bool available = true; + + internal BooleanInputChoice(ModelItem owner, string description, bool isAvailable) + : base((IModelItemOwner)owner, description) + => this.Available = isAvailable; + + public bool Available + { + get => this.available; + set + { + if (this.available == value) + return; + this.available = value; + this.FirePropertyChanged(nameof(Available)); + } + } + } +} diff --git a/ZuneUI/Breadcrumb.cs b/ZuneUI/Breadcrumb.cs new file mode 100644 index 0000000..3711549 --- /dev/null +++ b/ZuneUI/Breadcrumb.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Breadcrumb +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class Breadcrumb : ModelItem + { + private WizardPage _page; + private bool _active; + private bool _complete; + + public Breadcrumb(WizardPage page) => this._page = page; + + public WizardPage Page => this._page; + + public bool Active + { + get => this._active; + set + { + if (this._active == value) + return; + this._active = value; + this.FirePropertyChanged(nameof(Active)); + } + } + + public bool Complete + { + get => this._complete; + set + { + if (this._complete == value) + return; + this._complete = value; + this.FirePropertyChanged(nameof(Complete)); + } + } + } +} diff --git a/ZuneUI/BreadcrumbFactory.cs b/ZuneUI/BreadcrumbFactory.cs new file mode 100644 index 0000000..fb3646a --- /dev/null +++ b/ZuneUI/BreadcrumbFactory.cs @@ -0,0 +1,56 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BreadcrumbFactory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class BreadcrumbFactory + { + private IList _breadcrumbs; + + public IList Breadcrumbs => (IList)this._breadcrumbs; + + public void AddCrumb(Breadcrumb breadcrumb) + { + if (this._breadcrumbs == null) + { + this._breadcrumbs = (IList)new List(); + breadcrumb.Active = true; + } + this._breadcrumbs.Add(breadcrumb); + } + + public void UpdateState(WizardPage currentPage, WizardPage destinationPage, bool movingNext) + { + for (int index = 0; index < this._breadcrumbs.Count; ++index) + { + Breadcrumb breadcrumb = this._breadcrumbs[index]; + if (breadcrumb.Page == currentPage) + { + if (!movingNext) + { + this._breadcrumbs[index].Active = false; + if (index > 0) + this._breadcrumbs[index - 1].Complete = false; + } + } + else if (breadcrumb.Page == destinationPage) + { + this._breadcrumbs[index].Active = true; + if (movingNext) + { + if (index > 0) + this._breadcrumbs[index - 1].Complete = true; + } + else + this._breadcrumbs[index].Complete = false; + } + } + } + } +} diff --git a/ZuneUI/BurnSessionItem.cs b/ZuneUI/BurnSessionItem.cs new file mode 100644 index 0000000..c40a9d0 --- /dev/null +++ b/ZuneUI/BurnSessionItem.cs @@ -0,0 +1,116 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BurnSessionItem +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class BurnSessionItem : ModelItem + { + private BurnableCD _burnCD; + private int _burnListIndex; + private int _playlistContentId; + private bool _burnComplete; + private int _errorCode; + private int _burnProgress; + private bool _downloading; + private int _downloadProgress; + private bool _burnCanceled; + private Guid _zuneMediaId; + + internal BurnSessionItem( + BurnableCD burnCD, + int burnListIndex, + int playlistContentId, + Guid zuneMediaId) + { + this._burnCD = burnCD; + this._burnListIndex = burnListIndex; + this._playlistContentId = playlistContentId; + this._burnProgress = -1; + this._zuneMediaId = zuneMediaId; + } + + public int PlaylistContentId => this._playlistContentId; + + public Guid ZuneMediaId => this._zuneMediaId; + + public int ErrorCode + { + get => this._errorCode; + internal set + { + if (this._errorCode == value) + return; + this._errorCode = value; + this.FirePropertyChanged(nameof(ErrorCode)); + } + } + + public int BurnProgress + { + get => this._burnProgress; + internal set + { + if (this._burnProgress == value) + return; + this._burnProgress = value; + this.FirePropertyChanged(nameof(BurnProgress)); + } + } + + public bool BurnComplete + { + get => this._burnComplete; + internal set + { + if (this._burnComplete == value) + return; + this._burnComplete = value; + this.FirePropertyChanged(nameof(BurnComplete)); + } + } + + public bool BurnCanceled + { + get => this._burnCanceled; + internal set + { + if (this._burnCanceled == value) + return; + this._burnCanceled = value; + this.FirePropertyChanged(nameof(BurnCanceled)); + } + } + + public bool Downloading + { + get => this._downloading; + internal set + { + if (this._downloading == value) + return; + this._downloading = value; + this.FirePropertyChanged(nameof(Downloading)); + } + } + + public int DownloadProgress + { + get => this._downloadProgress; + internal set + { + if (this._downloadProgress == value) + return; + this._downloadProgress = value; + this.FirePropertyChanged(nameof(DownloadProgress)); + } + } + + internal int BurnListIndex => this._burnListIndex; + } +} diff --git a/ZuneUI/BurnableCD.cs b/ZuneUI/BurnableCD.cs new file mode 100644 index 0000000..671d8e5 --- /dev/null +++ b/ZuneUI/BurnableCD.cs @@ -0,0 +1,471 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.BurnableCD +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class BurnableCD : ModelItem + { + private CDAccess _cdAccess; + private ZuneLibraryCDDevice _device; + private bool _isBurning; + private bool _hasDeviceStartedBurn; + private bool _isErasing; + private bool _burnCanceling; + private List _items; + private int _playlistId; + private string _burnTitle; + private bool _downloadsComplete; + private HRESULT _burnError; + private ProgressNotification _burnNotification; + private int _sessionTotalTime; + private int _sessionTimeRemaining; + private int _sessionPercentComplete; + private int _sessionCurrentTrackNumber; + private bool _sessionFinalizing; + private Timer _progressTimer; + private int _simulatedTickInterval; + private string _burnProgressMessage; + private static string s_burnStartedMessage = Shell.LoadString(StringId.IDS_BURN_STARTED_NOTIFICATION); + private static string s_burnPreparingMessage = Shell.LoadString(StringId.IDS_BURN_PREPARING); + private static string s_burnProgressMessage = Shell.LoadString(StringId.IDS_BURN_PROGRESS_NOTIFICATION); + private static string s_burnProgressDataMessage = Shell.LoadString(StringId.IDS_BURN_PROGRESS_NOTIFICATION_DATA); + private static string s_burnFinalizingMessage = Shell.LoadString(StringId.IDS_BURN_FINALIZING); + private static string s_burnSucceededMessage = Shell.LoadString(StringId.IDS_BURN_SUCCEEDED_NOTIFICATION); + private static string s_burnFailedMessage = Shell.LoadString(StringId.IDS_BURN_FAILED_NOTIFICATION); + private static string s_burnCanceledMessage = Shell.LoadString(StringId.IDS_BURN_CANCELED_NOTIFICATION); + private static string s_burnCancelingMessage = Shell.LoadString(StringId.IDS_BURN_CANCELING_NOTIFICATION); + private static string s_eraseStartedMessage = Shell.LoadString(StringId.IDS_ERASE_STARTED_NOTIFICATION); + private static string s_eraseFinishedMessage = Shell.LoadString(StringId.IDS_ERASE_COMPLETED_NOTIFICATION); + + internal BurnableCD(CDAccess cdAccess, ZuneLibraryCDDevice device) + { + this._cdAccess = cdAccess; + this._device = device; + } + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + if (!fDisposing) + return; + this._device = (ZuneLibraryCDDevice)null; + this._cdAccess = (CDAccess)null; + } + + internal bool IsWriteable => this._device.IsWriteable; + + public bool CanBurnAudio => !this._device.IsDVD; + + public ZuneLibraryCDDevice Device => this._device; + + public char DriveLetter => this._device.DrivePath; + + public TimeSpan TimeAvailable => TimeSpan.FromSeconds((double)this._device.TimeAvailable); + + public long SpaceAvailable => this._device.SpaceAvailable; + + public bool IsBurning => this._isBurning; + + public bool IsErasing => this._isErasing; + + public bool IsBurnCanceling => this._burnCanceling; + + public void PrepareForBurn(string burnTitle, int playlistId, IList burnListItems) + { + this._isBurning = true; + this._burnError = new HRESULT(); + this._items = new List(burnListItems.Count); + this._playlistId = playlistId; + this._burnTitle = burnTitle; + this._downloadsComplete = false; + this._burnProgressMessage = this._cdAccess.IsAudioBurn ? BurnableCD.s_burnProgressMessage : BurnableCD.s_burnProgressDataMessage; + for (int index = 0; index < burnListItems.Count; ++index) + { + DataProviderObject burnListItem = (DataProviderObject)burnListItems[index]; + int property1 = (int)burnListItem.GetProperty("LibraryId"); + Guid property2 = (Guid)burnListItem.GetProperty("ZuneMediaId"); + this._items.Add(new BurnSessionItem(this, index, property1, property2)); + } + this.BeginSession(); + this.UpdateMessage(); + } + + public void ClearBurnItems() => this._items = (List)null; + + public void StartBurn() + { + if (!this._isBurning) + return; + this.WaitForDownloads(); + } + + private void WaitForDownloads() + { + bool flag = false; + if (this._cdAccess.IsAudioBurn) + { + foreach (BurnSessionItem burnSessionItem in this._items) + { + bool fPending = false; + if (Download.Instance.IsDownloading(burnSessionItem.ZuneMediaId, EContentType.MusicTrack, out fPending)) + { + burnSessionItem.Downloading = true; + flag = true; + } + } + } + if (!flag) + { + this.StartBurnForReal(); + } + else + { + Download.Instance.DownloadEvent += new DownloadEventHandler(this.OnDownloadEvent); + Download.Instance.DownloadProgressEvent += new DownloadEventProgressHandler(this.OnDownloadProgress); + this._downloadsComplete = false; + } + } + + private void OnDownloadEvent(Guid zuneMediaId, HRESULT hr) + { + if (this._downloadsComplete || hr == HRESULT._E_PENDING || hr == HRESULT._E_ALREADY_EXISTS) + return; + bool flag = true; + int hrError = 0; + foreach (BurnSessionItem burnSessionItem in this._items) + { + if (burnSessionItem.ZuneMediaId == zuneMediaId) + { + burnSessionItem.Downloading = false; + burnSessionItem.ErrorCode = hr.Int; + } + else if (burnSessionItem.Downloading) + flag = false; + if (hrError == 0 && burnSessionItem.ErrorCode != 0) + hrError = burnSessionItem.ErrorCode; + } + if (!flag) + return; + this._downloadsComplete = true; + if (hrError != 0) + { + this.OnSessionError(hrError); + this.NotifyBurnStopped(); + } + else + this.StartBurnForReal(); + } + + private void OnDownloadProgress(Guid zuneMediaId, float percent) + { + foreach (BurnSessionItem burnSessionItem in this._items) + { + if (burnSessionItem.ZuneMediaId == zuneMediaId) + { + burnSessionItem.DownloadProgress = (int)percent; + break; + } + } + } + + private void StartBurnForReal() + { + this._sessionCurrentTrackNumber = 0; + HRESULT hr = this._device.SetBurnPlaylist(this._playlistId); + if (hr.IsSuccess) + { + if (!string.IsNullOrEmpty(this._burnTitle)) + hr = this._device.SetVolumeLabelW(this._burnTitle); + if (hr.IsSuccess) + hr = this._device.StartBurn(); + } + if (hr.IsError) + { + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.OnSessionError(hr.Int); + this.NotifyBurnStopped(); + }, (object)null); + } + else + { + this._hasDeviceStartedBurn = true; + this.UpdateMessage(); + } + } + + internal void CancelBurn() + { + if (!this._isBurning || this._burnCanceling) + return; + this._burnCanceling = true; + if (this._hasDeviceStartedBurn) + this._device.StopBurn(); + if (this._progressTimer != null) + this._progressTimer.Stop(); + this.UpdateMessage(); + if (!this._hasDeviceStartedBurn) + this.NotifyBurnStopped(); + this._hasDeviceStartedBurn = false; + } + + private void BeginSession() + { + this._device.ItemProgressHandler += new OnItemProgressHandler(this.OnItemProgress); + this._device.ItemErrorHandler += new OnItemErrorHandler(this.OnItemError); + this._device.SessionProgressHandler += new OnSessionProgressHandler(this.OnSessionProgress); + this._device.BurnStateChangeHandler += new OnBurnStateChangeHandler(this.OnBurnStateChanged); + } + + private void NotifyBurnStopped() + { + this.EndSession(); + if (this._burnCanceling && this._items != null) + { + foreach (BurnSessionItem burnSessionItem in this._items) + burnSessionItem.BurnCanceled = true; + this._items = (List)null; + } + this._isBurning = false; + this._burnCanceling = false; + this._sessionFinalizing = false; + this._playlistId = PlaylistManager.InvalidPlaylistId; + this._burnTitle = (string)null; + this._cdAccess.IsBurning = false; + } + + private void EndSession() + { + this._device.ItemProgressHandler -= new OnItemProgressHandler(this.OnItemProgress); + this._device.ItemErrorHandler -= new OnItemErrorHandler(this.OnItemError); + this._device.SessionProgressHandler -= new OnSessionProgressHandler(this.OnSessionProgress); + this._device.BurnStateChangeHandler -= new OnBurnStateChangeHandler(this.OnBurnStateChanged); + Download.Instance.DownloadEvent -= new DownloadEventHandler(this.OnDownloadEvent); + Download.Instance.DownloadProgressEvent -= new DownloadEventProgressHandler(this.OnDownloadProgress); + this._downloadsComplete = false; + this._sessionTotalTime = 0; + this._sessionTimeRemaining = 0; + this._sessionPercentComplete = 0; + if (this._progressTimer != null) + { + this._progressTimer.Dispose(); + this._progressTimer = (Timer)null; + } + this.ShowCompletedMessage(); + } + + public void Erase() + { + if (this._isErasing) + return; + this._isErasing = true; + this._cdAccess.ActiveDriveLetter = this.DriveLetter; + this._cdAccess.IsErasing = true; + this.BeginSession(); + if (!this._device.EraseDisc().IsError) + return; + this.CompleteErase(); + } + + private void CompleteErase() + { + this.EndSession(); + this._isErasing = false; + this._cdAccess.IsErasing = false; + } + + public BurnSessionItem GetBurnItemByPlaylistContentId(int playlistContentId) + { + if (this._items != null) + { + foreach (BurnSessionItem burnSessionItem in this._items) + { + if (burnSessionItem.PlaylistContentId == playlistContentId) + return burnSessionItem; + } + } + return (BurnSessionItem)null; + } + + private void OnItemProgress(int index, EBurnProgressStatus eStatus, int nPercent) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + bool flag = false; + if (0 <= index && index < this._items.Count) + { + if (eStatus == EBurnProgressStatus.ebpsComplete || eStatus == EBurnProgressStatus.ebpsFinalizing) + this._items[index].BurnComplete = true; + else if (eStatus == EBurnProgressStatus.ebpsWritingImageToCD || eStatus == EBurnProgressStatus.ebpsTAOConvertingAndWriting) + { + this._items[index].BurnProgress = nPercent; + int num = index + 1; + if (this._sessionCurrentTrackNumber != num) + { + this._sessionCurrentTrackNumber = num; + flag = true; + } + } + } + if (eStatus == EBurnProgressStatus.ebpsFinalizing) + { + this._sessionFinalizing = true; + flag = true; + } + if (!flag) + return; + this.UpdateMessage(); + }, (object)null); + + private void OnItemError(int index, int hrError) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (index == -1) + { + this.OnSessionError(hrError); + } + else + { + if (0 > index || index >= this._items.Count) + return; + this._items[index].ErrorCode = hrError; + } + }, (object)null); + + private void OnSessionError(int hrError) + { + this._burnError = new HRESULT(hrError); + bool flag = false; + foreach (BurnSessionItem burnSessionItem in this._items) + { + if (burnSessionItem.ErrorCode != 0) + { + flag = true; + break; + } + } + foreach (BurnSessionItem burnSessionItem in this._items) + { + if (!flag) + burnSessionItem.ErrorCode = hrError; + else if (burnSessionItem.ErrorCode == 0) + burnSessionItem.BurnCanceled = true; + } + Shell.ShowErrorDialog(hrError, StringId.IDS_BURN_FAILED); + } + + private void OnSessionProgress(int lSessionTimeRemaining, int lSessionTotalTime) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this._sessionTotalTime = lSessionTotalTime * 1000; + this._sessionTimeRemaining = lSessionTimeRemaining * 1000; + this.UpdateMessage(); + int num = 100 - this._sessionPercentComplete; + if (num <= 0) + return; + this._simulatedTickInterval = this._sessionTimeRemaining / num; + if (this._simulatedTickInterval <= 0) + return; + if (this._progressTimer == null) + { + this._progressTimer = new Timer(); + this._progressTimer.Enabled = true; + this._progressTimer.Tick += new EventHandler(this.OnSimulatedSessionProgress); + } + this._progressTimer.Interval = this._simulatedTickInterval; + }, (object)null); + + private void OnSimulatedSessionProgress(object sender, EventArgs args) + { + this._sessionTimeRemaining = Math.Max(this._sessionTimeRemaining - this._simulatedTickInterval, 0); + this.UpdateMessage(); + } + + private void OnBurnStateChanged(EBurnState eBurnState) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (eBurnState != EBurnState.ebsStopped) + return; + if (this._isBurning) + { + this.NotifyBurnStopped(); + } + else + { + if (!this._isErasing) + return; + this.CompleteErase(); + } + }, (object)null); + + private ProgressNotification Notification + { + get => this._burnNotification; + set + { + this._burnNotification = value; + this._cdAccess.BurnNotification = this._burnNotification; + } + } + + private void UpdateMessage() + { + string message = this._isBurning ? BurnableCD.s_burnStartedMessage : BurnableCD.s_eraseStartedMessage; + if (this._burnNotification == null) + { + this.Notification = new ProgressNotification(message, NotificationTask.Burn, NotificationState.Normal, 0); + } + else + { + this._burnNotification.Type = NotificationState.Normal; + this._burnNotification.Message = message; + } + int num = 0; + if (this._sessionTotalTime > 0) + num = (this._sessionTotalTime - this._sessionTimeRemaining) * 100 / this._sessionTotalTime; + if (this._sessionPercentComplete < num) + this._sessionPercentComplete = num; + this._burnNotification.Percentage = this._sessionPercentComplete; + if (!this._isBurning) + return; + if (this._burnCanceling) + this._burnNotification.SubMessage = BurnableCD.s_burnCancelingMessage; + else if (this._sessionFinalizing) + this._burnNotification.SubMessage = BurnableCD.s_burnFinalizingMessage; + else if (this._sessionCurrentTrackNumber == 0) + this._burnNotification.SubMessage = BurnableCD.s_burnPreparingMessage; + else + this._burnNotification.SubMessage = string.Format(this._burnProgressMessage, (object)this._sessionCurrentTrackNumber, (object)this._items.Count); + } + + private void ShowCompletedMessage() + { + if (this._burnNotification != null && this._burnNotification.Type != NotificationState.Completed) + { + this._burnNotification.Type = NotificationState.Completed; + if (this._isBurning) + { + if (this._burnCanceling) + this._burnNotification.Message = BurnableCD.s_burnCanceledMessage; + else if (this._burnError.IsSuccess) + { + this._burnNotification.Message = BurnableCD.s_burnSucceededMessage; + this._burnNotification.Percentage = 100; + } + else + this._burnNotification.Message = BurnableCD.s_burnFailedMessage; + } + else + this._burnNotification.Message = BurnableCD.s_eraseFinishedMessage; + this._burnNotification.SubMessage = (string)null; + this.Notification = (ProgressNotification)null; + } + SoundHelper.Play(SoundId.BurnComplete); + } + } +} diff --git a/ZuneUI/CDAccess.cs b/ZuneUI/CDAccess.cs new file mode 100644 index 0000000..f38d46c --- /dev/null +++ b/ZuneUI/CDAccess.cs @@ -0,0 +1,627 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CDAccess +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using UIXControls; + +namespace ZuneUI +{ + public class CDAccess : ModelItem + { + private static string _ripCompleteMessage = ZuneUI.Shell.LoadString(StringId.IDS_RIP_COMPLETE_NOTIFICATION); + private static string _ripCanceledMessage = ZuneUI.Shell.LoadString(StringId.IDS_RIP_CANCELED_NOTIFICATION); + private static string _ripFailedMessage = ZuneUI.Shell.LoadString(StringId.IDS_RIP_FAILED_NOTIFICATION); + private static string _ripProgressMessage = ZuneUI.Shell.LoadString(StringId.IDS_RIP_PROGRESS_NOTIFICATION); + private static string _ripCurrentMessage = ZuneUI.Shell.LoadString(StringId.IDS_RIP_CURRENT_NOTIFICATION); + private static CDAccess _singletonInstance; + private static bool s_phase2Complete = false; + private ZuneLibraryCDDeviceList _cdDeviceList; + private ArrayListDataSet _CDs; + private IList _discardedCDs; + private CDAccess.AutoplayInfo _pendingAutoPlay; + private ZuneLibraryCDRecorder _recorder; + private bool _isRipping; + private ProgressNotification _ripNotification; + private int _ripTotalTracks; + private int _ripPercent; + private int _ripCurrentTrack = 1; + private int _ripTrackProgress; + private char _activeDriveLetter; + private bool _isBurning; + private bool _isErasing; + private bool _hasBurner; + private BurnableCD _activeBurnCD; + private BurnableCD _burnCDForNextSession; + private int _burnListId = int.MinValue; + private bool _isBurnListEmpty = true; + private bool _hasBurnedBurnList; + private DRMCanDoQuery _drmQuery; + private ProgressNotification _burnNotification; + + private CDAccess() + { + this._CDs = new ArrayListDataSet(); + if (!CDAccess.s_phase2Complete) + return; + this.Initialize(); + } + + public static void Phase2Catchup() + { + CDAccess.s_phase2Complete = true; + if (CDAccess.Instance == null) + return; + CDAccess.Instance.Initialize(); + } + + private void Initialize() + { + this._cdDeviceList = ZuneApplication.ZuneLibrary.GetCDDeviceList(); + DiscExperience disc = ZuneUI.Shell.MainFrame.Disc; + if (this._cdDeviceList != null) + { + this._cdDeviceList.MediaChangedHandler += new OnMediaChangedHandler(this.OnMediaChanged); + for (int index = 0; index < this._cdDeviceList.Count; ++index) + this._CDs.Add((object)null); + } + disc.RecalculateAvailableNodes(); + this._recorder = ZuneApplication.ZuneLibrary.GetRecorder(); + if (this._recorder == null) + return; + this._recorder.RecordStopHandler += new OnRecordStopHandler(this.OnRecordStop); + this._recorder.RecordProgressHandler += new OnRecordProgressHandler(this.OnRecordProgress); + } + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + if (fDisposing) + { + if (this._cdDeviceList != null) + { + this._cdDeviceList.MediaChangedHandler -= new OnMediaChangedHandler(this.OnMediaChanged); + int num = (int)this._cdDeviceList.Release(); + this._cdDeviceList = (ZuneLibraryCDDeviceList)null; + } + if (this._recorder != null) + { + this._recorder.RecordStopHandler -= new OnRecordStopHandler(this.OnRecordStop); + this._recorder.RecordProgressHandler -= new OnRecordProgressHandler(this.OnRecordProgress); + this._recorder = (ZuneLibraryCDRecorder)null; + } + foreach (CDAlbumCommand cd in (ListDataSet)this._CDs) + cd?.Dispose(); + this._CDs.Clear(); + } + if (this._drmQuery == null) + return; + this._drmQuery.Dispose(); + } + + public static CDAccess Instance + { + get + { + if (CDAccess._singletonInstance == null) + CDAccess._singletonInstance = new CDAccess(); + return CDAccess._singletonInstance; + } + } + + public static void HandleDiskFromAutoplay(string path, CDAction action) + { + int num = path.IndexOf(':'); + if (num <= 0) + return; + char upperInvariant = char.ToUpperInvariant(path[num - 1]); + if (upperInvariant < 'A' || upperInvariant > 'Z') + return; + CDAccess.HandleDiskFromAutoplay(upperInvariant, action); + } + + public static void HandleDiskFromAutoplay(char driveLetter, CDAction action) + { + CDAlbumCommand cdAlbumCommand = (CDAlbumCommand)null; + foreach (CDAlbumCommand cd in (ListDataSet)CDAccess.Instance.CDs) + { + if (cd != null && (int)cd.CDDevice.DrivePath == (int)driveLetter) + { + cdAlbumCommand = cd; + break; + } + } + if (cdAlbumCommand == null) + { + CDAccess.Instance._pendingAutoPlay = new CDAccess.AutoplayInfo(driveLetter, action); + } + else + { + cdAlbumCommand.Invoke(); + if (action == CDAction.Rip && cdAlbumCommand.InsertedDuringSession && ZuneShell.DefaultInstance.Management.AutoCopyCD.Value || !cdAlbumCommand.CDDevice.IsDriveReady) + return; + cdAlbumCommand.AutoPlayAction = action; + } + } + + public ArrayListDataSet CDs => this._CDs; + + public BurnableCD BurnCDForNextSession + { + get => this._burnCDForNextSession; + private set + { + if (this._burnCDForNextSession == value) + return; + this._burnCDForNextSession = value; + this.EnsureBurnList(false); + this.FirePropertyChanged(nameof(BurnCDForNextSession)); + } + } + + internal ZuneLibraryCDRecorder Recorder => this._recorder; + + public bool IsRipping + { + get => this._isRipping; + set + { + if (this._isRipping == value) + return; + this._isRipping = value; + this.FirePropertyChanged(nameof(IsRipping)); + } + } + + public bool IsAudioBurn => ((NamedIntOption)ZuneShell.DefaultInstance.Management.BurnFormat.ChosenValue).Value == 0; + + internal void UpdateIsAudioBurn() => this.FirePropertyChanged("IsAudioBurn"); + + public bool IsBurning + { + get => this._isBurning; + internal set + { + if (this._isBurning == value) + return; + this._isBurning = value; + this.FirePropertyChanged(nameof(IsBurning)); + } + } + + public bool IsErasing + { + get => this._isErasing; + internal set + { + if (this._isErasing == value) + return; + this._isErasing = value; + this.FirePropertyChanged(nameof(IsErasing)); + } + } + + public char ActiveDriveLetter + { + get => this._activeDriveLetter; + set => this._activeDriveLetter = value; + } + + public bool IsBurnCanceling => this._activeBurnCD != null && this._activeBurnCD.IsBurnCanceling; + + public bool HasBurner + { + get => this._hasBurner; + private set + { + if (this._hasBurner == value) + return; + this._hasBurner = value; + this.FirePropertyChanged(nameof(HasBurner)); + } + } + + public TimeSpan DefaultBurnTimeAvailable => TimeSpan.FromMinutes(0.0); + + public long DefaultBurnSpaceAvailable => 0; + + public ProgressNotification BurnNotification + { + get => this._burnNotification; + internal set + { + if (this._burnNotification == value) + return; + this._burnNotification = value; + this.FirePropertyChanged(nameof(BurnNotification)); + } + } + + public void AddToBurnList(IList items) + { + if (this._burnListId >= 0 && this._hasBurnedBurnList && !this._isBurnListEmpty) + { + Command yesCommand = new Command((IModelItemOwner)null, ZuneUI.Shell.LoadString(StringId.IDS_CREATE_BURN_LIST_YES_CREATE), (EventHandler)null); + yesCommand.Invoked += (EventHandler)delegate + { + this.AddToBurnPlaylist(items, true); + }; + Command noCommand = new Command((IModelItemOwner)null, ZuneUI.Shell.LoadString(StringId.IDS_CREATE_BURN_LIST_NO_ADD), (EventHandler)null); + noCommand.Invoked += (EventHandler)delegate + { + this.AddToBurnPlaylist(items, false); + }; + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_CREATE_BURN_LIST_DIALOG_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_CREATE_BURN_LIST_QUESTION), yesCommand, noCommand, (BooleanChoice)null); + } + else + this.AddToBurnPlaylist(items, false); + } + + private void AddToBurnPlaylist(IList items, bool createNew) + { + this.EnsureBurnList(createNew); + int playlist = (int)PlaylistManager.Instance.AddToPlaylist(this._burnListId, items, false); + this._hasBurnedBurnList = false; + this._isBurnListEmpty = false; + ZuneUI.Shell.MainFrame.Disc.RecalculateAvailableNodes(); + ZuneUI.Shell.MainFrame.Disc.Nodes.ChosenValue = (object)ZuneUI.Shell.MainFrame.Disc.BurnList; + } + + public int BurnListId => this._burnListId; + + public bool IsBurnListEmpty => this._isBurnListEmpty; + + public bool HasLoadedMedia + { + get + { + foreach (CDAlbumCommand cd in (ListDataSet)this._CDs) + { + if (cd != null && cd.IsMediaLoaded && (cd.TOC != null || cd.CanWrite)) + return true; + } + return false; + } + } + + private void EnsureBurnList(bool forceCreate) + { + if (this._burnListId >= 0 && !forceCreate) + return; + this._burnListId = PlaylistManager.Instance.CreatePlaylist(ZuneUI.Shell.LoadString(StringId.IDS_PLAYLIST_BURN_LIST), true).PlaylistId; + this._isBurnListEmpty = true; + ZuneUI.Shell.MainFrame.Disc.RecalculateAvailableNodes(); + this.FirePropertyChanged("BurnListId"); + } + + public void ClearBurnList() => this.EnsureBurnList(true); + + public bool DRMCanBurnFile(string filePath) + { + if (this._drmQuery == null) + { + try + { + this._drmQuery = new DRMCanDoQuery(); + } + catch (ApplicationException ex) + { + } + } + return this._drmQuery == null || this._drmQuery.CanBurnFile(filePath); + } + + public void PrepareForBurn(string burnTitle, int playlistId, IList burnListItems) + { + if (this._burnCDForNextSession == null) + return; + this.IsBurning = true; + this._activeBurnCD = this._burnCDForNextSession; + this._activeDriveLetter = this._activeBurnCD.DriveLetter; + this._hasBurnedBurnList = true; + this._activeBurnCD.PrepareForBurn(burnTitle, playlistId, burnListItems); + } + + public void StartBurn() => this._activeBurnCD.StartBurn(); + + public void CancelBurn() + { + if (this._activeBurnCD == null) + return; + this._activeBurnCD.CancelBurn(); + } + + public BurnSessionItem GetBurnItemByPlaylistContentId(int playlistContentId) => this._activeBurnCD != null ? this._activeBurnCD.GetBurnItemByPlaylistContentId(playlistContentId) : (BurnSessionItem)null; + + public string TimeSpanToStringForBurnTime(TimeSpan time) => string.Format("{1:0}{0}{2:00}", (object)CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator, (object)(int)time.TotalMinutes, (object)time.Seconds); + + public event EventHandler MediaChanged; + + public IList DiscardedCDs + { + get => this._discardedCDs; + set => this._discardedCDs = value; + } + + private void OnMediaChanged(char driveLetter, bool fMediaArrived) + { + CDAccess.ChangeInfo changeInfo = new CDAccess.ChangeInfo(driveLetter, fMediaArrived); + for (int idx = 0; idx < this._cdDeviceList.Count; ++idx) + { + ZuneLibraryCDDevice zuneLibraryCdDevice = this._cdDeviceList.GetItem(idx); + if ((int)zuneLibraryCdDevice.DrivePath == (int)changeInfo.DriveLetter) + { + changeInfo.Index = idx; + changeInfo.Device = zuneLibraryCdDevice; + break; + } + } + this.WaitForDrive((object)changeInfo); + } + + private void WaitForDrive(object arg) + { + CDAccess.ChangeInfo changeInfo = (CDAccess.ChangeInfo)arg; + if (changeInfo.Device == null || !changeInfo.MediaArrived || changeInfo.Device.IsDriveReady) + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredOnMediaChanged), (object)changeInfo); + else + Application.DeferredInvoke(new DeferredInvokeHandler(this.WaitForDrive), (object)changeInfo, TimeSpan.FromMilliseconds(500.0)); + } + + private void DeferredOnMediaChanged(object arg) + { + CDAccess.ChangeInfo changeInfo = (CDAccess.ChangeInfo)arg; + ZuneLibraryCDDevice device = changeInfo.Device; + int index = changeInfo.Index; + bool flag = (int)this._activeDriveLetter == (int)changeInfo.DriveLetter && !changeInfo.MediaArrived; + if (device != null) + { + CDAlbumCommand cd = (CDAlbumCommand)this._CDs[index]; + if (!ZuneLibraryCDDevice.IsImapiv2Installed && flag && (cd.BurnCD.IsBurning || cd.BurnCD.IsErasing)) + { + device.Dispose(); + return; + } + if (cd == null || !changeInfo.MediaArrived || device.TOC != cd.TOC) + { + CDAlbumCommand cdAlbumCommand = (CDAlbumCommand)null; + if (changeInfo.MediaArrived) + cdAlbumCommand = new CDAlbumCommand((Experience)ZuneUI.Shell.MainFrame.Disc, this, device, true); + this._CDs[index] = (object)cdAlbumCommand; + if (cd != null) + { + if (this._discardedCDs == null) + this._discardedCDs = (IList)new List(); + this._discardedCDs.Add((object)cd); + } + if (cdAlbumCommand == null) + device.Dispose(); + else + device.Close(); + } + else + device.Dispose(); + } + if (this._pendingAutoPlay != null && (int)this._pendingAutoPlay.DriveLetter == (int)changeInfo.DriveLetter) + { + CDAccess.HandleDiskFromAutoplay(this._pendingAutoPlay.DriveLetter, this._pendingAutoPlay.Action); + this._pendingAutoPlay = (CDAccess.AutoplayInfo)null; + } + if (flag && this._activeBurnCD != null) + { + if (this._activeBurnCD.IsBurning) + this._activeBurnCD.CancelBurn(); + else + this._activeBurnCD.ClearBurnItems(); + this._activeDriveLetter = char.MinValue; + } + this.UpdateBurnState(); + ZuneUI.Shell.MainFrame.Disc.UpdateNodes(this, changeInfo.DriveLetter, changeInfo.MediaArrived); + this.NotifyMediaChanged(); + } + + private void UpdateBurnState() + { + BurnableCD burnableCd = (BurnableCD)null; + foreach (CDAlbumCommand cd in (ListDataSet)this._CDs) + { + if (cd != null && cd.CanWrite) + { + burnableCd = cd.BurnCD; + break; + } + } + this.BurnCDForNextSession = burnableCd; + bool flag = false; + for (int idx = 0; idx < this._cdDeviceList.Count; ++idx) + { + ZuneLibraryCDDevice zuneLibraryCdDevice = this._cdDeviceList.GetItem(idx); + flag |= zuneLibraryCdDevice.IsBurner; + zuneLibraryCdDevice.Dispose(); + } + this.HasBurner = flag; + } + + private void NotifyMediaChanged() + { + this.FirePropertyChanged("MediaChanged"); + if (this.MediaChanged == null) + return; + this.MediaChanged((object)this, new EventArgs()); + } + + internal void StartRip(int trackCount) + { + this._ripTotalTracks += trackCount; + this.IsRipping = true; + this.UpdateMessage(false); + } + + internal void StopRip(int trackCount) + { + this._ripTotalTracks -= trackCount; + if (this._ripCurrentTrack > this._ripTotalTracks) + this.ShowCompletedMessage(RipState.Incomplete); + else + this.UpdateMessage(false); + } + + private void OnRecordProgress(string strSourceUrl, int percentComplete) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this._ripTrackProgress = percentComplete; + this.UpdateMessage(true); + CDAlbumTrack trackBySourceUrl = this.GetTrackBySourceUrl(strSourceUrl); + if (trackBySourceUrl == null) + return; + trackBySourceUrl.RipState = RipState.InProgress; + trackBySourceUrl.PercentComplete = percentComplete; + }, (object)null); + + private void OnRecordStop(string strSourceUrl, int hr) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + ++this._ripCurrentTrack; + this._ripTrackProgress = 0; + bool flag = this._ripCurrentTrack > this._ripTotalTracks; + CDAlbumTrack trackBySourceUrl = this.GetTrackBySourceUrl(strSourceUrl); + RipState ripState = RipState.InLibrary; + if (trackBySourceUrl != null) + { + if ((HRESULT)hr == HRESULT._E_ABORT) + ripState = RipState.Incomplete; + else if (hr < 0) + { + ripState = RipState.Error; + trackBySourceUrl.RipErrorCode = hr; + } + else + { + ripState = RipState.InLibrary; + trackBySourceUrl.RipTrack = false; + if (flag && ZuneShell.DefaultInstance.Management.AutoEjectCD.Value) + trackBySourceUrl.Album.CDDevice.Eject(); + } + trackBySourceUrl.RipState = ripState; + if (flag) + trackBySourceUrl.Album.IsRipping = false; + } + if (flag) + { + this._ripTotalTracks = 0; + this._ripCurrentTrack = 1; + this._ripPercent = 0; + this._ripTrackProgress = 0; + this.ShowCompletedMessage(ripState); + } + else + this.UpdateMessage(false); + }, (object)null); + + public ProgressNotification Notification + { + get => this._ripNotification; + set + { + if (this._ripNotification == value) + return; + this._ripNotification = value; + this.FirePropertyChanged(nameof(Notification)); + } + } + + private void ShowCompletedMessage(RipState ripState) + { + this.IsRipping = false; + if (this._ripNotification != null && this._ripNotification.Type != NotificationState.Completed) + { + this._ripNotification.Type = NotificationState.Completed; + switch (ripState) + { + case RipState.Incomplete: + this._ripNotification.Message = CDAccess._ripCanceledMessage; + break; + case RipState.Error: + this._ripNotification.Message = CDAccess._ripFailedMessage; + break; + default: + this._ripNotification.Message = CDAccess._ripCompleteMessage; + this._ripNotification.Percentage = 100; + break; + } + this._ripNotification.SubMessage = (string)null; + this.Notification = (ProgressNotification)null; + } + SoundHelper.Play(SoundId.RipComplete); + } + + private void UpdateMessage(bool trackProgress) + { + if (this._ripNotification == null) + { + this.Notification = new ProgressNotification(CDAccess._ripProgressMessage, NotificationTask.Rip, NotificationState.Normal, 0); + } + else + { + this._ripNotification.Type = NotificationState.Normal; + this._ripNotification.Message = CDAccess._ripProgressMessage; + } + int num = 0; + if (this._ripTotalTracks != 0) + num = ((this._ripCurrentTrack - 1) * 100 + this._ripTrackProgress) / this._ripTotalTracks; + if (trackProgress && this._ripPercent == num) + return; + this._ripPercent = num; + this._ripNotification.Percentage = num; + this._ripNotification.SubMessage = string.Format(CDAccess._ripCurrentMessage, (object)this._ripCurrentTrack, (object)this._ripTotalTracks); + } + + private CDAlbumTrack GetTrackBySourceUrl(string strSourceUrl) + { + int num1 = strSourceUrl.LastIndexOf('/'); + int num2 = strSourceUrl.LastIndexOf('/', num1 - 1); + int num3 = int.Parse(strSourceUrl.Substring(num1 + 1)); + ZuneLibraryCDDevice zuneLibraryCdDevice = this._cdDeviceList.GetItem(int.Parse(strSourceUrl.Substring(num2 + 1, num1 - num2 - 1))); + for (int itemIndex = 0; itemIndex < this.CDs.Count; ++itemIndex) + { + CDAlbumCommand cd = (CDAlbumCommand)this.CDs[itemIndex]; + if (cd != null && (int)cd.CDDevice.DrivePath == (int)zuneLibraryCdDevice.DrivePath) + return cd.CDDevice.IsMediaLoaded ? cd.GetTrack(num3 - 1) : (CDAlbumTrack)null; + } + return (CDAlbumTrack)null; + } + + private class AutoplayInfo + { + public char DriveLetter; + public CDAction Action; + + public AutoplayInfo(char driveLetter, CDAction action) + { + this.DriveLetter = driveLetter; + this.Action = action; + } + } + + private class ChangeInfo + { + public ZuneLibraryCDDevice Device; + public int Index; + public char DriveLetter; + public bool MediaArrived; + + public ChangeInfo(char driveLetter, bool mediaArrived) + { + this.DriveLetter = driveLetter; + this.MediaArrived = mediaArrived; + } + } + } +} diff --git a/ZuneUI/CDAction.cs b/ZuneUI/CDAction.cs new file mode 100644 index 0000000..50c5f75 --- /dev/null +++ b/ZuneUI/CDAction.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CDAction +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum CDAction + { + None, + Rip, + Play, + } +} diff --git a/ZuneUI/CDAlbumCommand.cs b/ZuneUI/CDAlbumCommand.cs new file mode 100644 index 0000000..7d5b1ae --- /dev/null +++ b/ZuneUI/CDAlbumCommand.cs @@ -0,0 +1,236 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CDAlbumCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class CDAlbumCommand : Node + { + private CDAction _autoPlayAction; + private int _libraryID = -1; + private bool _insertedDuringSession; + private string _TOC; + private bool _isRipping; + private int _ripCount; + private CDAlbumTrack[] _trackList; + private int _trackCount; + private CDAccess _cdAccess; + private ZuneLibraryCDDevice _device; + private BurnableCD _burnCD; + + public CDAlbumCommand(Experience owner, StringId id) + : base(owner, id, (string)null, SQMDataId.DiscTitleClicks) + { + } + + public CDAlbumCommand( + Experience owner, + CDAccess cdAccess, + ZuneLibraryCDDevice device, + bool insertedDuringSession) + : base(owner, (string)null, SQMDataId.DiscTitleClicks) + { + this._cdAccess = cdAccess; + this._device = device; + this._insertedDuringSession = insertedDuringSession; + this._TOC = device.TOC; + } + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + if (!fDisposing) + return; + if (this._burnCD != null) + { + this._burnCD.Dispose(); + this._burnCD = (BurnableCD)null; + } + if (this._device == null) + return; + this._device.Dispose(); + this._device = (ZuneLibraryCDDevice)null; + } + + public int RipCount + { + get => this._ripCount; + private set + { + if (this._ripCount == value) + return; + this._ripCount = value; + if (this._ripCount == 0) + this.IsRipping = false; + this.FirePropertyChanged(nameof(RipCount)); + } + } + + public CDAction AutoPlayAction + { + get => this._autoPlayAction; + internal set + { + if (this._autoPlayAction == value) + return; + this._autoPlayAction = value; + this.FirePropertyChanged(nameof(AutoPlayAction)); + } + } + + public void ClearAutoPlayAction() => this._autoPlayAction = CDAction.None; + + public int TrackCount + { + get => this._trackCount; + set + { + if (this._trackCount == value) + return; + this._trackCount = value; + if (value == 0) + { + this._trackList = (CDAlbumTrack[])null; + this.RipCount = 0; + } + else + { + this._trackList = new CDAlbumTrack[value]; + for (int index = 0; index < value; ++index) + this._trackList[index] = new CDAlbumTrack(this, (uint)index); + } + this.FirePropertyChanged(nameof(TrackCount)); + } + } + + public bool InsertedDuringSession => this._insertedDuringSession; + + public bool IsRipping + { + get => this._isRipping; + set + { + if (this._isRipping == value) + return; + this._isRipping = value; + this.FirePropertyChanged(nameof(IsRipping)); + } + } + + public CDAlbumTrack[] TrackList => this._trackList; + + public ZuneLibraryCDDevice CDDevice => this._device; + + public string TOC => this._TOC; + + public bool IsMediaLoaded => this._device != null && this._device.IsMediaLoaded; + + public bool CanErase => this._device != null && this._device.IsCDRW; + + public bool CanWrite => this._device != null && this._device.IsBlank; + + public BurnableCD BurnCD + { + get + { + if (this._burnCD == null && this._device != null) + this._burnCD = new BurnableCD(this._cdAccess, this._device); + return this._burnCD; + } + } + + public int LibraryID + { + get => this._libraryID; + set + { + if (this._libraryID == value || value == -1) + return; + this._libraryID = value; + this.TrackCount = 0; + this.FirePropertyChanged(nameof(LibraryID)); + } + } + + public CDAlbumTrack GetTrack(int trackIndex) => this._trackList == null ? (CDAlbumTrack)null : this._trackList[trackIndex]; + + public void ToggleRipAll() + { + int trackCount = this.TrackCount; + bool flag = this.RipCount < trackCount; + for (int index = 0; index < trackCount; ++index) + { + CDAlbumTrack track = this.TrackList[index]; + if (track.RipState != RipState.InProgress) + track.RipTrack = flag; + } + } + + internal void AddTrackToRip(CDAlbumTrack track) + { + ++this.RipCount; + if (!this.IsRipping) + return; + if (this._cdAccess.Recorder.AsyncAddRecordingRequest(this.CDDevice, track.TrackIndex) == 0) + track.RipState = RipState.Pending; + this._cdAccess.StartRip(1); + } + + internal void RemoveTrackToRip(CDAlbumTrack track) + { + --this.RipCount; + if (!this.IsRipping || track.RipState != RipState.Pending) + return; + if (this._cdAccess.Recorder.AsyncRemoveRecordingRequest(this.CDDevice, track.TrackIndex) == 0) + track.RipState = RipState.NotInLibrary; + this._cdAccess.StopRip(1); + } + + public void StartRip() + { + if (this.IsRipping || this.RipCount <= 0) + return; + ZuneLibraryCDDevice cdDevice = this.CDDevice; + if (this._cdAccess.Recorder == null || cdDevice == null) + return; + int trackCount = 0; + foreach (CDAlbumTrack track in this.TrackList) + { + if (track.RipTrack) + { + ++trackCount; + if (this._cdAccess.Recorder.AsyncAddRecordingRequest(cdDevice, track.TrackIndex) == 0) + track.RipState = RipState.Pending; + } + } + this._cdAccess.StartRip(trackCount); + this.IsRipping = true; + SQMLog.LogToStream(SQMDataId.RipRecordMode, (uint)ClientConfiguration.Recorder.RecordMode); + } + + public void StopRip() + { + int trackCount = 0; + for (int index = this.TrackList.Length - 1; index >= 0; --index) + { + CDAlbumTrack track = this.TrackList[index]; + if (track.RipTrack) + { + ++trackCount; + if (this._cdAccess.Recorder.AsyncRemoveRecordingRequest(this.CDDevice, track.TrackIndex) == 0) + track.RipState = RipState.Incomplete; + } + } + this._cdAccess.StopRip(trackCount); + this.IsRipping = false; + } + + protected override void Execute(Shell shell) => shell.NavigateToPage((ZunePage)new CDLand(this)); + } +} diff --git a/ZuneUI/CDAlbumTrack.cs b/ZuneUI/CDAlbumTrack.cs new file mode 100644 index 0000000..3f49214 --- /dev/null +++ b/ZuneUI/CDAlbumTrack.cs @@ -0,0 +1,82 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CDAlbumTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class CDAlbumTrack : ModelItem + { + private RipState _ripState = RipState.NotInLibrary; + private bool _ripTrack; + private int _percentComplete; + private uint _trackIndex; + private CDAlbumCommand _album; + private int _ripErrorCode; + + internal CDAlbumTrack(CDAlbumCommand album, uint trackIndex) + { + this._album = album; + this._trackIndex = trackIndex; + } + + public bool RipTrack + { + get => this._ripTrack; + set + { + if (this._ripTrack == value) + return; + this._ripTrack = value; + if (this._ripTrack) + this._album.AddTrackToRip(this); + else + this._album.RemoveTrackToRip(this); + this.FirePropertyChanged(nameof(RipTrack)); + } + } + + public RipState RipState + { + get => this._ripState; + set + { + if (this._ripState == value) + return; + this._ripState = value; + this.FirePropertyChanged(nameof(RipState)); + } + } + + public int PercentComplete + { + get => this._percentComplete; + set + { + if (this._percentComplete == value) + return; + this._percentComplete = value; + this.FirePropertyChanged(nameof(PercentComplete)); + } + } + + public int RipErrorCode + { + get => this._ripErrorCode; + internal set + { + if (this._ripErrorCode == value) + return; + this._ripErrorCode = value; + this.FirePropertyChanged(nameof(RipErrorCode)); + } + } + + public CDAlbumCommand Album => this._album; + + public uint TrackIndex => this._trackIndex; + } +} diff --git a/ZuneUI/CDLand.cs b/ZuneUI/CDLand.cs new file mode 100644 index 0000000..87836ee --- /dev/null +++ b/ZuneUI/CDLand.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CDLand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class CDLand : LibraryPage + { + private string _title = Shell.LoadString(StringId.IDS_NO_CD); + private CDAlbumCommand _album; + private PlaylistContentsPanel _burnListPanel; + + public CDLand(CDAlbumCommand album) + { + this._album = album; + this.PivotPreference = (Node)album; + this.IsRootPage = true; + this.UI = "res://ZuneShellResources!CDView.uix#CDView"; + this.ShowCDIcon = false; + this.ShowDeviceIcon = false; + this.ShowPlaylistIcon = false; + this.ShowNowPlayingBackgroundOnIdle = false; + this.PlaybackContext = PlaybackContext.Music; + this._burnListPanel = new PlaylistContentsPanel((LibraryPage)this); + } + + public override void InvokeSettings() + { + if (this.Album == Shell.MainFrame.Disc.BurnList) + Shell.SettingsFrame.Settings.Software.Invoke(SettingCategories.Burn); + else + Shell.SettingsFrame.Settings.Software.Invoke(SettingCategories.Rip); + } + + public override IPageState SaveAndRelease() => (IPageState)new CDLandPageState((IPage)this); + + protected override void OnDispose(bool disposing) + { + if (disposing) + this._burnListPanel.Dispose(); + base.OnDispose(disposing); + } + + public PlaylistContentsPanel BurnListPanel => this._burnListPanel; + + public CDAlbumCommand Album => this._album; + } +} diff --git a/ZuneUI/CDLandPageState.cs b/ZuneUI/CDLandPageState.cs new file mode 100644 index 0000000..dcc7b63 --- /dev/null +++ b/ZuneUI/CDLandPageState.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CDLandPageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class CDLandPageState : IPageState + { + private CDLand _page; + + public CDLandPageState(IPage page) => this._page = (CDLand)page; + + public IPage RestoreAndRelease() + { + if (this._page.Album != Shell.MainFrame.Disc.BurnList && this._page.Album != Shell.MainFrame.Disc.NoCD && !this._page.Album.IsMediaLoaded) + { + this._page.Dispose(); + return (IPage)null; + } + if (this._page.Album != Shell.MainFrame.Disc.NoCD || !Shell.MainFrame.Disc.HasCD) + return (IPage)this._page; + this._page.Dispose(); + return (IPage)null; + } + + public void Release() => this._page.Release(); + + public bool CanBeTrimmed => true; + } +} diff --git a/ZuneUI/CalculateValue`1.cs b/ZuneUI/CalculateValue`1.cs new file mode 100644 index 0000000..1eb2834 --- /dev/null +++ b/ZuneUI/CalculateValue`1.cs @@ -0,0 +1,10 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CalculateValue`1 +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public delegate T CalculateValue(); +} diff --git a/ZuneUI/CardTypePropertyDescriptor.cs b/ZuneUI/CardTypePropertyDescriptor.cs new file mode 100644 index 0000000..8cc0440 --- /dev/null +++ b/ZuneUI/CardTypePropertyDescriptor.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CardTypePropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + public class CardTypePropertyDescriptor : PropertyDescriptor + { + public CardTypePropertyDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : base(name, multiValueString, unknownString, required) + { + } + + public override string ConvertToString(object value) => value == null ? CreditCardHelper.CardTypeToString(CreditCardType.Unknown) : CreditCardHelper.CardTypeToString((CreditCardType)value); + + public override object ConvertFromString(string value) => (object)CreditCardHelper.CardTypeFromString(value); + + public override bool IsValidInternal(string value) => !StringParserHelper.IsNullOrEmptyOrBlank(value); + } +} diff --git a/ZuneUI/CartItem.cs b/ZuneUI/CartItem.cs new file mode 100644 index 0000000..36603b2 --- /dev/null +++ b/ZuneUI/CartItem.cs @@ -0,0 +1,206 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CartItem +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using System; + +namespace ZuneUI +{ + public class CartItem : ModelItem + { + private string _messagingId; + private string _type; + private string _detailsLink; + private Guid _mediaId; + private EContentType _mediaType; + private string _displayType; + private DataProviderObject _marketplaceItem; + private string _title; + private string _sortTitle; + private string _artistName; + private string _albumTitle; + private bool _availableInMarketplace; + private Command _executeCommand; + private object _extraData; + + public CartItem() + { + this._mediaId = Guid.Empty; + this._albumTitle = string.Empty; + this._title = string.Empty; + this._artistName = string.Empty; + } + + public string MessagingId + { + get => this._messagingId; + set + { + if (!(this._messagingId != value)) + return; + this._messagingId = value; + this.FirePropertyChanged(nameof(MessagingId)); + } + } + + public string Type + { + get => this._type; + set + { + if (!(this._type != value)) + return; + this._type = value; + this.FirePropertyChanged(nameof(Type)); + } + } + + public string DetailsLink + { + get => this._detailsLink; + set + { + if (!(this._detailsLink != value)) + return; + this._detailsLink = value; + this.FirePropertyChanged(nameof(DetailsLink)); + } + } + + public Guid MediaId + { + get => this._mediaId; + set + { + if (!(this._mediaId != value)) + return; + this._mediaId = value; + this.FirePropertyChanged(nameof(MediaId)); + } + } + + public EContentType MediaType + { + get => this._mediaType; + set + { + if (this._mediaType == value) + return; + this._mediaType = value; + this.FirePropertyChanged(nameof(MediaType)); + } + } + + public string DisplayType + { + get => this._displayType; + set + { + if (!(this._displayType != value)) + return; + this._displayType = value; + this.FirePropertyChanged(nameof(DisplayType)); + } + } + + public DataProviderObject MarketplaceItem + { + get => this._marketplaceItem; + set + { + if (this._marketplaceItem == value) + return; + this._marketplaceItem = value; + this.FirePropertyChanged(nameof(MarketplaceItem)); + } + } + + public string Title + { + get => this._title; + set + { + if (!(this._title != value)) + return; + this._title = value; + this.FirePropertyChanged(nameof(Title)); + } + } + + public string SortTitle + { + get => this._sortTitle; + set + { + if (!(this._sortTitle != value)) + return; + this._sortTitle = value; + this.FirePropertyChanged(nameof(SortTitle)); + } + } + + public string ArtistName + { + get => this._artistName; + set + { + if (!(this._artistName != value)) + return; + this._artistName = value; + this.FirePropertyChanged(nameof(ArtistName)); + } + } + + public string AlbumTitle + { + get => this._albumTitle; + set + { + if (!(this._albumTitle != value)) + return; + this._albumTitle = value; + this.FirePropertyChanged(nameof(AlbumTitle)); + } + } + + public bool AvailableInMarketplace + { + get => this._availableInMarketplace; + set + { + if (this._availableInMarketplace == value) + return; + this._availableInMarketplace = value; + this.FirePropertyChanged(nameof(AvailableInMarketplace)); + } + } + + public Command ExecuteCommand + { + get => this._executeCommand; + set + { + if (this._executeCommand == value) + return; + this._executeCommand = value; + this.FirePropertyChanged(nameof(ExecuteCommand)); + } + } + + public object ExtraData + { + get => this._extraData; + set + { + if (this._extraData == value) + return; + this._extraData = value; + this.FirePropertyChanged(nameof(ExtraData)); + } + } + } +} diff --git a/ZuneUI/CartItemSortColumn.cs b/ZuneUI/CartItemSortColumn.cs new file mode 100644 index 0000000..857787f --- /dev/null +++ b/ZuneUI/CartItemSortColumn.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CartItemSortColumn +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum CartItemSortColumn + { + AvailableInMarketplace, + SortTitle, + ArtistName, + DisplayType, + } +} diff --git a/ZuneUI/CartItemsAvailableInMarketplaceComparer.cs b/ZuneUI/CartItemsAvailableInMarketplaceComparer.cs new file mode 100644 index 0000000..8965cfc --- /dev/null +++ b/ZuneUI/CartItemsAvailableInMarketplaceComparer.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CartItemsAvailableInMarketplaceComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class CartItemsAvailableInMarketplaceComparer : CartItemsComparer + { + public CartItemsAvailableInMarketplaceComparer(bool sortAscending) + : base(sortAscending, (GetCartItemPropertyDelegate)null) + { + } + } +} diff --git a/ZuneUI/CartItemsComparer.cs b/ZuneUI/CartItemsComparer.cs new file mode 100644 index 0000000..b38178b --- /dev/null +++ b/ZuneUI/CartItemsComparer.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CartItemsComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + public class CartItemsComparer : IComparer + { + public readonly bool SortAscending; + internal readonly GetCartItemPropertyDelegate PropertyDelegate; + + internal CartItemsComparer(bool sortAscending, GetCartItemPropertyDelegate propertyDelegate) + { + this.SortAscending = sortAscending; + this.PropertyDelegate = propertyDelegate; + } + + public static string GetCartItemSortTitle(CartItem item) => item.SortTitle; + + public static string GetCartItemArtistName(CartItem item) => item.ArtistName; + + public static string GetCartItemDisplayType(CartItem item) => item.DisplayType; + + public int Compare(object x, object y) + { + CartItem cartItem1 = x as CartItem; + CartItem cartItem2 = y as CartItem; + if (cartItem1 == null || cartItem2 == null) + return 0; + int num = ((IComparable)cartItem1.AvailableInMarketplace).CompareTo((object)cartItem2.AvailableInMarketplace); + if (num != 0) + return -num; + if (this.PropertyDelegate != null) + num = string.Compare(this.PropertyDelegate(cartItem1), this.PropertyDelegate(cartItem2)); + return !this.SortAscending ? -num : num; + } + } +} diff --git a/ZuneUI/CartItemsHelper.cs b/ZuneUI/CartItemsHelper.cs new file mode 100644 index 0000000..397eb4b --- /dev/null +++ b/ZuneUI/CartItemsHelper.cs @@ -0,0 +1,62 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CartItemsHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using System.Collections; +using ZuneXml; + +namespace ZuneUI +{ + public class CartItemsHelper + { + public static EContentType ExtractContentType(object obj) + { + EContentType econtentType = EContentType.Unknown; + if (obj is MessageRoot messageRoot) + econtentType = messageRoot.ContentType; + return econtentType; + } + + public static void Sort(ListDataSet list, CartItemSortColumn column, bool sortAscending) + { + if (list == null || list.Count == 0) + return; + IComparer comparer = (IComparer)null; + switch (column) + { + case CartItemSortColumn.AvailableInMarketplace: + comparer = (IComparer)new CartItemsAvailableInMarketplaceComparer(sortAscending); + break; + case CartItemSortColumn.SortTitle: + comparer = (IComparer)new CartItemsComparer(sortAscending, new GetCartItemPropertyDelegate(CartItemsComparer.GetCartItemSortTitle)); + break; + case CartItemSortColumn.ArtistName: + comparer = (IComparer)new CartItemsComparer(sortAscending, new GetCartItemPropertyDelegate(CartItemsComparer.GetCartItemArtistName)); + break; + case CartItemSortColumn.DisplayType: + comparer = (IComparer)new CartItemsComparer(sortAscending, new GetCartItemPropertyDelegate(CartItemsComparer.GetCartItemDisplayType)); + break; + } + if (comparer == null) + return; + ArrayList arrayList = new ArrayList(list.Count); + arrayList.AddRange((ICollection)list); + arrayList.Sort(comparer); + list.Source = (IList)arrayList; + } + + public static void ErrorMessageCartAlreadyFull() => ErrorDialogInfo.Show(HRESULT._NS_E_CART_FULL.Int, Shell.LoadString(StringId.IDS_CART_FULL)); + + public static void ErrorMessageTooManyNewItems() => ErrorDialogInfo.Show(HRESULT._NS_E_CART_TOO_MANY_NEW_ITEMS.Int, Shell.LoadString(StringId.IDS_CART_FULL)); + + public static void ErrorMessageMoreCartItemsAvailable(int extraCartItems) + { + StringId stringId = extraCartItems == 1 ? StringId.IDS_CART_FULL_MORE_DEVICE_ITEMS_SINGULAR : StringId.IDS_CART_FULL_MORE_DEVICE_ITEMS_PLURAL; + ErrorDialogInfo.Show(HRESULT._NS_E_CART_MORE_ITEMS_AVAILABLE.Int, Shell.LoadString(StringId.IDS_CART_FULL), string.Format(Shell.LoadString(stringId), (object)extraCartItems)); + } + } +} diff --git a/ZuneUI/CartNavigationCommandHandler.cs b/ZuneUI/CartNavigationCommandHandler.cs new file mode 100644 index 0000000..e0a7c06 --- /dev/null +++ b/ZuneUI/CartNavigationCommandHandler.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CartNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class CartNavigationCommandHandler : NavigationCommandHandlerBase + { + protected override ZunePage GetPage(IDictionary args) + { + ZunePage zunePage = (ZunePage)new CartPage(); + zunePage.UIPath = this.UIPath; + return zunePage; + } + } +} diff --git a/ZuneUI/CartPage.cs b/ZuneUI/CartPage.cs new file mode 100644 index 0000000..80676b6 --- /dev/null +++ b/ZuneUI/CartPage.cs @@ -0,0 +1,61 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CartPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class CartPage : LibraryPage + { + private Command _refreshPageCommand; + private CartPanel _cartPanel; + private bool _isEmptyCart; + public static readonly string CartPageTemplate = "res://ZuneMarketplaceResources!Cart.uix#CartLibrary"; + + public CartPage() + { + this.PivotPreference = Shell.MainFrame.Marketplace.Cart; + this.IsRootPage = true; + this.UI = CartPage.CartPageTemplate; + this._refreshPageCommand = new Command((IModelItemOwner)this); + this._cartPanel = new CartPanel(this); + } + + public override IPageState SaveAndRelease() + { + if (this.IsEmptyCart) + return (IPageState)null; + if (this.CartPanel.SelectedItem != null) + { + if (this.NavigationArguments == null) + this.NavigationArguments = (IDictionary)new Hashtable(1); + this.NavigationArguments[(object)"MessageId"] = (object)this.CartPanel.SelectedItem.MessagingId; + this.CartPanel.SelectedItem = (CartItem)null; + } + else + this.NavigationArguments = (IDictionary)null; + this._cartPanel.Release(); + return base.SaveAndRelease(); + } + + public CartPanel CartPanel => this._cartPanel; + + public bool IsEmptyCart + { + get => this._isEmptyCart; + set + { + if (this._isEmptyCart == value) + return; + this._isEmptyCart = value; + this.FirePropertyChanged(nameof(IsEmptyCart)); + } + } + + public Command RefreshPageCommand => this._refreshPageCommand; + } +} diff --git a/ZuneUI/CartPanel.cs b/ZuneUI/CartPanel.cs new file mode 100644 index 0000000..5baff68 --- /dev/null +++ b/ZuneUI/CartPanel.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CartPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class CartPanel : LibraryPanel + { + private CartItem _selectedItem; + + public CartPanel(CartPage page) + : base((IModelItemOwner)page) + { + } + + public CartItem SelectedItem + { + get => this._selectedItem; + set + { + if (this._selectedItem == value) + return; + this._selectedItem = value; + this.FirePropertyChanged(nameof(SelectedItem)); + } + } + } +} diff --git a/ZuneUI/Category.cs b/ZuneUI/Category.cs new file mode 100644 index 0000000..96c4621 --- /dev/null +++ b/ZuneUI/Category.cs @@ -0,0 +1,49 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Category +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class Category : ModelItem + { + private string _target; + private bool _allowScrolling; + private SQMDataId _sqmCountID; + + public Category(StringId titleID, string target) + : this(titleID, target, true, SQMDataId.Invalid) + { + } + + public Category(StringId titleID, string target, bool allowScrolling) + : this(titleID, target, allowScrolling, SQMDataId.Invalid) + { + this._target = target; + this._allowScrolling = allowScrolling; + } + + public Category(StringId titleID, string target, bool allowScrolling, SQMDataId sqmCountID) + : base((IModelItemOwner)null, Shell.LoadString(titleID)) + { + this._target = target; + this._allowScrolling = allowScrolling; + this._sqmCountID = sqmCountID; + } + + public string Target => this._target; + + public bool AllowScrolling => this._allowScrolling; + + public void LogCategoryView() + { + if (this._sqmCountID == SQMDataId.Invalid) + return; + SQMLog.Log(this._sqmCountID, 1); + } + } +} diff --git a/ZuneUI/CategoryPage.cs b/ZuneUI/CategoryPage.cs new file mode 100644 index 0000000..2538c5a --- /dev/null +++ b/ZuneUI/CategoryPage.cs @@ -0,0 +1,328 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CategoryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using UIXControls; + +namespace ZuneUI +{ + public class CategoryPage : DialogPage + { + private int _currentMenuItemIndex; + private bool _isWizard; + private bool _allowAdvance = true; + private bool _allowCancel = true; + private bool _requireSecurityIcon; + private bool _isMenuDisabled; + private Choice _menu; + private CategoryPageNode _node; + private Category _currentCategory; + private static bool _inSettings = false; + private static CategoryPage _entryPage; + private bool _hideDeviceOnCancel; + + internal static CategoryPage EntryPage => CategoryPage._entryPage; + + public CategoryPage(CategoryPageNode node) + { + this.UI = "res://ZuneShellResources!Management.uix"; + this.BackgroundUI = "res://ZuneShellResources!Management.uix#Background"; + this.TransportControlStyle = TransportControlStyle.None; + this.PivotPreference = (Node)node; + this.ShowCDIcon = false; + this.ShowDeviceIcon = false; + this.ShowPlaylistIcon = false; + this.ShowSettings = false; + this.ShowSearch = false; + this.ShowNowPlayingBackgroundOnIdle = false; + this.CanEnterCompactMode = false; + this.NotificationAreaVisible = false; + this.TransportControlsVisible = false; + if (CategoryPage._entryPage == null) + CategoryPage._entryPage = this; + this._node = node; + if (node.Experience == Shell.SettingsFrame.Wizard) + this._isWizard = true; + this._hideDeviceOnCancel = node.HideDeviceOnCancel; + this._menu = new Choice((IModelItemOwner)this); + this._menu.Options = node.Categories; + this._menu.ChosenChanged += new EventHandler(this.CurrentCategoryChosenChanged); + this.ShowBackArrow = node.AllowBackNavigation; + } + + protected override void OnDispose(bool disposing) + { + if (disposing && this._menu != null) + { + this._menu.ChosenChanged -= new EventHandler(this.CurrentCategoryChosenChanged); + this._menu.Dispose(); + this._menu = (Choice)null; + } + base.OnDispose(disposing); + } + + private void CurrentCategoryChosenChanged(object sender, EventArgs args) => this.CurrentCategory = (Category)this.Menu.ChosenValue; + + public Choice Menu => this._menu; + + public Category CurrentCategory + { + get => this._currentCategory; + set + { + if (ZuneShell.DefaultInstance.NavigationLocked) + { + ZuneShell.DefaultInstance.DeferredNavigateCategory = value; + ZuneShell.DefaultInstance.BlockedByNavigationLock = true; + } + else + { + if (this._currentCategory == value) + return; + this._currentCategory = value; + int num = this._menu.Options.IndexOf((object)value); + if (num != -1) + { + this._menu.ChosenIndex = num; + this.CurrentMenuItemIndex = num; + } + this.FirePropertyChanged(nameof(CurrentCategory)); + } + } + } + + public void ReleaseDeferredNavigation() + { + ZuneShell defaultInstance = ZuneShell.DefaultInstance; + if (defaultInstance.DeferredNavigateCategory != null) + { + Category navigateCategory = defaultInstance.DeferredNavigateCategory; + defaultInstance.DeferredNavigateCategory = (Category)null; + this.CurrentCategory = navigateCategory; + } + else + { + if (defaultInstance.DeferredNavigateNode == null) + return; + Node deferredNavigateNode = defaultInstance.DeferredNavigateNode; + defaultInstance.DeferredNavigateNode = (Node)null; + deferredNavigateNode.Invoke(); + } + } + + protected override void OnNavigatedAwayWorker(IPage destination) + { + base.OnNavigatedAwayWorker(destination); + if (ZuneShell.DefaultInstance == null) + return; + Management management = ZuneShell.DefaultInstance.Management; + management.RemoveNSSDeviceListChangeEvent(); + management.CurrentCategoryPage = (CategoryPage)null; + } + + protected override void OnNavigatedToWorker() + { + if (this.NavigationArguments != null && this.NavigationArguments.Contains((object)"Host")) + { + this._menu.ChosenValue = (object)(Category)this.NavigationArguments[(object)"Host"]; + this.NavigationArguments.Remove((object)"Host"); + } + ZuneShell.DefaultInstance.Management.CurrentCategoryPage = this; + if (!CategoryPage._inSettings) + { + CategoryPage._inSettings = true; + this.PauseSyncIfNecessary(); + } + base.OnNavigatedToWorker(); + } + + public override IPageState SaveAndRelease() => (IPageState)new CategoryPageState((IPage)this); + + public override bool HandleBack() + { + bool flag = CategoryPage._entryPage == this; + if (flag && ZuneShell.DefaultInstance.Management.HasPendingCommits) + { + Command yesCommand = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_DIALOG_YES), (EventHandler)null); + yesCommand.Invoked += (EventHandler)((sender, args) => this.SaveAndExit()); + Command noCommand = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_DIALOG_NO), (EventHandler)null); + noCommand.Invoked += (EventHandler)((sender, args) => this.CancelAndExit()); + MessageBox.Show(Shell.LoadString(StringId.IDS_SAVE_CHANGES_DIALOG_TITLE), Shell.LoadString(StringId.IDS_SAVE_CHANGES_ON_BACK_DIALOG_TEXT), yesCommand, noCommand, (BooleanChoice)null); + return true; + } + if (!flag) + return false; + CategoryPage._entryPage = (CategoryPage)null; + this.CancelAndExit(); + return true; + } + + public override bool HandleEscape() + { + ZuneShell.DefaultInstance.NavigateBack(); + return true; + } + + public bool InFUE => this._node == Shell.SettingsFrame.Wizard.FUE; + + public bool InDeviceSettings => this._node == Shell.SettingsFrame.Settings.Device; + + public bool MenuDisabled + { + get => this._isMenuDisabled; + set + { + if (value == this._isMenuDisabled) + return; + this._isMenuDisabled = value; + this.FirePropertyChanged(nameof(MenuDisabled)); + } + } + + public override bool IsWizard => this._isWizard; + + public bool MenuItemsAvailable => this._menu != null; + + private int CurrentMenuItemIndex + { + get => this._currentMenuItemIndex; + set + { + if (this._currentMenuItemIndex == value) + return; + this._currentMenuItemIndex = value; + this.AllowAdvance = true; + } + } + + public override bool AllowAdvance + { + get => this._allowAdvance; + set + { + if (this._allowAdvance == value) + return; + this._allowAdvance = value; + this.FirePropertyChanged(nameof(AllowAdvance)); + } + } + + public override bool AllowCancel + { + get => this._allowCancel; + set + { + if (this._allowCancel == value) + return; + this._allowCancel = value; + this.FirePropertyChanged(nameof(AllowCancel)); + } + } + + public override bool RequireSecurityIcon + { + get => this._requireSecurityIcon; + set + { + if (this._requireSecurityIcon == value) + return; + this._requireSecurityIcon = value; + this.FirePropertyChanged(nameof(RequireSecurityIcon)); + } + } + + public override void NavigatePage(bool forward) + { + if (this.Menu.Options.Count == 1) + return; + if (forward) + ++this.CurrentMenuItemIndex; + else + --this.CurrentMenuItemIndex; + this.Menu.ChosenValue = this.Menu.Options[this.CurrentMenuItemIndex]; + } + + public override bool NavigationAvailable(bool forward) + { + if (!this.IsWizard) + return false; + return forward ? this._currentMenuItemIndex < this.Menu.Options.Count - 1 : this._currentMenuItemIndex > 0; + } + + public override void Save() + { + ZuneShell.DefaultInstance.Management.CommitListSave(); + ZuneShell.DefaultInstance.Management.DeviceManagement.SetupComplete(false); + } + + public override void Exit() + { + CategoryPage._entryPage = (CategoryPage)null; + if (!this.InFUE) + ZuneShell.DefaultInstance.NavigateBack(); + this.RestartSyncIfNecessary(); + CategoryPage._inSettings = false; + DeviceManagement.NavigatingToWizard = false; + if (ZuneShell.DefaultInstance != null) + ZuneShell.DefaultInstance.DisposeManagement(); + ZuneShell.DefaultInstance.NavigationLocked = false; + ZuneShell.DefaultInstance.Management.DeviceManagement.SetupComplete(false); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + DeviceManagement.HandleSetupQueue(); + }, DeferredInvokePriority.Low); + this.CancelAllFirmwareUpdates(); + } + + private void CancelAllFirmwareUpdates() + { + foreach (UIDevice uiDevice in SingletonModelItem.Instance) + { + if (uiDevice.UIFirmwareUpdater != null && uiDevice.UIFirmwareUpdater.IsCheckingForUpdates) + uiDevice.UIFirmwareUpdater.CancelFirmwareUpdate(); + } + } + + public override void SaveAndExit() + { + this.Save(); + this.Exit(); + } + + public override void CancelAndExit() + { + this.Exit(); + if (DeviceManagement.SetupDevice == null || !this._hideDeviceOnCancel && !DeviceManagement.SetupDevice.RequiresFirmwareUpdate) + return; + if (SyncControls.Instance.ChangeIntoSetupDevice) + { + SyncControls.Instance.ChangeIntoSetupDevice = false; + DeviceManagement.SetupDevice = (UIDevice)null; + } + else + DeviceManagement.HideSetupDevice(); + } + + public void PauseSyncIfNecessary() + { + if (DeviceManagement.NavigatingToWizard) + return; + SyncControls.Instance.CurrentDevice.IsLockedAgainstSyncing = true; + } + + public void RestartSyncIfNecessary() + { + UIDevice currentDevice = SyncControls.Instance.CurrentDevice; + if (DeviceManagement.NavigatingToWizard || !currentDevice.IsLockedAgainstSyncing) + return; + currentDevice.IsLockedAgainstSyncing = false; + if (!currentDevice.IsReadyForSync) + return; + currentDevice.BeginSync(true, false); + } + } +} diff --git a/ZuneUI/CategoryPageNode.cs b/ZuneUI/CategoryPageNode.cs new file mode 100644 index 0000000..7e5a67d --- /dev/null +++ b/ZuneUI/CategoryPageNode.cs @@ -0,0 +1,72 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CategoryPageNode +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class CategoryPageNode : Node + { + private IList _categories; + private bool _allowBackNavigation = true; + private bool _hideDeviceOnCancel = true; + + public CategoryPageNode( + Experience owner, + StringId id, + IList categories, + SQMDataId sqmDataID, + bool allowBackNavigation, + bool hideDeviceOnCancel) + : base(owner, id, (string)null, sqmDataID) + { + this._allowBackNavigation = allowBackNavigation; + this._hideDeviceOnCancel = hideDeviceOnCancel; + bool flag = false; + foreach (Category category in (IEnumerable)categories) + { + if (category == null) + flag = true; + } + if (flag) + { + List categoryList = new List(categories.Count); + foreach (Category category in (IEnumerable)categories) + { + if (category != null) + categoryList.Add(category); + } + categories = (IList)categoryList.ToArray(); + } + this._categories = categories; + } + + protected override void Execute(Shell shell) => this.Invoke((Category)this._categories[0], (IDictionary)null); + + public void Invoke(Category category) => this.Invoke(category, (IDictionary)null); + + public void Invoke(Category category, IDictionary commandArgs) + { + ZuneShell defaultInstance = ZuneShell.DefaultInstance; + if (defaultInstance == null) + throw new InvalidOperationException("No Shell instance has been registered. Unable to perform navigation."); + CategoryPage categoryPage = new CategoryPage(this); + categoryPage.CurrentCategory = category; + if (commandArgs != null) + categoryPage.NavigationArguments = commandArgs; + defaultInstance.NavigateToPage((ZunePage)categoryPage); + } + + public IList Categories => this._categories; + + public bool AllowBackNavigation => this._allowBackNavigation; + + public bool HideDeviceOnCancel => this._hideDeviceOnCancel; + } +} diff --git a/ZuneUI/CategoryPageState.cs b/ZuneUI/CategoryPageState.cs new file mode 100644 index 0000000..8c8f058 --- /dev/null +++ b/ZuneUI/CategoryPageState.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CategoryPageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class CategoryPageState : IPageState + { + private IPage _page; + + public CategoryPageState(IPage page) => this._page = page; + + public IPage RestoreAndRelease() + { + if (CategoryPage.EntryPage != null) + return this._page; + this.Release(); + return (IPage)null; + } + + public void Release() => this._page.Release(); + + public bool CanBeTrimmed => true; + } +} diff --git a/ZuneUI/ChannelDetailsPanel.cs b/ZuneUI/ChannelDetailsPanel.cs new file mode 100644 index 0000000..3d60a85 --- /dev/null +++ b/ZuneUI/ChannelDetailsPanel.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ChannelDetailsPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class ChannelDetailsPanel : LibraryPanel + { + public ChannelDetailsPanel(ChannelLibraryPage page) + : base((IModelItemOwner)page) + { + } + } +} diff --git a/ZuneUI/ChannelEpisodePanel.cs b/ZuneUI/ChannelEpisodePanel.cs new file mode 100644 index 0000000..cfce872 --- /dev/null +++ b/ZuneUI/ChannelEpisodePanel.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ChannelEpisodePanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ChannelEpisodePanel : SubscriptionEpisodePanel + { + public ChannelEpisodePanel(ChannelLibraryPage page) + : base((SubscriptionLibraryPage)page) + { + } + + public override SyncCategory SyncCategory => SyncCategory.Channel; + } +} diff --git a/ZuneUI/ChannelLibraryPage.cs b/ZuneUI/ChannelLibraryPage.cs new file mode 100644 index 0000000..3945d70 --- /dev/null +++ b/ZuneUI/ChannelLibraryPage.cs @@ -0,0 +1,77 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ChannelLibraryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Playlist; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class ChannelLibraryPage : SubscriptionLibraryPage + { + private static string _saveAsPlaylistMessageSuccess = Shell.LoadString(StringId.IDS_CHANNEL_SAVE_PLAYLIST_SUCCESS); + private static string _saveAsPlaylistMessageFailure = Shell.LoadString(StringId.IDS_CHANNEL_SAVE_PLAYLIST_FAILURE); + + public ChannelLibraryPage() + : this(false) + { + } + + public ChannelLibraryPage(bool showDevice) + : base(showDevice, MediaType.Playlist) + { + if (showDevice) + { + this.PivotPreference = Shell.MainFrame.Device.Channels; + Deviceland.InitDevicePage((ZunePage)this); + this.ShowComputerIcon = ComputerIconState.Show; + } + else + { + this.DetailsPanel = (LibraryPanel)new ChannelDetailsPanel(this); + this.PivotPreference = Shell.MainFrame.Collection.Channels; + } + this.IsRootPage = true; + this.UIPath = "Collection\\Channels"; + this.SeriesPanel = (SubscriptionSeriesPanel)new ChannelSeriesPanel(this); + this.EpisodePanel = (SubscriptionEpisodePanel)new ChannelEpisodePanel(this); + this.TransportControlStyle = TransportControlStyle.Music; + this.PlaybackContext = PlaybackContext.Music; + } + + protected override string LandUI => "res://ZuneShellResources!ChannelLibrary.uix#ChannelLibrary"; + + protected override EMediaTypes SeriesMediaType => EMediaTypes.eMediaTypePlaylist; + + protected override EListType SeriesListType => EListType.ePlaylistList; + + protected override StringId SubscriptionErrorStringId => StringId.IDS_PLAYLIST_SUBSCRIPTION_ERROR; + + public static Guid GetZuneMediaId(int seriesId) => SubscriptionLibraryPage.GetZuneMediaId(seriesId, EListType.ePlaylistList); + + public static void FindInCollection(int seriesId) => ChannelLibraryPage.FindInCollection(seriesId, -1); + + public static void FindInCollection(int seriesId, int libraryId) + { + if (seriesId <= 0 && libraryId <= 0) + return; + Hashtable hashtable = new Hashtable(); + if (seriesId > 0) + hashtable.Add((object)"SeriesLibraryId", (object)seriesId); + if (libraryId > 0) + hashtable.Add((object)"EpisodeLibraryId", (object)libraryId); + ZuneShell.DefaultInstance.Execute("Collection\\Channels", (IDictionary)hashtable); + } + + public static void SaveAsPlaylist(int playlistId) => PlaylistManager.Instance.SavePlaylistAsStatic(playlistId, new PlaylistAsyncOperationCompleted(ChannelLibraryPage.SaveAsPlaylistCompleted)); + + public static void SaveAsPlaylistCompleted(HRESULT hr) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + NotificationArea.Instance.Add((Notification)new MessageNotification(!hr.IsSuccess ? ChannelLibraryPage._saveAsPlaylistMessageFailure : ChannelLibraryPage._saveAsPlaylistMessageSuccess, NotificationTask.Library, NotificationState.Completed)); + }, (object)null); + } +} diff --git a/ZuneUI/ChannelSeriesPanel.cs b/ZuneUI/ChannelSeriesPanel.cs new file mode 100644 index 0000000..63725e3 --- /dev/null +++ b/ZuneUI/ChannelSeriesPanel.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ChannelSeriesPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ChannelSeriesPanel : SubscriptionSeriesPanel + { + public ChannelSeriesPanel(ChannelLibraryPage page) + : base((SubscriptionLibraryPage)page) + { + } + + public override SyncCategory SyncCategory => SyncCategory.Channel; + } +} diff --git a/ZuneUI/ChannelTrackActionCommand.cs b/ZuneUI/ChannelTrackActionCommand.cs new file mode 100644 index 0000000..2bf17db --- /dev/null +++ b/ZuneUI/ChannelTrackActionCommand.cs @@ -0,0 +1,85 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ChannelTrackActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; + +namespace ZuneUI +{ + public class ChannelTrackActionCommand : MarketplaceActionCommand + { + private bool _lastSignedInUserHadActiveSubscription; + + public ChannelTrackActionCommand() + { + this.ShowHiddenProgress = true; + SignIn.Instance.SignInStatusUpdatedEvent += new EventHandler(this.OnSignInEvent); + } + + protected override EContentType ContentType => EContentType.MusicTrack; + + public override void UpdateState() + { + this.Progress = -1f; + this.Downloading = false; + this._lastSignedInUserHadActiveSubscription = SignIn.Instance.LastSignedInUserHadActiveSubscription; + bool fIsDownloadPending = false; + bool fIsHidden = false; + this.CollectionId = (int)this.Model.GetProperty("MediaId"); + if (this.CanAddToCollection) + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_ADD_TO_COLLECTION); + this.Available = true; + } + else if (this.CanFindInCollection) + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_INCOLLECTION); + this.Available = true; + } + else if (ZuneApplication.Service.IsDownloading(this.Id, EContentType.MusicTrack, out fIsDownloadPending, out fIsHidden)) + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_PENDING); + this.Downloading = true; + this.Available = true; + } + else if (this.CanDownload) + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD); + this.Available = true; + } + else if (this.CanPurchase) + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_BUTTON); + this.Available = true; + } + else + this.Available = false; + } + + public override bool CanFindInCollection => PlaylistManager.IsInVisibleCollection(this.CollectionId, MediaType.Track); + + public override void FindInCollection() => MusicLibraryPage.FindInCollection(-1, -1, this.CollectionId); + + public bool CanAddToCollection => this._lastSignedInUserHadActiveSubscription && ZuneApplication.Service.InHiddenCollection(this.Id, EContentType.MusicTrack); + + public bool CanDownload => this._lastSignedInUserHadActiveSubscription && !this.CanFindInCollection && (!this.CanAddToCollection && !this.Downloading) && this.Id != Guid.Empty && Download.Instance.GetErrorCode(this.Id) != HRESULT._ZUNE_E_NO_SUBSCRIPTION_DOWNLOAD_RIGHTS.Int; + + public bool CanPurchase => this.Id != Guid.Empty; + + protected override string ZuneMediaIdPropertyName => "ZuneMediaId"; + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + if (!fDisposing) + return; + SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignInEvent); + } + + private void OnSignInEvent(object sender, EventArgs args) => this.UpdateState(); + } +} diff --git a/ZuneUI/ChannelsNavigationCommandHandler.cs b/ZuneUI/ChannelsNavigationCommandHandler.cs new file mode 100644 index 0000000..5959823 --- /dev/null +++ b/ZuneUI/ChannelsNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ChannelsNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class ChannelsNavigationCommandHandler : DeviceAwareNavigationHandler + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new ChannelLibraryPage(this.ShowDeviceContents); + } +} diff --git a/ZuneUI/ClientUpdate.cs b/ZuneUI/ClientUpdate.cs new file mode 100644 index 0000000..f0991eb --- /dev/null +++ b/ZuneUI/ClientUpdate.cs @@ -0,0 +1,38 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ClientUpdate +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class ClientUpdate : ModelItem + { + private object mylock = new object(); + private static ClientUpdate singletonInstance; + + public static ClientUpdate Instance + { + get + { + if (ClientUpdate.singletonInstance == null) + ClientUpdate.singletonInstance = new ClientUpdate(); + return ClientUpdate.singletonInstance; + } + } + + private ClientUpdate() + { + } + + public void InvokeClientUpdate() + { + SoftwareUpdates.Instance.InstallUpdates(); + DeviceManagement.SetupDevice = (UIDevice)null; + } + + public void ClientUpdateSkipped() => DeviceManagement.HideSetupDevice(); + } +} diff --git a/ZuneUI/CollectionExperience.cs b/ZuneUI/CollectionExperience.cs new file mode 100644 index 0000000..e062ad9 --- /dev/null +++ b/ZuneUI/CollectionExperience.cs @@ -0,0 +1,168 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CollectionExperience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Util; +using System.Collections; + +namespace ZuneUI +{ + public class CollectionExperience : Experience + { + private ArrayListDataSet _nodes; + private Node _music; + private Node _videos; + private Node _photos; + private Node _podcasts; + private Node _channels; + private Node _applications; + private Node _radio; + private Node _downloads; + private bool _isDevice; + + public CollectionExperience(Frame frameOwner) + : base(frameOwner, StringId.IDS_COLLECTION_PIVOT, SQMDataId.CollectionClicks) + { + } + + public CollectionExperience(Frame frameOwner, bool isDevice) + : base(frameOwner, StringId.IDS_DEVICE_PIVOT, SQMDataId.DeviceClicks) + => this._isDevice = isDevice; + + public override IList NodesList + { + get + { + if (this._nodes == null) + { + this._nodes = new ArrayListDataSet((IModelItemOwner)this); + this._nodes.Add((object)this.Music); + this._nodes.Add((object)this.Videos); + this._nodes.Add((object)this.Photos); + this._nodes.Add((object)this.Podcasts); + if (FeatureEnablement.IsFeatureEnabled(Features.eChannels)) + this._nodes.Add((object)this.Channels); + if (FeatureEnablement.IsFeatureEnabled(Features.eRadio)) + this._nodes.Add((object)this.Radio); + this.UpdateApplicationPivot(); + } + return (IList)this._nodes; + } + } + + public Node Music + { + get + { + if (this._music == null) + this._music = new Node((Experience)this, StringId.IDS_MUSIC_PIVOT, this._isDevice ? "Device\\Music" : "Collection\\Music\\Default", this._isDevice ? SQMDataId.DeviceMusicClicks : SQMDataId.CollectionMusicClicks); + return this._music; + } + } + + public Node Videos + { + get + { + if (this._videos == null) + this._videos = new Node((Experience)this, StringId.IDS_VIDEO_PIVOT, this._isDevice ? "Device\\Videos" : "Collection\\Videos\\Default", this._isDevice ? SQMDataId.DeviceVideoClicks : SQMDataId.CollectionVideoClicks); + return this._videos; + } + } + + public Node Photos + { + get + { + if (this._photos == null) + this._photos = new Node((Experience)this, StringId.IDS_PICTURES_PIVOT, this._isDevice ? "Device\\Photos" : "Collection\\Photos", this._isDevice ? SQMDataId.DevicePicturesClicks : SQMDataId.CollectionPicturesClicks); + return this._photos; + } + } + + public Node Podcasts + { + get + { + if (this._podcasts == null) + this._podcasts = new Node((Experience)this, StringId.IDS_PODCASTS_PIVOT, this._isDevice ? "Device\\Podcasts" : "Collection\\Podcasts", this._isDevice ? SQMDataId.DevicePodcastsClicks : SQMDataId.CollectionPodcastsClicks); + return this._podcasts; + } + } + + public Node Channels + { + get + { + if (this._channels == null) + this._channels = new Node((Experience)this, StringId.IDS_CHANNELS_PIVOT, this._isDevice ? "Device\\Channels" : "Collection\\Channels", this._isDevice ? SQMDataId.DeviceChannelsClicks : SQMDataId.CollectionChannelsClicks); + return this._channels; + } + } + + public Node Applications + { + get + { + if (this._applications == null) + this._applications = new Node((Experience)this, StringId.IDS_APPS_PIVOT, this._isDevice ? "Device\\Applications" : "Collection\\Applications", SQMDataId.Invalid); + return this._applications; + } + } + + public Node Radio + { + get + { + if (this._radio == null) + this._radio = new Node((Experience)this, StringId.IDS_RADIO_PIVOT, this._isDevice ? "Device\\Radio" : "Collection\\Radio", SQMDataId.Invalid); + return this._radio; + } + } + + public Node Downloads + { + get + { + if (this._downloads == null) + this._downloads = new Node((Experience)this, StringId.IDS_DOWNLOADS_PIVOT, "Collection\\Downloads", SQMDataId.MarketplaceDownloadsClicks); + return this._downloads; + } + } + + public void UpdateApplicationPivot() + { + if (FeatureEnablement.IsFeatureEnabled(Features.eGames) && ClientConfiguration.Shell.ShowApplicationPivot) + { + if (this.NodesList.Contains((object)this.Applications)) + return; + this.NodesList.Add((object)this.Applications); + } + else + { + if (!this.NodesList.Contains((object)this.Applications)) + return; + this.NodesList.Remove((object)this.Applications); + } + } + + public void UpdateDownloadPivot(bool show) + { + int nodeIndex = this.GetNodeIndex(this.Downloads); + bool flag = nodeIndex != -1; + if (show == flag) + return; + this.Downloads.Available = show; + if (show) + this.NodesList.Add((object)this.Downloads); + else + this.NodesList.RemoveAt(nodeIndex); + } + + public override string DefaultUIPath => "Collection\\Default"; + } +} diff --git a/ZuneUI/CollectionPlaylistAttachment.cs b/ZuneUI/CollectionPlaylistAttachment.cs new file mode 100644 index 0000000..d93404e --- /dev/null +++ b/ZuneUI/CollectionPlaylistAttachment.cs @@ -0,0 +1,103 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CollectionPlaylistAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Messaging; +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class CollectionPlaylistAttachment : PropertySetAttachment + { + public const string RequestTypeString = "playlist"; + private PlaylistMessageData m_playlistData; + private IList m_tracks; + private int m_mediaId; + + public CollectionPlaylistAttachment( + string author, + string title, + string imageUri, + int mediaId, + IList tracks) + : base(Guid.Empty, title, author, imageUri) + { + this.AttachmentUI = "res://ZuneShellResources!SocialComposer.uix#CollectionPlaylistAttachmentUI"; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_PLAYLIST_ATTACHMENT); + this.AllowEmailRecipients = false; + this.m_tracks = tracks; + this.m_mediaId = mediaId; + } + + protected override void FirePropertyChanged(string propertyName) + { + if (propertyName == "Subtitle") + this.FirePropertyChanged("Author"); + if (propertyName == "Title" || propertyName == "Subtitle") + { + this.m_playlistData = (PlaylistMessageData)null; + this.FirePropertyChanged("PropertySet"); + } + base.FirePropertyChanged(propertyName); + } + + public override MediaType MediaType => MediaType.Playlist; + + public override string RequestType => "playlist"; + + public override string[] Properties => new string[0]; + + public override IPropertySetMessageData PropertySet + { + get + { + if (this.m_playlistData == null) + this.m_playlistData = new PlaylistMessageData(this.Title, this.Author, this.Tracks); + return (IPropertySetMessageData)this.m_playlistData; + } + } + + public string Author + { + get => this.Subtitle; + set => this.Subtitle = value; + } + + public int MediaId => this.m_mediaId; + + public IList Tracks + { + get => this.m_tracks; + set + { + if (this.m_tracks == value) + return; + this.m_tracks = value; + this.FirePropertyChanged(nameof(Tracks)); + this.FirePropertyChanged("IsReady"); + } + } + + public override bool IsReady => this.Tracks != null; + + public override void LogSend() => SQMLog.Log(SQMDataId.InboxMessageSendUserPlaylist, 1); + + public override bool IsValid(out string errorMessage) + { + bool flag = true; + errorMessage = (string)null; + int num = ClientConfiguration.Messaging.MaxSubMessagesPerMessage * ClientConfiguration.Messaging.MaxTracksPerMessage; + if (this.m_tracks != null && this.m_tracks.Count > num) + { + flag = false; + errorMessage = string.Format(Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_ERROR_TOO_MANY_TRACKS), (object)num); + } + return flag; + } + } +} diff --git a/ZuneUI/CollectionRadioPanel.cs b/ZuneUI/CollectionRadioPanel.cs new file mode 100644 index 0000000..7b7ba1f --- /dev/null +++ b/ZuneUI/CollectionRadioPanel.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CollectionRadioPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class CollectionRadioPanel : ListPanel + { + public CollectionRadioPanel(RadioPage page) + : base((IModelItemOwner)page) + { + } + } +} diff --git a/ZuneUI/CommandHandler.cs b/ZuneUI/CommandHandler.cs new file mode 100644 index 0000000..bd88eba --- /dev/null +++ b/ZuneUI/CommandHandler.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class CommandHandler : Command, ICommandHandler + { + private IDictionary _arguments; + + public IDictionary Arguments => this._arguments; + + public void Execute(string command, IDictionary commandArgs) + { + this._arguments = commandArgs; + this.Invoke(); + } + } +} diff --git a/ZuneUI/CommandHandlerBase.cs b/ZuneUI/CommandHandlerBase.cs new file mode 100644 index 0000000..447ef7a --- /dev/null +++ b/ZuneUI/CommandHandlerBase.cs @@ -0,0 +1,38 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CommandHandlerBase +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class CommandHandlerBase : ICommandHandler + { + private IDictionary _arguments; + private ICommand _executeCommand; + + public IDictionary Arguments => this._arguments; + + public ICommand ExecuteCommand + { + get => this._executeCommand; + set + { + if (this._executeCommand == value) + return; + this._executeCommand = value; + } + } + + public void Execute(string command, IDictionary commandArgs) + { + this._arguments = commandArgs; + if (this._executeCommand == null) + return; + this._executeCommand.Invoke(); + } + } +} diff --git a/ZuneUI/CommandStringExtractorList.cs b/ZuneUI/CommandStringExtractorList.cs new file mode 100644 index 0000000..04e64d9 --- /dev/null +++ b/ZuneUI/CommandStringExtractorList.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CommandStringExtractorList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class CommandStringExtractorList : StringExtractorList + { + public CommandStringExtractorList() + { + } + + public CommandStringExtractorList(IList source) + : this() + => this.Source = source; + + protected override string ExtractString(object item) => ((ModelItem)item).Description; + } +} diff --git a/ZuneUI/CommentHelper.cs b/ZuneUI/CommentHelper.cs new file mode 100644 index 0000000..70215ed --- /dev/null +++ b/ZuneUI/CommentHelper.cs @@ -0,0 +1,134 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CommentHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Messaging; +using Microsoft.Zune.Service; +using System; +using System.Text; + +namespace ZuneUI +{ + public class CommentHelper : NotifyPropertyChangedImpl + { + private string _author; + private string _message; + private DateTime _updated; + private Guid _commentId; + private bool _pendingAddComplete; + + public bool AddingComment + { + get => this._pendingAddComplete; + private set + { + if (this._pendingAddComplete == value) + return; + this._pendingAddComplete = value; + this.FirePropertyChanged(nameof(AddingComment)); + } + } + + public string CommentMessage + { + get => this._message; + private set + { + if (!(this._message != value)) + return; + this._message = value; + this.FirePropertyChanged(nameof(CommentMessage)); + } + } + + public Guid CommentId + { + get => this._commentId; + private set + { + if (!(this._commentId != value)) + return; + this._commentId = value; + this.FirePropertyChanged(nameof(CommentId)); + } + } + + public string CommentAuthor + { + get => this._author; + private set + { + if (!(this._author != value)) + return; + this._author = value; + this.FirePropertyChanged(nameof(CommentAuthor)); + } + } + + public DateTime CommentUpdated + { + get => this._updated; + private set + { + if (!(this._updated != value)) + return; + this._updated = value; + this.FirePropertyChanged(nameof(CommentUpdated)); + } + } + + public void AddComment(string recipient, string message) + { + if (this.AddingComment || string.IsNullOrEmpty(recipient) || (string.IsNullOrEmpty(message) || !SignIn.Instance.SignedIn)) + return; + this.AddingComment = true; + this.CommentAuthor = SignIn.Instance.ZuneTag; + this.CommentMessage = message; + this.CommentId = Guid.Empty; + this.CommentUpdated = DateTime.UtcNow; + StringBuilder stringBuilder = new StringBuilder(Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_Comments)); + stringBuilder.Append("/members/"); + stringBuilder.Append(Uri.EscapeDataString(recipient)); + stringBuilder.Append("/comments"); + if (MessagingService.Instance.AddComment(stringBuilder.ToString(), recipient, this._message, new CommentCallback(this.OnAddCommentCompleted))) + return; + this.OnAddCommentCompleted(HRESULT._E_FAIL, Guid.Empty); + } + + public void DeleteComment(string profileTag, Guid commentId) + { + if (!(commentId != Guid.Empty) || !SignIn.Instance.SignedIn) + return; + StringBuilder stringBuilder = new StringBuilder(Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_Comments)); + stringBuilder.Append("/members/"); + stringBuilder.Append(Uri.EscapeDataString(profileTag)); + stringBuilder.Append("/comments/"); + stringBuilder.Append(Uri.EscapeDataString(commentId.ToString())); + MessagingService.Instance.DeleteComment(stringBuilder.ToString(), profileTag, (MessagingCallback)null); + } + + private void OnAddCommentCompleted(HRESULT hr, Guid commentId) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnAddCommentCompletedDeferred), (object)new object[2] + { + (object) hr, + (object) commentId + }); + + private void OnAddCommentCompletedDeferred(object args) + { + object[] objArray = (object[])args; + HRESULT hresult = (HRESULT)objArray[0]; + Guid guid = (Guid)objArray[1]; + if (hresult.IsSuccess) + { + this.CommentId = guid; + this.CommentUpdated = DateTime.UtcNow; + } + else + Shell.ShowErrorDialog(hresult.Int, "Error"); + this.AddingComment = false; + } + } +} diff --git a/ZuneUI/CommitListHashtable.cs b/ZuneUI/CommitListHashtable.cs new file mode 100644 index 0000000..11fbddd --- /dev/null +++ b/ZuneUI/CommitListHashtable.cs @@ -0,0 +1,95 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CommitListHashtable +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class CommitListHashtable + { + private Hashtable _hashtable; + + public CommitListHashtable() => this._hashtable = new Hashtable(); + + public void Clear() + { + this._hashtable.Clear(); + ZuneShell.DefaultInstance.Management.HasPendingCommits = false; + } + + public object this[object key] + { + get => this._hashtable[key]; + set + { + this._hashtable[key] = value; + ZuneShell.DefaultInstance.Management.HasPendingCommits = true; + } + } + + public int Count => this._hashtable.Count; + + public bool ContainsKey(object key) => this._hashtable.ContainsKey(key); + + public bool ContainsValue(object value) => this._hashtable.ContainsValue(value); + + public bool ContainsIntValue(int searchValue) + { + foreach (DictionaryEntry dictionaryEntry in (Hashtable)this._hashtable.Clone()) + { + if (dictionaryEntry.Value is int && (int)dictionaryEntry.Value == searchValue) + return true; + } + return false; + } + + public void RemoveByIntValue(int removeValue) + { + foreach (DictionaryEntry dictionaryEntry in (Hashtable)this._hashtable.Clone()) + { + if (dictionaryEntry.Value is int && (int)dictionaryEntry.Value == removeValue) + this._hashtable.Remove(dictionaryEntry.Key); + } + this.CheckForPendingCommits(); + } + + public void RemoveByStringValue(string removeValue) + { + if (removeValue == null) + return; + foreach (DictionaryEntry dictionaryEntry in (Hashtable)this._hashtable.Clone()) + { + if (dictionaryEntry.Value is string && (string)dictionaryEntry.Value == removeValue) + this._hashtable.Remove(dictionaryEntry.Key); + } + this.CheckForPendingCommits(); + } + + public void Remove(object key) + { + if (key == null) + return; + if (key != null) + this._hashtable.Remove(key); + this.CheckForPendingCommits(); + } + + public void Save() + { + Hashtable hashtable = (Hashtable)this._hashtable.Clone(); + this.Clear(); + foreach (DictionaryEntry dictionaryEntry in hashtable) + ((ProxySettingDelegate)dictionaryEntry.Key)(dictionaryEntry.Value); + } + + private void CheckForPendingCommits() + { + if (this._hashtable == null || this._hashtable.Count != 0) + return; + this.Clear(); + } + } +} diff --git a/ZuneUI/ComposerHelper.cs b/ZuneUI/ComposerHelper.cs new file mode 100644 index 0000000..1185497 --- /dev/null +++ b/ZuneUI/ComposerHelper.cs @@ -0,0 +1,413 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ComposerHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.ErrorMapperApi; +using Microsoft.Zune.Messaging; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Text; +using UIXControls; + +namespace ZuneUI +{ + public class ComposerHelper : DialogHelper + { + private const int c_maxMessageLength = 230; + private RecipientHelper _recipientHelper; + private Command _sendFailed; + private Command _sendSucceeded; + private string _message; + private string _serviceContext; + + public ComposerHelper() + { + this._recipientHelper = new RecipientHelper(); + this._sendFailed = new Command(); + this._sendSucceeded = new Command(); + } + + public void ClearState() + { + this._recipientHelper.ClearState(); + this.Message = string.Empty; + } + + public bool Send(Attachment attachment) + { + string endPointUri = Microsoft.Zune.Service.Service.GetEndPointUri(Microsoft.Zune.Service.EServiceEndpointId.SEID_Messaging); + string zuneTag = SignIn.Instance.ZuneTag; + Uri.EscapeDataString(","); + string errorMessage = (string)null; + HRESULT hresult = HRESULT._S_OK; + bool flag = true; + bool wishlist = false; + bool allowEmailRecipients = true; + if (attachment != null) + { + wishlist = attachment.Wishlist; + allowEmailRecipients = attachment.AllowEmailRecipients; + if (!attachment.IsValid(out errorMessage)) + { + flag = false; + hresult = HRESULT._NS_E_MESSAGING_CLIENT_ERROR; + } + } + if (flag && !this.RecipientHelper.ValidateAll(allowEmailRecipients)) + { + flag = false; + hresult = HRESULT._NS_E_MESSAGING_RECIPIENT_ERROR; + errorMessage = this.RecipientHelper.ErrorMessage; + } + if (!SignIn.Instance.SignedIn || string.IsNullOrEmpty(endPointUri) || string.IsNullOrEmpty(zuneTag)) + flag = false; + if (flag) + flag = this.Send(string.Format("{0}/messaging/{1}/send", (object)endPointUri, (object)Uri.EscapeDataString(zuneTag)), attachment, wishlist); + if (!flag) + this.OnSendCompleted(hresult.IsError ? hresult : HRESULT._NS_E_MESSAGING_CLIENT_ERROR, errorMessage, wishlist); + return flag; + } + + private bool Send(string requestUrl, Attachment attachment, bool wishlist) + { + bool flag = false; + if (attachment is PropertySetAttachment) + { + PropertySetAttachment propertySetAttachment = (PropertySetAttachment)attachment; + string recipientString = this.CreateRecipientString(false); + flag = MessagingService.Instance.Compose(requestUrl, this.Message, recipientString, propertySetAttachment.RequestType, propertySetAttachment.PropertySet, new MessagingCallback(this.OnSendCompletedAsync), (object)wishlist); + } + else + { + string strMessage = (string)null; + try + { + strMessage = this.CreateUrlEncodedString(attachment); + } + catch (ArgumentNullException ex) + { + } + if (strMessage != null) + flag = MessagingService.Instance.Compose(requestUrl, strMessage, new MessagingCallback(this.OnSendCompletedAsync), (object)wishlist); + } + if (flag && attachment != null) + attachment.LogSend(); + return flag; + } + + public static bool ManageFriend(FriendAction action, string zuneTag) + { + bool flag = !string.IsNullOrEmpty(zuneTag); + string strPostUrl = (string)null; + if (flag) + { + strPostUrl = ComposerHelper.CreateOperationUri("friends"); + flag = strPostUrl != null; + } + if (flag) + flag = MessagingService.Instance.ManageFriend(action, strPostUrl, zuneTag); + return flag; + } + + public bool ManageFavorites(FavoritesAction action, MediaType mediaType, IList favorites) + { + string str1 = (string)null; + string str2 = (string)null; + string operationUri = ComposerHelper.CreateOperationUri("playlists/BuiltIn-FavoriteTracks"); + bool flag = operationUri != null; + switch (action) + { + case FavoritesAction.Add: + str1 = "add"; + break; + case FavoritesAction.Remove: + str1 = "delete"; + break; + default: + flag = false; + break; + } + if (mediaType == MediaType.Track) + str2 = "track"; + else + flag = false; + if (flag) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append(str1); + stringBuilder.Append(' '); + stringBuilder.Append(str2); + stringBuilder.Append(' '); + for (int index = 0; index < favorites.Count; ++index) + { + if (index > 0) + stringBuilder.Append(','); + stringBuilder.Append(favorites[index].ToString()); + } + flag = MessagingService.Instance.ManageFavorites(action, operationUri, stringBuilder.ToString(), new MessagingCallback(this.OnFavoritesManagementCompletedAsync), (object)new ComposerHelper.FavoritesManagementState(action, favorites.Count)); + } + return flag; + } + + public static bool ManageProfile( + string fieldName, + string fieldValue, + MessagingCallback callback, + object state) + { + bool flag = !string.IsNullOrEmpty(fieldName); + string strProfileUrl = (string)null; + if (flag) + { + strProfileUrl = ComposerHelper.CreateOperationUri(fieldName); + flag = strProfileUrl != null; + } + if (flag) + flag = MessagingService.Instance.ManageProfile(strProfileUrl, fieldValue, callback, state); + return flag; + } + + public static bool ManageProfileImage( + ProfileImage image, + MessagingCallback callback, + object state) + { + bool flag = !string.IsNullOrEmpty(image.TypeName); + string strProfileImageUrl = (string)null; + if (flag) + { + strProfileImageUrl = ComposerHelper.CreateOperationUri(image.TypeName); + flag = strProfileImageUrl != null; + } + if (flag) + flag = image.Image == null ? image.ResourceId != null && MessagingService.Instance.ManageProfileImage(strProfileImageUrl, image.ResourceId, callback, state) : MessagingService.Instance.ManageProfileImage(strProfileImageUrl, (SafeBitmap)image.Image, callback, state); + if (flag) + { + if (image.Type == ProfileImageType.Background) + SQMLog.Log(SQMDataId.SocialEditBackground, 1); + else if (image.Type == ProfileImageType.Tile) + SQMLog.Log(SQMDataId.SocialEditTile, 1); + } + return flag; + } + + public static string CreateOperationUri(string operation) + { + string zuneTagOrGuid = (string)null; + Guid userGuid = SignIn.Instance.UserGuid; + if (!GuidHelper.IsEmpty(userGuid)) + zuneTagOrGuid = userGuid.ToString(); + return ComposerHelper.CreateOperationUri(operation, zuneTagOrGuid); + } + + public static string GetUserTileUri(string zuneTag) => ComposerHelper.CreateOperationUri("usertile", zuneTag); + + public static string CreateOperationUri(string operation, string zuneTagOrGuid) + { + if (string.IsNullOrEmpty(zuneTagOrGuid)) + return (string)null; + string endPointUri = Microsoft.Zune.Service.Service.GetEndPointUri(operation == "comments" ? Microsoft.Zune.Service.EServiceEndpointId.SEID_Comments : Microsoft.Zune.Service.EServiceEndpointId.SEID_SocialApi); + if (string.IsNullOrEmpty(endPointUri)) + return (string)null; + zuneTagOrGuid = Uri.EscapeUriString(zuneTagOrGuid); + StringBuilder stringBuilder = new StringBuilder(endPointUri); + stringBuilder.Append("/members"); + if (operation == "search") + return UrlHelper.MakeUrl(stringBuilder.ToString(), "q", zuneTagOrGuid); + stringBuilder.Append("/"); + stringBuilder.Append(zuneTagOrGuid); + if (!string.IsNullOrEmpty(operation)) + { + stringBuilder.Append("/"); + stringBuilder.Append(operation); + } + return stringBuilder.ToString(); + } + + private string CreateUrlEncodedString(Attachment attachment) + { + StringBuilder stringBuilder = new StringBuilder(); + if (attachment != null) + { + foreach (string property in attachment.Properties) + { + if (property == null) + throw new ArgumentNullException(); + } + } + stringBuilder.Append("recipients="); + stringBuilder.Append(this.CreateRecipientString(true)); + if (!string.IsNullOrEmpty(this._message) && this._message.Length <= 230) + { + stringBuilder.Append("&text="); + stringBuilder.Append(Uri.EscapeDataString(this._message)); + } + if (attachment != null) + { + string[] properties = attachment.Properties; + int num = properties.Length - 1; + for (int index = 0; index < num; index += 2) + { + stringBuilder.Append("&"); + stringBuilder.Append(Uri.EscapeDataString(properties[index])); + stringBuilder.Append("="); + stringBuilder.Append(Uri.EscapeDataString(properties[index + 1])); + } + } + else + stringBuilder.Append("&type=message"); + if (!string.IsNullOrEmpty(this._serviceContext)) + { + stringBuilder.Append("&context="); + stringBuilder.Append(Uri.EscapeDataString(this._serviceContext)); + } + return stringBuilder.ToString(); + } + + private string CreateRecipientString(bool uriEscape) + { + StringBuilder stringBuilder = new StringBuilder(); + IList validRecipients = this.RecipientHelper.ValidRecipients; + string str = ","; + if (validRecipients != null) + { + for (int index = 0; index < validRecipients.Count; ++index) + { + if (index != 0) + stringBuilder.Append(str); + if (uriEscape) + stringBuilder.Append(Uri.EscapeDataString((string)validRecipients[index])); + else + stringBuilder.Append((string)validRecipients[index]); + } + } + return stringBuilder.ToString(); + } + + public RecipientHelper RecipientHelper => this._recipientHelper; + + public int MaxMessageLength => 230; + + public Command SendFailed => this._sendFailed; + + public Command SendSucceeded => this._sendSucceeded; + + public string Message + { + get => this._message; + set + { + if (!(this._message != value)) + return; + this._message = value == null ? value : value.Replace("\r\n", "\n"); + this.FirePropertyChanged(nameof(Message)); + } + } + + public string ServiceContext + { + get => this._serviceContext; + set + { + if (!(this._serviceContext != value)) + return; + this._serviceContext = value; + this.FirePropertyChanged(nameof(ServiceContext)); + } + } + + protected override void OnDispose(bool disposing) + { + if (disposing && this._recipientHelper != null) + { + this._recipientHelper.Dispose(); + this._recipientHelper = (RecipientHelper)null; + } + base.OnDispose(disposing); + } + + private void OnSendCompleted(HRESULT hr, string dialogMessage, bool wishlist) + { + if (hr.IsError) + { + if (wishlist) + { + ErrorMapperResult descriptionAndUrl = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int, eErrorCondition.eEC_Cart); + ErrorDialogInfo.Show(descriptionAndUrl.Hr, Shell.LoadString(StringId.IDS_CART_CANT_ADD_ITEMS), descriptionAndUrl.Description); + } + else + ErrorDialogInfo.Show(hr.Int, this.Description, dialogMessage); + this._sendFailed.Invoke(); + } + else + { + this._sendSucceeded.Invoke(); + if (!wishlist) + NotificationArea.Instance.Add((Notification)new MessageNotification(Shell.LoadString(StringId.IDS_MESSAGE_SENT_NOTIFICATION), NotificationTask.Messaging, NotificationState.OneShot)); + else + ++Shell.MainFrame.Marketplace.CartItemsCount; + } + } + + private void OnSendCompleted(object obj) + { + ComposerHelper.SendCompletedParams sendCompletedParams = (ComposerHelper.SendCompletedParams)obj; + this.OnSendCompleted(sendCompletedParams.HR, (string)null, sendCompletedParams.Wishlist); + } + + private void OnSendCompletedAsync(HRESULT hr, object state) + { + bool wishlist = (bool)state; + Application.DeferredInvoke(new DeferredInvokeHandler(this.OnSendCompleted), (object)new ComposerHelper.SendCompletedParams(hr, wishlist)); + } + + private void OnFavoritesManagementCompleted(object obj) + { + if (!(obj is ComposerHelper.FavoritesManagementState favoritesManagementState) || favoritesManagementState.Action != FavoritesAction.Add || !favoritesManagementState.MgmtOperationResult.IsSuccess) + return; + NotificationArea.Instance.Add((Notification)new MessageNotification(string.Format(Shell.LoadString(favoritesManagementState.FavoritesCount == 1 ? StringId.IDS_FAVORITE_MGMT_NOTIFICATION : StringId.IDS_FAVORITES_MGMT_NOTIFICATION), (object)favoritesManagementState.FavoritesCount), NotificationTask.Messaging, NotificationState.OneShot)); + } + + private void OnFavoritesManagementCompletedAsync(HRESULT hr, object state) + { + if (!(state is ComposerHelper.FavoritesManagementState favoritesManagementState)) + return; + favoritesManagementState.MgmtOperationResult = hr; + Application.DeferredInvoke(new DeferredInvokeHandler(this.OnFavoritesManagementCompleted), (object)favoritesManagementState); + } + + private class SendCompletedParams + { + private readonly HRESULT _hr; + private readonly bool _wishlist; + + public SendCompletedParams(HRESULT hr, bool wishlist) + { + this._hr = hr; + this._wishlist = wishlist; + } + + public HRESULT HR => this._hr; + + public bool Wishlist => this._wishlist; + } + + private class FavoritesManagementState + { + public FavoritesAction Action; + public int FavoritesCount; + public HRESULT MgmtOperationResult; + + public FavoritesManagementState(FavoritesAction action, int favoritesCount) + { + this.Action = action; + this.FavoritesCount = favoritesCount; + } + } + } +} diff --git a/ZuneUI/ComputerIconState.cs b/ZuneUI/ComputerIconState.cs new file mode 100644 index 0000000..8c349fb --- /dev/null +++ b/ZuneUI/ComputerIconState.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ComputerIconState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum ComputerIconState + { + Show, + ShowAsDropTarget, + Hide, + } +} diff --git a/ZuneUI/ConfirmCloseDialog.cs b/ZuneUI/ConfirmCloseDialog.cs new file mode 100644 index 0000000..9cb4d0e --- /dev/null +++ b/ZuneUI/ConfirmCloseDialog.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ConfirmCloseDialog +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using UIXControls; + +namespace ZuneUI +{ + public class ConfirmCloseDialog : DialogHelper + { + private EventHandler _handler; + + internal static void Show(string ui, EventHandler handler) => new ConfirmCloseDialog(ui, handler).Show(); + + public static void ShowDefault() => ConfirmCloseDialog.ShowDefault("res://ZuneShellResources!ConfirmClose.uix#ConfirmCloseContentUI"); + + public static void ShowDefault(string ui) => ConfirmCloseDialog.Show(ui, new EventHandler(ConfirmCloseDialog.ForceCloseHandler)); + + private static void ForceCloseHandler(object sender, EventArgs args) => Application.Window.ForceClose(); + + private ConfirmCloseDialog(string ui, EventHandler handler) + : base(ui) + => this._handler = handler; + + public void Close() => this._handler((object)this, (EventArgs)null); + } +} diff --git a/ZuneUI/ConfirmationStep.cs b/ZuneUI/ConfirmationStep.cs new file mode 100644 index 0000000..0d6d709 --- /dev/null +++ b/ZuneUI/ConfirmationStep.cs @@ -0,0 +1,90 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ConfirmationStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Collections; + +namespace ZuneUI +{ + public class ConfirmationStep : AccountManagementStep + { + private ArrayList _bulletItems; + private EBillingOfferType _offerType; + private ulong _offerId; + + public ConfirmationStep(Wizard owner, AccountManagementWizardState state, bool parent) + : base(owner, state, parent) + { + this.Description = Shell.LoadString(StringId.IDS_CONFIRM_SUBSCRIPTION_HEADER); + this.NextTextOverride = Shell.LoadString(StringId.IDS_BILLING_CONTINUE); + this._bulletItems = (ArrayList)null; + this._offerType = EBillingOfferType.Unknown; + this._offerId = 0UL; + this.RequireSignIn = true; + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#ConfirmationStep"; + + public EBillingOfferType OfferType + { + get => this._offerType; + set + { + this._offerType = value; + this.FirePropertyChanged(nameof(OfferType)); + } + } + + public ArrayList BulletItems + { + get => this._bulletItems; + set + { + this._bulletItems = value; + this.FirePropertyChanged(nameof(BulletItems)); + } + } + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled; + if (flag) + flag = this.State.IsPurchaseConfirmationNeeded && (this.OfferType == EBillingOfferType.Subscription || this.OfferType == EBillingOfferType.Renewal || this.OfferType == EBillingOfferType.Trial); + return flag; + } + } + + protected override void OnActivate() + { + if ((long)this._offerId != (long)this.State.SelectBillingOfferStep.SelectedBillingOffer.Id || this.BulletItems == null) + this.ServiceActivationRequestsDone = false; + base.OnActivate(); + } + + protected override void OnStartActivationRequests(object state) + { + ArrayList bulletStrings; + HRESULT subscriptionDetails = this.State.AccountManagement.GetSubscriptionDetails(this.State.SelectBillingOfferStep.SelectedBillingOffer.Id.ToString(), out bulletStrings); + if (subscriptionDetails.IsError) + { + bulletStrings = (ArrayList)null; + this.SetError(subscriptionDetails, (ServiceError)null); + } + this._offerId = this.State.SelectBillingOfferStep.SelectedBillingOffer.Id; + this.EndActivationRequests((object)bulletStrings); + } + + protected override void OnEndActivationRequests(object args) + { + if (args == null) + this.NavigateToErrorHandler(); + else + this.BulletItems = (ArrayList)args; + } + } +} diff --git a/ZuneUI/ConstantSplitSubList.cs b/ZuneUI/ConstantSplitSubList.cs new file mode 100644 index 0000000..59edfed --- /dev/null +++ b/ZuneUI/ConstantSplitSubList.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ConstantSplitSubList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class ConstantSplitSubList : SubList + { + private int _splitSize = 1; + + public int SplitSize + { + get => this._splitSize; + set + { + if (this._splitSize == value) + return; + this._splitSize = value > 0 ? value : throw new ArgumentOutOfRangeException(nameof(value), "SplitSize must be positive."); + this.FirePropertyChanged(nameof(SplitSize)); + this.ProduceSubLists(); + } + } + + protected override List GetSplits() + { + if (this.Source == null) + return (List)null; + int capacity = this.Source.Count / this._splitSize; + List intList = new List(capacity); + for (int index = 0; index < capacity; ++index) + { + int num = (index + 1) * this._splitSize; + intList.Add(num); + } + return intList; + } + } +} diff --git a/ZuneUI/ContactInfoParentPropertyEditor.cs b/ZuneUI/ContactInfoParentPropertyEditor.cs new file mode 100644 index 0000000..7b21a6a --- /dev/null +++ b/ZuneUI/ContactInfoParentPropertyEditor.cs @@ -0,0 +1,38 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ContactInfoParentPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ContactInfoParentPropertyEditor : BaseContactInfoPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static BirthdayPropertyDescriptor s_Birthday = new BirthdayPropertyDescriptor(nameof(Birthday), string.Empty, string.Empty, true); + public static CountryPropertyDescriptor s_Country = new CountryPropertyDescriptor(nameof(Country), string.Empty, string.Empty, true); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (ContactInfoParentPropertyEditor.s_dataProviderProperties == null) + ContactInfoParentPropertyEditor.s_dataProviderProperties = new PropertyDescriptor[7] + { + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_FirstName, + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_LastName, + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_PhoneNumber, + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_PhoneExtension, + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_Email, + (PropertyDescriptor) ContactInfoParentPropertyEditor.s_Birthday, + (PropertyDescriptor) ContactInfoParentPropertyEditor.s_Country + }; + return ContactInfoParentPropertyEditor.s_dataProviderProperties; + } + } + + public static PropertyDescriptor Birthday => (PropertyDescriptor)ContactInfoParentPropertyEditor.s_Birthday; + + public static PropertyDescriptor Country => (PropertyDescriptor)ContactInfoParentPropertyEditor.s_Country; + } +} diff --git a/ZuneUI/ContactInfoParentStep.cs b/ZuneUI/ContactInfoParentStep.cs new file mode 100644 index 0000000..12df093 --- /dev/null +++ b/ZuneUI/ContactInfoParentStep.cs @@ -0,0 +1,121 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ContactInfoParentStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class ContactInfoParentStep : RegionInfoStep + { + private bool _isAdult; + + public ContactInfoParentStep(Wizard owner, AccountManagementWizardState state) + : base(owner, state, true) + { + this.NextTextOverride = Shell.LoadString(StringId.IDS_I_ACCEPT_BUTTON); + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_PARENT_CONTACT_HEAD); + this.Initialize((WizardPropertyEditor)new ContactInfoParentPropertyEditor()); + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#ParentContactInfoStep"; + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled; + if (flag) + flag = this.State.BasicAccountInfoStep.IsParentAccountNeeded; + return flag; + } + } + + public bool IsAdult + { + get => this._isAdult; + protected set + { + if (this._isAdult == value) + return; + this._isAdult = value; + this.FirePropertyChanged(nameof(IsAdult)); + } + } + + protected override PropertyDescriptor CountryDescriptor => ContactInfoParentPropertyEditor.Country; + + protected override void OnCountryChanged() + { + if (this.WizardPropertyEditor == null) + return; + this.WizardPropertyEditor.SetPropertyState(BaseContactInfoPropertyEditor.FirstName, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(BaseContactInfoPropertyEditor.LastName, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(BaseContactInfoPropertyEditor.PhoneNumber, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(BaseContactInfoPropertyEditor.PhoneExtension, (object)this.SelectedCountry); + } + + protected override void OnActivate() + { + this.SelectedCountry = this.State.BasicAccountInfoStep.SelectedCountry; + this.ServiceDeactivationRequestsDone = false; + this.SetPropertyState(ContactInfoParentPropertyEditor.Birthday, (object)this.State.BasicAccountInfoStep.SelectedLocale); + this.SetUncommittedValue(ContactInfoParentPropertyEditor.Birthday, this.GetCommittedValue(ContactInfoParentPropertyEditor.Birthday)); + MetadataEditProperty property = this.WizardPropertyEditor.GetProperty(BaseContactInfoPropertyEditor.Email); + if (string.IsNullOrEmpty(property.Value)) + { + if (this.State.EmailSelectionParentStep.IsEmailPassportId) + { + property.Value = this.State.EmailSelectionParentStep.GetCommittedValue(EmailSelectionPropertyEditor.Email) as string; + } + else + { + string committedValue1 = this.State.CreatePassportParentStep.GetCommittedValue(CreatePassportPropertyEditor.PassportId) as string; + string committedValue2 = this.State.CreatePassportParentStep.GetCommittedValue(CreatePassportPropertyEditor.PassportDomain) as string; + if (committedValue1 != null && committedValue2 != null) + property.Value = committedValue1 + "@" + committedValue2; + } + } + base.OnActivate(); + } + + internal override bool OnMovingNext() + { + if (this.ServiceDeactivationRequestsDone) + { + this.WizardPropertyEditor.GetProperty(ContactInfoParentPropertyEditor.Birthday).ExternalError = !this.IsAdult ? HRESULT._ZUNE_E_SIGNUP_INVALID_PARENT_AGE : HRESULT._S_OK; + if (this.IsAdult) + return base.OnMovingNext(); + this.ShowValidation(); + this.ServiceDeactivationRequestsDone = false; + return false; + } + this.StartDeactivationRequests((object)((DateTime?)this.GetUncommittedValue(ContactInfoParentPropertyEditor.Birthday)).Value); + return false; + } + + protected override void OnStartDeactivationRequests(object state) => this.EndDeactivationRequests((object)this.ObtainIsAdult((DateTime)state)); + + protected override void OnEndDeactivationRequests(object args) => this.IsAdult = (bool)args; + + private bool ObtainIsAdult(DateTime birthday) + { + AccountCountry country = AccountCountryList.Instance.GetCountry(this.State.BasicAccountInfoStep.SelectedCountry); + bool flag = false; + if (country != null) + flag = this.ObtainAge(birthday) >= country.AdultAge; + return flag; + } + + private int ObtainAge(DateTime birthday) + { + DateTime today = DateTime.Today; + int num = today.Year - birthday.Year; + if (today.Month < birthday.Month || today.Month == birthday.Month && today.Day < birthday.Day) + --num; + return num; + } + } +} diff --git a/ZuneUI/ContactInfoPropertyEditor.cs b/ZuneUI/ContactInfoPropertyEditor.cs new file mode 100644 index 0000000..513e2d5 --- /dev/null +++ b/ZuneUI/ContactInfoPropertyEditor.cs @@ -0,0 +1,62 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ContactInfoPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ContactInfoPropertyEditor : BaseContactInfoPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static CountryFieldValidationPropertyDescriptor s_Street1 = new CountryFieldValidationPropertyDescriptor(nameof(Street1), CountryFieldValidatorType.Street1); + public static CountryFieldValidationPropertyDescriptor s_Street2 = new CountryFieldValidationPropertyDescriptor(nameof(Street2), CountryFieldValidatorType.Street2); + public static CountryFieldValidationPropertyDescriptor s_City = new CountryFieldValidationPropertyDescriptor(nameof(City), CountryFieldValidatorType.City); + public static CountryFieldValidationPropertyDescriptor s_District = new CountryFieldValidationPropertyDescriptor(nameof(District), CountryFieldValidatorType.District); + public static StateDescriptor s_State = new StateDescriptor(nameof(State)); + public static CountryPropertyDescriptor s_Country = new CountryPropertyDescriptor(nameof(Country), string.Empty, string.Empty, true); + public static PostalCodeDescriptor s_PostalCode = new PostalCodeDescriptor(nameof(PostalCode)); + public static LanguagePropertyDescriptor s_Language = new LanguagePropertyDescriptor(nameof(Language), string.Empty, string.Empty, true); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (ContactInfoPropertyEditor.s_dataProviderProperties == null) + ContactInfoPropertyEditor.s_dataProviderProperties = new PropertyDescriptor[13] + { + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_FirstName, + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_LastName, + (PropertyDescriptor) ContactInfoPropertyEditor.s_Street1, + (PropertyDescriptor) ContactInfoPropertyEditor.s_Street2, + (PropertyDescriptor) ContactInfoPropertyEditor.s_City, + (PropertyDescriptor) ContactInfoPropertyEditor.s_District, + (PropertyDescriptor) ContactInfoPropertyEditor.s_State, + (PropertyDescriptor) ContactInfoPropertyEditor.s_Country, + (PropertyDescriptor) ContactInfoPropertyEditor.s_PostalCode, + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_PhoneNumber, + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_PhoneExtension, + (PropertyDescriptor) BaseContactInfoPropertyEditor.s_Email, + (PropertyDescriptor) ContactInfoPropertyEditor.s_Language + }; + return ContactInfoPropertyEditor.s_dataProviderProperties; + } + } + + public static PropertyDescriptor Street1 => (PropertyDescriptor)ContactInfoPropertyEditor.s_Street1; + + public static PropertyDescriptor Street2 => (PropertyDescriptor)ContactInfoPropertyEditor.s_Street2; + + public static PropertyDescriptor City => (PropertyDescriptor)ContactInfoPropertyEditor.s_City; + + public static PropertyDescriptor District => (PropertyDescriptor)ContactInfoPropertyEditor.s_District; + + public static PropertyDescriptor State => (PropertyDescriptor)ContactInfoPropertyEditor.s_State; + + public static PropertyDescriptor Country => (PropertyDescriptor)ContactInfoPropertyEditor.s_Country; + + public static PropertyDescriptor PostalCode => (PropertyDescriptor)ContactInfoPropertyEditor.s_PostalCode; + + public static PropertyDescriptor Language => (PropertyDescriptor)ContactInfoPropertyEditor.s_Language; + } +} diff --git a/ZuneUI/ContactInformationWizard.cs b/ZuneUI/ContactInformationWizard.cs new file mode 100644 index 0000000..ef480af --- /dev/null +++ b/ZuneUI/ContactInformationWizard.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ContactInformationWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ContactInformationWizard : AccountManagementWizard + { + private AccountManagementFinishStep _finishStep; + private AccountManagementErrorPage _errorStep; + + public ContactInformationWizard() + { + this._finishStep = new AccountManagementFinishStep((Wizard)this, this.State, Shell.LoadString(StringId.IDS_ACCOUNT_FINISHED_DESCRIPTION), this.State.ContactInfoStep.DetailDescription); + this._errorStep = new AccountManagementErrorPage((Wizard)this, Shell.LoadString(StringId.IDS_ACCOUNT_CONTACT_INFO_ERROR_TITLE), Shell.LoadString(StringId.IDS_ACCOUNT_CONTACT_INFO_ERROR_DESC)); + this.AddPage((WizardPage)this.State.ContactInfoStep); + this.AddPage((WizardPage)this._finishStep); + this.AddPage((WizardPage)this._errorStep); + } + + protected override void OnAsyncCommitCompleted(bool success) + { + base.OnAsyncCommitCompleted(success); + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_ACCOUNT_CONTACT_INFO_SUCCESS_DESC); + } + } +} diff --git a/ZuneUI/ContainerPlayMarker.cs b/ZuneUI/ContainerPlayMarker.cs new file mode 100644 index 0000000..9900b38 --- /dev/null +++ b/ZuneUI/ContainerPlayMarker.cs @@ -0,0 +1,51 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ContainerPlayMarker +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Playlist; +using System; + +namespace ZuneUI +{ + [Serializable] + public class ContainerPlayMarker + { + private int _libraryId = -1; + private MediaType _mediaType; + private PlaylistType _playlistType; + private int _playlistSubType; + private bool _marked; + + public int LibraryId + { + get => this._libraryId; + set => this._libraryId = value; + } + + public MediaType MediaType + { + get => this._mediaType; + set => this._mediaType = value; + } + + public PlaylistType PlaylistType + { + get => this._playlistType; + set => this._playlistType = value; + } + + public int PlaylistSubType + { + get => this._playlistSubType; + set => this._playlistSubType = value; + } + + public bool Marked + { + get => this._marked; + set => this._marked = value; + } + } +} diff --git a/ZuneUI/CountryFieldValidationPropertyDescriptor.cs b/ZuneUI/CountryFieldValidationPropertyDescriptor.cs new file mode 100644 index 0000000..247e05a --- /dev/null +++ b/ZuneUI/CountryFieldValidationPropertyDescriptor.cs @@ -0,0 +1,85 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CountryFieldValidationPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Text.RegularExpressions; + +namespace ZuneUI +{ + public class CountryFieldValidationPropertyDescriptor : PropertyDescriptor + { + private CountryFieldValidatorType _fieldValidatorType; + + public CountryFieldValidationPropertyDescriptor( + string name, + CountryFieldValidatorType fieldValidatorType) + : base(name, string.Empty, string.Empty, false) + { + this._fieldValidatorType = fieldValidatorType; + } + + internal override string GetOverlayString(object state) + { + string str = string.Empty; + AccountCountry accountCountry = this.GetAccountCountry(state); + if (accountCountry != null) + { + CountryFieldValidator validator = accountCountry.GetValidator(this._fieldValidatorType); + if (validator != null) + str = validator.FriendlyFormat; + } + return str; + } + + internal override string GetLabelString(object state) + { + string str = string.Empty; + AccountCountry accountCountry = this.GetAccountCountry(state); + if (accountCountry != null) + { + CountryFieldValidator validator = accountCountry.GetValidator(this._fieldValidatorType); + if (validator != null) + str = Shell.LoadString(validator.NameStringId); + } + return str; + } + + public override bool IsValidInternal(string value, object state) + { + string pattern = (string)null; + AccountCountry accountCountry = this.GetAccountCountry(state); + if (accountCountry == null) + return true; + if (accountCountry != null) + { + CountryFieldValidator validator = accountCountry.GetValidator(this._fieldValidatorType); + if (validator != null && !string.IsNullOrEmpty(validator.Regex)) + pattern = validator.Regex; + } + return string.IsNullOrEmpty(pattern) || value != null && Regex.IsMatch(value, pattern); + } + + public override bool IsRequiredInternal(object state) + { + AccountCountry accountCountry = this.GetAccountCountry(state); + if (accountCountry != null) + { + CountryFieldValidator validator = accountCountry.GetValidator(this._fieldValidatorType); + if (validator != null && !string.IsNullOrEmpty(validator.Regex)) + return true; + } + return false; + } + + private AccountCountry GetAccountCountry(object state) + { + AccountCountry accountCountry = (AccountCountry)null; + if (state != null) + accountCountry = AccountCountryList.Instance.GetCountry(state as string); + return accountCountry; + } + } +} diff --git a/ZuneUI/CountryFieldValidatorType.cs b/ZuneUI/CountryFieldValidatorType.cs new file mode 100644 index 0000000..7056fce --- /dev/null +++ b/ZuneUI/CountryFieldValidatorType.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CountryFieldValidatorType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum CountryFieldValidatorType + { + Default, + FirstName, + LastName, + AccountHolderName, + Street1, + Street2, + City, + State, + PostalCode, + District, + Country, + PhoneType, + PhonePrefix, + PhoneNumber, + PhoneCountryCode, + PhoneExtension, + MobilePhoneNumber, + } +} diff --git a/ZuneUI/CountryHelper.cs b/ZuneUI/CountryHelper.cs new file mode 100644 index 0000000..b60c97b --- /dev/null +++ b/ZuneUI/CountryHelper.cs @@ -0,0 +1,57 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CountryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Globalization; + +namespace ZuneUI +{ + internal class CountryHelper + { + internal static string GetDisplayName(string countryCode) + { + string str = string.Empty; + if (!string.IsNullOrEmpty(countryCode)) + { + try + { + str = new RegionInfo(countryCode).DisplayName; + } + catch (ArgumentException ex) + { + } + } + return str; + } + + internal static string GetAbbreviation(string countryName) + { + string str = string.Empty; + if (!string.IsNullOrEmpty(countryName)) + { + foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)) + { + try + { + if (!string.IsNullOrEmpty(culture.Name)) + { + RegionInfo regionInfo = new RegionInfo(culture.Name); + if (regionInfo.DisplayName.Equals(countryName, StringComparison.CurrentCultureIgnoreCase)) + { + str = regionInfo.TwoLetterISORegionName; + break; + } + } + } + catch (ArgumentException ex) + { + } + } + } + return str; + } + } +} diff --git a/ZuneUI/CountryNameComparer.cs b/ZuneUI/CountryNameComparer.cs new file mode 100644 index 0000000..7ad7bb1 --- /dev/null +++ b/ZuneUI/CountryNameComparer.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CountryNameComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + internal class CountryNameComparer : IComparer + { + private static CountryNameComparer s_instance; + + public static IComparer Instance + { + get + { + if (CountryNameComparer.s_instance == null) + CountryNameComparer.s_instance = new CountryNameComparer(); + return (IComparer)CountryNameComparer.s_instance; + } + } + + private CountryNameComparer() + { + } + + int IComparer.Compare(string x, string y) => string.Compare(CountryHelper.GetDisplayName(x), CountryHelper.GetDisplayName(y), StringComparison.CurrentCultureIgnoreCase); + } +} diff --git a/ZuneUI/CountryPropertyDescriptor.cs b/ZuneUI/CountryPropertyDescriptor.cs new file mode 100644 index 0000000..86dcc47 --- /dev/null +++ b/ZuneUI/CountryPropertyDescriptor.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CountryPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class CountryPropertyDescriptor : PropertyDescriptor + { + public CountryPropertyDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : base(name, multiValueString, unknownString, required) + { + this.DefaultValue = (object)CultureHelper.GetDefaultCountry(); + } + + public override object ConvertFromString(string value) => (object)CountryHelper.GetAbbreviation(value); + + public override string ConvertToString(object value) => CountryHelper.GetDisplayName(value as string); + } +} diff --git a/ZuneUI/CreatePassportPropertyEditor.cs b/ZuneUI/CreatePassportPropertyEditor.cs new file mode 100644 index 0000000..182d623 --- /dev/null +++ b/ZuneUI/CreatePassportPropertyEditor.cs @@ -0,0 +1,63 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CreatePassportPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class CreatePassportPropertyEditor : WizardPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static PropertyDescriptor s_PassportId = new PropertyDescriptor("Name", string.Empty, string.Empty, true); + public static PropertyDescriptor s_PassportDomain = (PropertyDescriptor)new EmailDomainPropertyDescriptor("Domain", string.Empty, string.Empty); + public static PropertyDescriptor s_Password1 = (PropertyDescriptor)new NonBlankPropertyDescriptor("Password", string.Empty, string.Empty, 6, true); + public static PropertyDescriptor s_Password2 = (PropertyDescriptor)new NonBlankPropertyDescriptor(nameof(Password2), string.Empty, string.Empty, 6, true); + public static PropertyDescriptor s_SecretQuestion = new PropertyDescriptor(nameof(SecretQuestion), string.Empty, string.Empty, true); + public static NonBlankPropertyDescriptor s_SecretAnswer = new NonBlankPropertyDescriptor(nameof(SecretAnswer), string.Empty, string.Empty, 5, true); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (CreatePassportPropertyEditor.s_dataProviderProperties == null) + CreatePassportPropertyEditor.s_dataProviderProperties = new PropertyDescriptor[6] + { + CreatePassportPropertyEditor.s_PassportId, + CreatePassportPropertyEditor.s_PassportDomain, + CreatePassportPropertyEditor.s_Password1, + CreatePassportPropertyEditor.s_Password2, + CreatePassportPropertyEditor.s_SecretQuestion, + (PropertyDescriptor) CreatePassportPropertyEditor.s_SecretAnswer + }; + return CreatePassportPropertyEditor.s_dataProviderProperties; + } + } + + public override bool IsValid() + { + HRESULT hresult = HRESULT._S_OK; + MetadataEditProperty property1 = this.GetProperty(CreatePassportPropertyEditor.s_Password1); + MetadataEditProperty property2 = this.GetProperty(CreatePassportPropertyEditor.s_Password2); + if (property1.Value != property2.Value) + hresult = HRESULT._ZUNE_E_SIGNUP_PASSWORDS_DONT_MATCH; + if (hresult.IsError || property1.ExternalError == HRESULT._ZUNE_E_SIGNUP_INVALID_PARENT_EMAIL) + property1.ExternalError = hresult; + if (hresult.IsError || property2.ExternalError == HRESULT._ZUNE_E_SIGNUP_INVALID_PARENT_EMAIL) + property2.ExternalError = hresult; + return base.IsValid(); + } + + public static PropertyDescriptor PassportId => CreatePassportPropertyEditor.s_PassportId; + + public static PropertyDescriptor PassportDomain => CreatePassportPropertyEditor.s_PassportDomain; + + public static PropertyDescriptor Password1 => CreatePassportPropertyEditor.s_Password1; + + public static PropertyDescriptor Password2 => CreatePassportPropertyEditor.s_Password2; + + public static PropertyDescriptor SecretQuestion => CreatePassportPropertyEditor.s_SecretQuestion; + + public static NonBlankPropertyDescriptor SecretAnswer => CreatePassportPropertyEditor.s_SecretAnswer; + } +} diff --git a/ZuneUI/CreatePassportStep.cs b/ZuneUI/CreatePassportStep.cs new file mode 100644 index 0000000..9984ab1 --- /dev/null +++ b/ZuneUI/CreatePassportStep.cs @@ -0,0 +1,342 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CreatePassportStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.ErrorMapperApi; +using Microsoft.Zune.Service; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class CreatePassportStep : AccountManagementStep + { + private IList _suggestedPassportIds; + private WinLiveInformation _winLiveInformation; + private string _lastLocale; + private bool _createdPassport; + private Dictionary _errorMappings; + private static IList s_secretQuestions; + private string _secretAnswerString; + + public CreatePassportStep(Wizard owner, AccountManagementWizardState state, bool parentAccount) + : base(owner, state, parentAccount) + { + if (parentAccount) + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_START_PARENT_HEADER); + else + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_PASSPORT_STEP); + this._secretAnswerString = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_SECRET_ANSWER_HELP); + this.NextTextOverride = Shell.LoadString(StringId.IDS_I_ACCEPT_BUTTON); + this.Initialize((WizardPropertyEditor)new CreatePassportPropertyEditor()); + } + + public override string UI => "res://ZuneShellResources!CreatePassport.uix#CreatePassportStep"; + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled && !this.CreatedPassport; + if (flag) + flag = this.EmailSelectionStep.IsEnabled && (!this.EmailSelectionStep.HasEmail || !this.EmailSelectionStep.IsEmailPassportId) && (this._owner.CurrentPage != this || this.WinLiveInformation != null); + return flag; + } + } + + public override bool IsValid + { + get + { + MetadataEditProperty property1 = this.WizardPropertyEditor.GetProperty(CreatePassportPropertyEditor.PassportId); + MetadataEditProperty property2 = this.WizardPropertyEditor.GetProperty(CreatePassportPropertyEditor.PassportDomain); + string email = this.Email; + HRESULT hresult = HRESULT._S_OK; + if (this.ParentAccount && (email.Equals(this.State.EmailSelectionStep.Email, StringComparison.InvariantCultureIgnoreCase) || email.Equals(this.State.CreatePassportStep.Email, StringComparison.InvariantCultureIgnoreCase))) + hresult = HRESULT._ZUNE_E_SIGNUP_INVALID_PARENT_EMAIL; + if (hresult.IsError || property1.ExternalError == HRESULT._ZUNE_E_SIGNUP_INVALID_PARENT_EMAIL) + property1.ExternalError = hresult; + if (hresult.IsError || property2.ExternalError == HRESULT._ZUNE_E_SIGNUP_INVALID_PARENT_EMAIL) + property2.ExternalError = hresult; + return base.IsValid; + } + } + + public WinLiveInformation WinLiveInformation + { + get => this._winLiveInformation; + private set + { + if (this._winLiveInformation == value) + return; + this._winLiveInformation = value; + this.FirePropertyChanged(nameof(WinLiveInformation)); + this.FirePropertyChanged("IsEnabled"); + if (!this.CreateEmail) + return; + this.SetDefaultWindowsLiveDomain(); + } + } + + public WinLiveInformation WinLiveHip => !this.ParentAccount ? this.State.HipPassportStep.WinLiveHip : this.State.HipPassportParentStep.WinLiveHip; + + public bool CreateEmail => this.EmailSelectionStep.IsEnabled && !this.EmailSelectionStep.HasEmail; + + public IList SuggestedPassportIds + { + get => this._suggestedPassportIds; + private set + { + if (this._suggestedPassportIds == value) + return; + this._suggestedPassportIds = value; + this.FirePropertyChanged(nameof(SuggestedPassportIds)); + } + } + + public string CommittedEmail + { + get + { + string committedValue1 = this.GetCommittedValue(CreatePassportPropertyEditor.PassportId) as string; + string committedValue2 = this.GetCommittedValue(CreatePassportPropertyEditor.PassportDomain) as string; + string str = (string)null; + if (committedValue1 != null && committedValue2 != null) + str = string.Format("{0}@{1}", (object)committedValue1, (object)committedValue2); + return str; + } + } + + public string Email + { + get + { + string uncommittedValue1 = this.GetUncommittedValue(CreatePassportPropertyEditor.PassportId) as string; + string uncommittedValue2 = this.GetUncommittedValue(CreatePassportPropertyEditor.PassportDomain) as string; + string str = (string)null; + if (uncommittedValue1 != null && uncommittedValue2 != null) + str = string.Format("{0}@{1}", (object)uncommittedValue1, (object)uncommittedValue2); + return str; + } + set + { + if (!(this.Email != value)) + return; + string str1 = string.Empty; + string str2 = string.Empty; + int length = 0; + if (value != null) + length = value.IndexOf('@'); + if (length > 0 && length + 2 <= value.Length) + { + str1 = value.Substring(0, length); + str2 = value.Substring(length + 1); + } + this.SetCommittedValue(CreatePassportPropertyEditor.PassportId, (object)str1); + this.SetCommittedValue(CreatePassportPropertyEditor.PassportDomain, (object)str2); + this.FirePropertyChanged(nameof(Email)); + } + } + + internal bool CreatedPassport + { + get => this._createdPassport; + private set => this._createdPassport = value; + } + + internal override Dictionary ErrorPropertyMappings + { + get + { + if (this._errorMappings == null) + { + this._errorMappings = new Dictionary(18); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SIGNIN_NAME_TOO_SHORT.Int, CreatePassportPropertyEditor.PassportId); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SIGNIN_NAME_TOO_LONG.Int, CreatePassportPropertyEditor.PassportId); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SIGNIN_NAME_INVALID.Int, CreatePassportPropertyEditor.PassportId); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_EMAIL_INVALID.Int, CreatePassportPropertyEditor.PassportId); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_NAME_INVALID.Int, CreatePassportPropertyEditor.PassportId); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_MEMBER_EXISTS.Int, CreatePassportPropertyEditor.PassportId); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_DOMAIN_IS_MANAGED.Int, CreatePassportPropertyEditor.PassportDomain); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_PASSWORD_TOO_LONG.Int, CreatePassportPropertyEditor.Password1); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_PASSWORD_TOO_SHORT.Int, CreatePassportPropertyEditor.Password1); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_PASSWORD_INVALID.Int, CreatePassportPropertyEditor.Password1); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SECRET_QUESTION_TOO_SHORT.Int, CreatePassportPropertyEditor.SecretQuestion); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SECRET_QUESTION_TOO_LONG.Int, CreatePassportPropertyEditor.SecretQuestion); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SECRET_QUESTION_CONTAINS_ANSWER.Int, CreatePassportPropertyEditor.SecretQuestion); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SECRET_QUESTION_CONTAINS_PASSWORD.Int, CreatePassportPropertyEditor.SecretQuestion); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SECRET_ANSWER_TOO_SHORT.Int, (PropertyDescriptor)CreatePassportPropertyEditor.SecretAnswer); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SECRET_ANSWER_TOO_LONG.Int, (PropertyDescriptor)CreatePassportPropertyEditor.SecretAnswer); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SECRET_ANSWER_CONTAINS_MEMBER_NAME.Int, (PropertyDescriptor)CreatePassportPropertyEditor.SecretAnswer); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_SECRET_ANSWER_CONTAINS_PASSWORD.Int, (PropertyDescriptor)CreatePassportPropertyEditor.SecretAnswer); + } + return this._errorMappings; + } + } + + public static IList SecretQuestions + { + get + { + if (CreatePassportStep.s_secretQuestions == null) + { + string str = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_SECRET_QUESTIONS); + if (str != null) + CreatePassportStep.s_secretQuestions = (IList)str.Split(';'); + } + return CreatePassportStep.s_secretQuestions; + } + } + + private EmailSelectionStep EmailSelectionStep => !this.ParentAccount ? this.State.EmailSelectionStep : this.State.EmailSelectionParentStep; + + protected override void OnActivate() + { + this.ServiceDeactivationRequestsDone = false; + if (this.EmailSelectionStep.HasEmail && !this.CreateEmail) + this.Email = this.EmailSelectionStep.GetCommittedValue(EmailSelectionPropertyEditor.Email) as string; + string selectedLocale = this.State.BasicAccountInfoStep.SelectedLocale; + if (this._lastLocale != selectedLocale) + this.ServiceActivationRequestsDone = false; + if (!this.ServiceActivationRequestsDone) + { + this._lastLocale = selectedLocale; + this.StartActivationRequests((object)selectedLocale); + } + else if (this.CreateEmail) + this.SetDefaultWindowsLiveDomain(); + this.SecretAnswerString = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_SECRET_ANSWER_HELP); + CreatePassportPropertyEditor.SecretAnswer.MinLength = 5; + } + + public string SecretAnswerString + { + get => this._secretAnswerString; + private set + { + if (!(this._secretAnswerString != value)) + return; + this._secretAnswerString = value; + this.FirePropertyChanged(nameof(SecretAnswerString)); + } + } + + internal override void Deactivate() + { + base.Deactivate(); + this.SuggestedPassportIds = (IList)null; + } + + internal override bool OnMovingNext() + { + string email = this.Email; + string committedEmail = this.CommittedEmail; + if (email == committedEmail) + this.ServiceDeactivationRequestsDone = true; + if (this.ServiceDeactivationRequestsDone) + { + if (this.SuggestedPassportIds == null || this.SuggestedPassportIds.Count == 0 || this.SuggestedPassportIds.Contains((object)email)) + { + this.SuggestedPassportIds = (IList)null; + return base.OnMovingNext(); + } + this.ServiceDeactivationRequestsDone = false; + return false; + } + this.StartDeactivationRequests((object)email); + return false; + } + + internal override ErrorMapperResult GetMappedErrorDescriptionAndUrl(HRESULT hr) => Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int, eErrorCondition.eEC_WinLive); + + protected override bool OnCommitChanges() + { + bool flag = true; + if (this.IsEnabled && !this.CreatedPassport) + { + string email = this.Email; + string committedValue1 = this.GetCommittedValue(CreatePassportPropertyEditor.Password1) as string; + string committedValue2 = this.GetCommittedValue(CreatePassportPropertyEditor.SecretQuestion) as string; + string committedValue3 = this.GetCommittedValue((PropertyDescriptor)CreatePassportPropertyEditor.SecretAnswer) as string; + string selectedCountry = this.State.BasicAccountInfoStep.SelectedCountry; + int languagePreference = 0; + string selectedLocale = this.State.BasicAccountInfoStep.SelectedLocale; + if (!string.IsNullOrEmpty(selectedLocale)) + languagePreference = CultureHelper.GetLCIDFromCultureString(selectedLocale, true); + int termsOfServiceVersion = 0; + if (this.WinLiveInformation != null) + termsOfServiceVersion = this.WinLiveInformation.TermsOfServiceVersion; + string hipChallenge = string.Empty; + if (this.WinLiveHip != null) + hipChallenge = this.WinLiveHip.HipChallenge; + string committedValue4; + DateTime? committedValue5; + if (this.ParentAccount) + { + committedValue4 = this.State.HipPassportParentStep.GetCommittedValue(HipPropertyEditor.HipCharacters) as string; + committedValue5 = (DateTime?)this.State.ContactInfoParentStep.GetCommittedValue(ContactInfoParentPropertyEditor.Birthday); + } + else + { + committedValue4 = this.State.HipPassportStep.GetCommittedValue(HipPropertyEditor.HipCharacters) as string; + committedValue5 = (DateTime?)this.State.BasicAccountInfoStep.GetCommittedValue(BasicAccountInfoPropertyEditor.Birthday); + } + ServiceError serviceError = (ServiceError)null; + HRESULT account = this.State.WinLiveSignup.CreateAccount(email, committedValue1, committedValue2, committedValue3, selectedCountry, hipChallenge, committedValue4, committedValue5.Value, termsOfServiceVersion, languagePreference, out serviceError); + flag = account.IsSuccess; + if (flag) + this.CreatedPassport = true; + else + this.SetError(account, serviceError); + } + return flag; + } + + protected override void OnStartActivationRequests(object state) => this.EndActivationRequests((object)this.ObtainWinLiveInformation(state as string)); + + protected override void OnEndActivationRequests(object args) + { + if (args == null) + this.NavigateToErrorHandler(); + else + this.WinLiveInformation = args as WinLiveInformation; + } + + protected override void OnStartDeactivationRequests(object state) => this.EndDeactivationRequests((object)this.ObtainUniquePassportIds(state as string)); + + protected override void OnEndDeactivationRequests(object args) => this.SuggestedPassportIds = args as IList; + + private void SetDefaultWindowsLiveDomain() + { + if (this.GetUncommittedValue(CreatePassportPropertyEditor.PassportDomain) is string uncommittedValue && (this._winLiveInformation.Domains == null || this._winLiveInformation.Domains.Count <= 0 || this._winLiveInformation.Domains.Contains((object)uncommittedValue))) + return; + this.SetUncommittedValue(CreatePassportPropertyEditor.PassportDomain, (object)(this._winLiveInformation.Domains[0] as string)); + } + + private WinLiveInformation ObtainWinLiveInformation(string locale) + { + WinLiveInformation information1 = (WinLiveInformation)null; + ServiceError serviceError = (ServiceError)null; + HRESULT information2 = this.State.WinLiveSignup.GetInformation(locale, Microsoft.Zune.Service.EHipType.Image, out information1, out serviceError); + if (information2.IsError) + this.SetError(information2, serviceError); + return information1; + } + + private IList ObtainUniquePassportIds(string email) + { + IList list = (IList)null; + ServiceError serviceError = (ServiceError)null; + WinLiveAvailableInformation information; + HRESULT hr = this.State.WinLiveSignup.CheckAvailableSigninName(email, true, (string)null, (string)null, out information, out serviceError); + if (hr.IsError) + this.SetError(hr, serviceError); + else if (!information.Available) + list = information.SuggestedNames; + return list; + } + } +} diff --git a/ZuneUI/CreditCardExpirationDateDescriptor.cs b/ZuneUI/CreditCardExpirationDateDescriptor.cs new file mode 100644 index 0000000..d23fe43 --- /dev/null +++ b/ZuneUI/CreditCardExpirationDateDescriptor.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CreditCardExpirationDateDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class CreditCardExpirationDateDescriptor : DatePropertyDescriptor + { + public CreditCardExpirationDateDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : base(name, multiValueString, unknownString, required) + { + } + + public override bool IsValidInternal(string value) + { + DateTime dateTime; + if (StringParserHelper.IsNullOrEmptyOrBlank(value) || !StringParserHelper.TryParseDate(value, out dateTime)) + return false; + DateTime now = DateTime.Now; + if (dateTime.Year > now.Year) + return true; + return dateTime.Year == now.Year && dateTime.Month >= now.Month; + } + } +} diff --git a/ZuneUI/CreditCardHelper.cs b/ZuneUI/CreditCardHelper.cs new file mode 100644 index 0000000..c053ffd --- /dev/null +++ b/ZuneUI/CreditCardHelper.cs @@ -0,0 +1,85 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CreditCardHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System; +using System.Collections; + +namespace ZuneUI +{ + public static class CreditCardHelper + { + private static string[] s_CardTypeStrs; + private static string[] s_SupportedCardTypeStrs; + private static string[] s_JpnSupportedCardTypeStrs; + + public static string CardTypeToString(CreditCardType cardType) => CreditCardHelper.CardTypeToString((int)cardType); + + public static string CardTypeToString(int cardType) + { + string[] creditCardMappings = CreditCardHelper.CreditCardMappings; + return cardType >= 0 && cardType < creditCardMappings.Length ? creditCardMappings[cardType] : (string)null; + } + + public static CreditCardType CardTypeFromString(string cardTypeStr) + { + string[] creditCardMappings = CreditCardHelper.CreditCardMappings; + for (int index = 0; index < creditCardMappings.Length; ++index) + { + if (creditCardMappings[index] == cardTypeStr) + return (CreditCardType)index; + } + return CreditCardType.Unknown; + } + + public static IList CardTypes + { + get + { + if (CreditCardHelper.s_SupportedCardTypeStrs == null || CreditCardHelper.s_JpnSupportedCardTypeStrs == null) + { + string[] creditCardMappings = CreditCardHelper.CreditCardMappings; + CreditCardHelper.s_SupportedCardTypeStrs = new string[4] + { + creditCardMappings[2], + creditCardMappings[3], + creditCardMappings[1], + creditCardMappings[0] + }; + CreditCardHelper.s_JpnSupportedCardTypeStrs = new string[4] + { + creditCardMappings[2], + creditCardMappings[1], + creditCardMappings[0], + creditCardMappings[4] + }; + Array.Sort(CreditCardHelper.s_SupportedCardTypeStrs); + Array.Sort(CreditCardHelper.s_JpnSupportedCardTypeStrs); + } + return SignIn.Instance.SignedIn && string.Compare(SignIn.Instance.CountryCode, "JP", StringComparison.OrdinalIgnoreCase) == 0 ? (IList)CreditCardHelper.s_JpnSupportedCardTypeStrs : (IList)CreditCardHelper.s_SupportedCardTypeStrs; + } + } + + private static string[] CreditCardMappings + { + get + { + if (CreditCardHelper.s_CardTypeStrs == null) + CreditCardHelper.s_CardTypeStrs = new string[7] + { + Shell.LoadString(StringId.IDS_BILLING_CC_VISA), + Shell.LoadString(StringId.IDS_BILLING_CC_MASTERCARD), + Shell.LoadString(StringId.IDS_BILLING_CC_AMEX), + Shell.LoadString(StringId.IDS_BILLING_CC_DISCOVER), + Shell.LoadString(StringId.IDS_BILLING_CC_JCB), + Shell.LoadString(StringId.IDS_BILLING_CC_DINERS), + Shell.LoadString(StringId.IDS_BILLING_CC_KLCC) + }; + return CreditCardHelper.s_CardTypeStrs; + } + } + } +} diff --git a/ZuneUI/CreditCardNumberDescriptor.cs b/ZuneUI/CreditCardNumberDescriptor.cs new file mode 100644 index 0000000..4f59d44 --- /dev/null +++ b/ZuneUI/CreditCardNumberDescriptor.cs @@ -0,0 +1,49 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CreditCardNumberDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text.RegularExpressions; + +namespace ZuneUI +{ + public class CreditCardNumberDescriptor : PropertyDescriptor + { + private bool _allowSeperators; + private static Regex s_numbersWithSeperatorsRegex = new Regex("^\\d(\\d*(-)*( )*)*$", RegexOptions.IgnoreCase); + private static Regex s_numbersRegex = new Regex("^\\d+$", RegexOptions.IgnoreCase); + + public CreditCardNumberDescriptor( + string name, + string multiValueString, + string unknownString, + bool required, + bool allowSeperators) + : base(name, multiValueString, unknownString, required) + { + this._allowSeperators = allowSeperators; + } + + public override string ConvertToString(object value) => value == null ? string.Empty : value as string; + + public override object ConvertFromString(string value) => value == null ? (object)string.Empty : (object)this.RemoveSeperators(value); + + public override bool IsValidInternal(string value) + { + if (string.IsNullOrEmpty(value)) + return !this.Required; + return this._allowSeperators ? CreditCardNumberDescriptor.s_numbersWithSeperatorsRegex.IsMatch(value) : CreditCardNumberDescriptor.s_numbersRegex.IsMatch(value); + } + + private string RemoveSeperators(string value) + { + if (this._allowSeperators) + { + value = value.Replace("-", ""); + value = value.Replace(" ", ""); + } + return value; + } + } +} diff --git a/ZuneUI/CreditCardPropertySource.cs b/ZuneUI/CreditCardPropertySource.cs new file mode 100644 index 0000000..6655907 --- /dev/null +++ b/ZuneUI/CreditCardPropertySource.cs @@ -0,0 +1,107 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CreditCardPropertySource +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System; + +namespace ZuneUI +{ + public class CreditCardPropertySource : PropertySource + { + private static PropertySource _instance; + + protected CreditCardPropertySource() + { + } + + public static PropertySource Instance + { + get + { + if (CreditCardPropertySource._instance == null) + CreditCardPropertySource._instance = (PropertySource)new CreditCardPropertySource(); + return CreditCardPropertySource._instance; + } + } + + public override object Get(object media, PropertyDescriptor property) + { + CreditCard creditCard = media as CreditCard; + string descriptorName = property.DescriptorName; + if (creditCard == null) + return (object)null; + if (descriptorName == PropertyEditCreditCard.s_Street1.DescriptorName) + return (object)creditCard.Address.Street1; + if (descriptorName == PropertyEditCreditCard.s_Street2.DescriptorName) + return (object)creditCard.Address.Street2; + if (descriptorName == PropertyEditCreditCard.s_City.DescriptorName) + return (object)creditCard.Address.City; + if (descriptorName == PropertyEditCreditCard.s_District.DescriptorName) + return (object)creditCard.Address.District; + if (descriptorName == PropertyEditCreditCard.s_State.DescriptorName) + return (object)creditCard.Address.State; + if (descriptorName == PropertyEditCreditCard.s_PostalCode.DescriptorName) + return (object)creditCard.Address.PostalCode; + if (descriptorName == PropertyEditCreditCard.s_CardType.DescriptorName) + return (object)creditCard.CreditCardType; + if (descriptorName == PropertyEditCreditCard.s_AccountHolderName.DescriptorName) + return (object)creditCard.AccountHolderName; + if (descriptorName == PropertyEditCreditCard.s_AccountNumber.DescriptorName) + return (object)creditCard.AccountNumber; + if (descriptorName == PropertyEditCreditCard.s_CcvNumber.DescriptorName) + return (object)creditCard.CCVNumber; + if (descriptorName == PropertyEditCreditCard.s_ExpirationDate.DescriptorName) + return (object)creditCard.ExpirationDate; + if (descriptorName == PropertyEditCreditCard.s_PhoneExtension.DescriptorName) + return (object)creditCard.PhoneExtension; + return descriptorName == PropertyEditCreditCard.s_PhoneNumber.DescriptorName ? (object)PropertyEditCreditCard.s_PhoneNumber.Combine(creditCard.PhonePrefix, creditCard.PhoneNumber) : (object)null; + } + + public override void Set(object media, PropertyDescriptor property, object value) + { + CreditCard creditCard = media as CreditCard; + string descriptorName = property.DescriptorName; + if (creditCard == null) + return; + if (descriptorName == PropertyEditCreditCard.s_Street1.DescriptorName) + creditCard.Address.Street1 = (string)value; + else if (descriptorName == PropertyEditCreditCard.s_Street2.DescriptorName) + creditCard.Address.Street2 = (string)value; + else if (descriptorName == PropertyEditCreditCard.s_City.DescriptorName) + creditCard.Address.City = (string)value; + else if (descriptorName == PropertyEditCreditCard.s_District.DescriptorName) + creditCard.Address.District = (string)value; + else if (descriptorName == PropertyEditCreditCard.s_State.DescriptorName) + creditCard.Address.State = (string)value; + else if (descriptorName == PropertyEditCreditCard.s_PostalCode.DescriptorName) + creditCard.Address.PostalCode = (string)value; + else if (descriptorName == PropertyEditCreditCard.s_CardType.DescriptorName) + creditCard.CreditCardType = (CreditCardType)value; + else if (descriptorName == PropertyEditCreditCard.s_AccountHolderName.DescriptorName) + creditCard.AccountHolderName = (string)value; + else if (descriptorName == PropertyEditCreditCard.s_AccountNumber.DescriptorName) + creditCard.AccountNumber = (string)value; + else if (descriptorName == PropertyEditCreditCard.s_CcvNumber.DescriptorName) + creditCard.CCVNumber = (string)value; + else if (descriptorName == PropertyEditCreditCard.s_ExpirationDate.DescriptorName) + creditCard.ExpirationDate = (DateTime)value; + else if (descriptorName == PropertyEditCreditCard.s_PhoneExtension.DescriptorName) + { + creditCard.PhoneExtension = (string)value; + } + else + { + if (!(descriptorName == PropertyEditCreditCard.s_PhoneNumber.DescriptorName)) + return; + string areaCode; + string number; + PropertyEditCreditCard.s_PhoneNumber.Split(value as string, out areaCode, out number); + creditCard.PhonePrefix = areaCode; + creditCard.PhoneNumber = number; + } + } + } +} diff --git a/ZuneUI/CryptoHelper.cs b/ZuneUI/CryptoHelper.cs new file mode 100644 index 0000000..5a19edb --- /dev/null +++ b/ZuneUI/CryptoHelper.cs @@ -0,0 +1,153 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CryptoHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Text; + +namespace ZuneUI +{ + internal class CryptoHelper : IDisposable + { + private const uint PROV_RSA_FULL = 1; + private const uint CRYPT_VERIFYCONTEXT = 4026531840; + private const uint CRYPT_NEWKEYSET = 8; + private const uint ALG_CLASS_DATA_ENCRYPT = 24576; + private const uint ALG_CLASS_HASH = 32768; + private const uint ALG_TYPE_ANY = 0; + private const uint ALG_TYPE_STREAM = 2048; + private const uint ALG_SID_RC4 = 1; + private const uint ALG_SID_MD5 = 3; + private const uint CALG_MD5 = 32771; + private const uint CALG_RC4 = 26625; + private const uint NTE_BAD_KEYSET = 2148073494; + private IntPtr m_hCryptoProvider; + private IntPtr m_hKey; + + public CryptoHelper(string key) + { + IntPtr phHash = IntPtr.Zero; + byte[] bytes = Encoding.Unicode.GetBytes(key); + try + { + if (!CryptoHelper.CryptAcquireContext(out this.m_hCryptoProvider, (string)null, (string)null, 1U, 4026531840U)) + { + int lastWin32Error = Marshal.GetLastWin32Error(); + if (-2146893802 != lastWin32Error) + throw new Win32Exception(lastWin32Error); + if (!CryptoHelper.CryptAcquireContext(out this.m_hCryptoProvider, (string)null, (string)null, 1U, 4026531848U)) + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + if (!CryptoHelper.CryptCreateHash(this.m_hCryptoProvider, 32771U, IntPtr.Zero, 0U, out phHash)) + throw new Win32Exception(Marshal.GetLastWin32Error()); + if (!CryptoHelper.CryptHashData(phHash, bytes, (uint)bytes.Length, 0U)) + throw new Win32Exception(Marshal.GetLastWin32Error()); + if (!CryptoHelper.CryptDeriveKey(this.m_hCryptoProvider, 26625U, phHash, 8388608U, out this.m_hKey)) + throw new Win32Exception(Marshal.GetLastWin32Error()); + } + finally + { + if (phHash != IntPtr.Zero) + CryptoHelper.CryptDestroyHash(phHash); + } + } + + public string Encrypt(string data) + { + byte[] bytes = Encoding.Unicode.GetBytes(data); + uint length = (uint)bytes.Length; + if (!CryptoHelper.CryptEncrypt(this.m_hKey, IntPtr.Zero, true, 0U, bytes, ref length, length)) + throw new Win32Exception(Marshal.GetLastWin32Error()); + return Convert.ToBase64String(bytes); + } + + public string Decrypt(string data) + { + byte[] numArray = Convert.FromBase64String(data); + uint length = (uint)numArray.Length; + if (!CryptoHelper.CryptDecrypt(this.m_hKey, IntPtr.Zero, true, 0U, numArray, ref length)) + throw new Win32Exception(Marshal.GetLastWin32Error()); + return Encoding.Unicode.GetString(numArray); + } + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize((object)this); + } + + public void Dispose(bool disposing) + { + if (IntPtr.Zero != this.m_hKey) + CryptoHelper.CryptDestroyKey(this.m_hKey); + if (!(IntPtr.Zero != this.m_hCryptoProvider)) + return; + CryptoHelper.CryptReleaseContext(this.m_hCryptoProvider, 0U); + } + + ~CryptoHelper() => this.Dispose(false); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool CryptAcquireContext( + out IntPtr phProv, + string pszContainer, + string pszProvider, + uint dwProvType, + uint dwFlags); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool CryptCreateHash( + IntPtr hProv, + uint algId, + IntPtr hKey, + uint dwFlags, + out IntPtr phHash); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool CryptHashData( + IntPtr hHash, + byte[] pbData, + uint dwDataLen, + uint dwFlags); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool CryptDestroyHash(IntPtr hHash); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool CryptDeriveKey( + IntPtr hProv, + uint algId, + IntPtr hBaseData, + uint dwFlags, + out IntPtr phKey); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool CryptDestroyKey(IntPtr hHashKey); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool CryptEncrypt( + IntPtr hKey, + IntPtr hHash, + bool final, + uint dwFlags, + byte[] pbData, + ref uint pdwDataLen, + uint dwBufLen); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool CryptDecrypt( + IntPtr hKey, + IntPtr hHash, + bool final, + uint dwFlags, + byte[] pbData, + ref uint pdwDataLen); + } +} diff --git a/ZuneUI/CultureHelper.cs b/ZuneUI/CultureHelper.cs new file mode 100644 index 0000000..6a339f8 --- /dev/null +++ b/ZuneUI/CultureHelper.cs @@ -0,0 +1,236 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CultureHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Util; +using System; +using System.Globalization; +using System.Text; +using System.Threading; +using UIXControls; + +namespace ZuneUI +{ + public class CultureHelper + { + private static bool s_marketplaceCultureChecked = false; + private static bool? useAlternateStyling; + + public static void CheckMarketplaceCulture() + { + if (CultureHelper.s_marketplaceCultureChecked) + return; + string marketplaceCulture1 = FeatureEnablement.GetMarketplaceCulture(); + if (string.IsNullOrEmpty(marketplaceCulture1)) + return; + CultureHelper.s_marketplaceCultureChecked = true; + string strB = (string)null; + if (marketplaceCulture1.Length > 1) + strB = marketplaceCulture1.Substring(0, 2); + string strA1 = CultureInfo.CurrentUICulture.ToString(); + string strA2 = (string)null; + if (strA1.Length > 1) + strA2 = strA1.Substring(0, 2); + bool flag1 = 0 == string.Compare(strA2, strB, StringComparison.InvariantCultureIgnoreCase); + bool flag2 = false; + bool flag3 = false; + if (!flag1) + { + string marketplaceCulture2 = ClientConfiguration.Shell.LastMarketplaceCulture; + flag2 = 0 != string.Compare(marketplaceCulture1, marketplaceCulture2, StringComparison.InvariantCultureIgnoreCase); + string lastClientCulture = ClientConfiguration.Shell.LastClientCulture; + flag3 = 0 != string.Compare(strA1, lastClientCulture, StringComparison.InvariantCultureIgnoreCase); + } + ClientConfiguration.Shell.LastMarketplaceCulture = marketplaceCulture1; + ClientConfiguration.Shell.LastClientCulture = strA1; + if (flag1 || !flag2 && !flag3) + return; + MessageBox.Show(Shell.LoadString(StringId.IDS_MARKETPLACE_CULTURE_MISMATCH_TITLE), Shell.LoadString(StringId.IDS_MARKETPLACE_CULTURE_MISMATCH), (EventHandler)null); + } + + public static void CheckValidRegionAndLanguage() + { + if (FeatureEnablement.HasValidRegionAndLanguage()) + return; + ErrorDialogInfo.Show(HRESULT._ZUNE_E_UNKNOWN_REGION_OR_LANGUAGE.Int, Shell.LoadString(StringId.IDS_UNKNOWN_REGION_OR_LANGUAGE_TITLE)); + } + + public static bool ShowYomiSortFields() + { + string letterIsoLanguageName = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; + string region = FeatureEnablement.GetRegion(); + return letterIsoLanguageName.Equals("ja", StringComparison.OrdinalIgnoreCase) || region.Equals("jp", StringComparison.OrdinalIgnoreCase); + } + + public static string GetCurrentRegionDisplayName() + { + string region = FeatureEnablement.GetRegion(); + try + { + return new RegionInfo(FeatureEnablement.GetRegion()).DisplayName; + } + catch (ArgumentException ex) + { + return region; + } + } + + public static bool IsEnUs() + { + bool flag1 = Thread.CurrentThread.CurrentUICulture.Equals((object)new CultureInfo("en-US")); + bool flag2 = StringHelper.IsEqualCaseInsensitive(FeatureEnablement.GetRegion(), "US"); + return flag1 && flag2; + } + + public static bool UseAlternateStyling() + { + if (!CultureHelper.useAlternateStyling.HasValue) + { + switch (CultureInfo.CurrentUICulture.LCID) + { + case 4: + case 17: + case 18: + case 1028: + case 1041: + case 1042: + case 2052: + case 3076: + case 4100: + case 5124: + case 31748: + CultureHelper.useAlternateStyling = new bool?(true); + break; + default: + CultureHelper.useAlternateStyling = new bool?(false); + break; + } + } + return CultureHelper.useAlternateStyling.Value; + } + + public static uint GeoId() => FeatureEnablement.GetGeoId(); + + public static bool IsValidGeoId(uint geoId) => (int)FeatureEnablement.GetInvalidGeoId() != (int)geoId; + + public static int GetLCIDFromCultureString(string culture, bool useDefault) + { + int num = -1; + if (!string.IsNullOrEmpty(culture)) + { + try + { + num = new CultureInfo(culture).LCID; + } + catch (Exception ex) + { + if (culture.Equals("es-US", StringComparison.InvariantCultureIgnoreCase)) + num = 21514; + } + } + if (num == -1 && useDefault) + num = CultureInfo.CurrentUICulture.LCID; + return num; + } + + public static string GetHelpUrl() + { + string uri = Shell.LoadString(StringId.IDS_WWW_ZUNE_NET_SUPPORT_URL); + string lynxCulture = FeatureEnablement.GetLynxCulture(); + if (!string.IsNullOrEmpty(lynxCulture)) + uri = CultureHelper.AppendFwlinkCulture(uri, lynxCulture); + StringBuilder args = new StringBuilder(uri); + string uiPath = ZuneShell.DefaultInstance.CurrentPage.UIPath; + if (!string.IsNullOrEmpty(uiPath)) + UrlHelper.AppendParam(false, args, "path", uiPath); + foreach (UIDevice uiDevice in SingletonModelItem.Instance) + { + if (uiDevice.IsConnectedToPC || SignIn.Instance.SignedIn && uiDevice.UserId == SignIn.Instance.LastSignedInUserId) + { + UrlHelper.AppendParam(false, args, "mfr", uiDevice.Manufacturer); + UrlHelper.AppendParam(false, args, "mdl", uiDevice.ModelName); + } + } + return args.ToString(); + } + + public static string GetPrivacyUrl() + { + string uri = Shell.LoadString(StringId.IDS_PRIVACY_STATEMENT_URL); + string lynxCulture = FeatureEnablement.GetLynxCulture(); + if (!string.IsNullOrEmpty(lynxCulture)) + uri = CultureHelper.AppendFwlinkCulture(uri, lynxCulture); + return uri; + } + + public static string AppendFwlinkCulture(string uri, int lcid) + { + if (lcid >= 0) + uri = string.Format("{0}&clcid=0x{1:x}", (object)uri, (object)lcid); + return uri; + } + + public static string AppendFwlinkCulture(string uri, string culture) + { + if (!string.IsNullOrEmpty(culture)) + uri = CultureHelper.AppendFwlinkCulture(uri, CultureHelper.GetLCIDFromCultureString(culture, false)); + return uri; + } + + public static string AppendFwlinkCulture(string uri) + { + uri = CultureHelper.AppendFwlinkCulture(uri, CultureHelper.GetLCIDFromCultureString((string)null, true)); + return uri; + } + + public static string AppendFwlinkLynxCulture(string uri) + { + string lynxCulture = FeatureEnablement.GetLynxCulture(); + if (!string.IsNullOrEmpty(lynxCulture)) + uri = CultureHelper.AppendFwlinkCulture(uri, lynxCulture); + return uri; + } + + public static string AppendLynxCultureQueryString(string uri) => CultureHelper.AppendLynxCultureQueryString(uri, false); + + public static string AppendLynxCultureQueryString(string uri, bool first) + { + string lynxCulture = FeatureEnablement.GetLynxCulture(); + if (string.IsNullOrEmpty(lynxCulture)) + return uri; + return first ? string.Format("{0}?culture={1}", (object)uri, (object)lynxCulture) : string.Format("{0}&culture={1}", (object)uri, (object)lynxCulture); + } + + internal static string GetDefaultCountry() => FeatureEnablement.GetRegion(); + + internal static string GetDefaultLanguage() + { + string str = (string)null; + CultureInfo currentUiCulture = CultureInfo.CurrentUICulture; + if (currentUiCulture != null) + str = currentUiCulture.TwoLetterISOLanguageName; + return str; + } + + public static CultureInfo GetCulture(string cultureString) + { + CultureInfo cultureInfo = (CultureInfo)null; + if (!string.IsNullOrEmpty(cultureString)) + { + try + { + cultureInfo = new CultureInfo(cultureString, false); + } + catch + { + } + } + if (cultureInfo == null) + cultureInfo = CultureInfo.CurrentCulture; + return cultureInfo; + } + } +} diff --git a/ZuneUI/CurrentPageCommandHandler.cs b/ZuneUI/CurrentPageCommandHandler.cs new file mode 100644 index 0000000..d68b814 --- /dev/null +++ b/ZuneUI/CurrentPageCommandHandler.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CurrentPageCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + public class CurrentPageCommandHandler : ICommandHandler + { + public void Execute(string command, IDictionary commandArgs) + { + ZuneShell defaultInstance = ZuneShell.DefaultInstance; + if (defaultInstance == null) + throw new InvalidOperationException("No Shell instance has been registered. Unable to perform navigation."); + defaultInstance.CurrentPage.CommandHandler?.Execute(command, commandArgs); + } + } +} diff --git a/ZuneUI/CustomSubList.cs b/ZuneUI/CustomSubList.cs new file mode 100644 index 0000000..73e92db --- /dev/null +++ b/ZuneUI/CustomSubList.cs @@ -0,0 +1,44 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.CustomSubList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class CustomSubList : SubList + { + private List _splits; + + public static void AssignSplits(CustomSubList list, IList inList) + { + List intList = new List(inList.Count); + foreach (object obj in (IEnumerable)inList) + { + if (obj is int num) + intList.Add(num); + } + list.Splits = intList; + } + + public List Splits + { + get => this._splits; + set + { + if (this._splits == value) + return; + if (value != null) + this.ValidateSplits(value); + this._splits = value; + this.FirePropertyChanged(nameof(Splits)); + this.ProduceSubLists(); + } + } + + protected override List GetSplits() => this.Splits; + } +} diff --git a/ZuneUI/DataObjectStringExtractorList.cs b/ZuneUI/DataObjectStringExtractorList.cs new file mode 100644 index 0000000..22b6ffb --- /dev/null +++ b/ZuneUI/DataObjectStringExtractorList.cs @@ -0,0 +1,44 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DataObjectStringExtractorList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class DataObjectStringExtractorList : StringExtractorList + { + private string _property; + + public DataObjectStringExtractorList() => this.CanSearchForString = true; + + public DataObjectStringExtractorList(IList source, string property) + : this() + { + this.Source = source; + this.Property = property; + } + + public string Property + { + get => this._property; + set + { + if (!(this._property != value)) + return; + this._property = value; + this.Reset(); + } + } + + protected override string ExtractString(object item) + { + if (this._property == null) + return base.ExtractString(item); + return ((DataProviderObject)item).GetProperty(this._property)?.ToString(); + } + } +} diff --git a/ZuneUI/DataProviderObjectPropertySource.cs b/ZuneUI/DataProviderObjectPropertySource.cs new file mode 100644 index 0000000..abe1f19 --- /dev/null +++ b/ZuneUI/DataProviderObjectPropertySource.cs @@ -0,0 +1,38 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DataProviderObjectPropertySource +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class DataProviderObjectPropertySource : PropertySource + { + private static PropertySource _instance; + + protected DataProviderObjectPropertySource() + { + } + + public static PropertySource Instance + { + get + { + if (DataProviderObjectPropertySource._instance == null) + DataProviderObjectPropertySource._instance = (PropertySource)new DataProviderObjectPropertySource(); + return DataProviderObjectPropertySource._instance; + } + } + + public override object Get(object media, PropertyDescriptor property) => !(media is DataProviderObject dataProviderObject) ? (object)null : dataProviderObject.GetProperty(property.DescriptorName); + + public override void Set(object media, PropertyDescriptor property, object value) + { + if (!(media is DataProviderObject dataProviderObject)) + return; + dataProviderObject.SetProperty(property.DescriptorName, value); + } + } +} diff --git a/ZuneUI/DataProviderPropertyComparer.cs b/ZuneUI/DataProviderPropertyComparer.cs new file mode 100644 index 0000000..2dbe017 --- /dev/null +++ b/ZuneUI/DataProviderPropertyComparer.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DataProviderPropertyComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class DataProviderPropertyComparer : IComparer + { + private string _propertyName; + + public DataProviderPropertyComparer() + { + } + + public DataProviderPropertyComparer(string propertyName) => this._propertyName = propertyName; + + public string PropertyName + { + get => this._propertyName; + set => this._propertyName = value; + } + + public int Compare(object x, object y) + { + DataProviderObject dataProviderObject1 = x as DataProviderObject; + DataProviderObject dataProviderObject2 = y as DataProviderObject; + if (dataProviderObject1 != null && dataProviderObject2 != null) + { + object property1 = dataProviderObject1.GetProperty(this.PropertyName); + object property2 = dataProviderObject2.GetProperty(this.PropertyName); + if (property1 is IComparable comparable) + return comparable.CompareTo(property2); + if (object.Equals(property1, property2)) + return 0; + } + return 1; + } + } +} diff --git a/ZuneUI/DataProviderTitleList.cs b/ZuneUI/DataProviderTitleList.cs new file mode 100644 index 0000000..03542b0 --- /dev/null +++ b/ZuneUI/DataProviderTitleList.cs @@ -0,0 +1,80 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DataProviderTitleList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class DataProviderTitleList : IList, ICollection, IEnumerable + { + private List _dataProviders = new List(); + + public IList DataProviders => (IList)this._dataProviders; + + public void InitializeDataProviders(IList list) + { + this._dataProviders = new List(); + foreach (object obj in (IEnumerable)list) + this._dataProviders.Add(obj as DataProviderObject); + } + + public int Add(object value) => throw new NotImplementedException(); + + public void Clear() => this._dataProviders.Clear(); + + public bool Contains(object value) => this.IndexOf(value) >= 0; + + public int IndexOf(object value) + { + string b = value as string; + for (int index = 0; index < this._dataProviders.Count; ++index) + { + if (string.Equals((string)this._dataProviders[index].GetProperty("Title"), b, StringComparison.CurrentCultureIgnoreCase)) + return index; + } + return -1; + } + + public void Insert(int index, object value) => throw new NotImplementedException(); + + public bool IsFixedSize => ((IList)this._dataProviders).IsFixedSize; + + public bool IsReadOnly => ((IList)this._dataProviders).IsReadOnly; + + public void Remove(object value) + { + int index = this.IndexOf((object)(value as string)); + if (index < 0) + return; + this._dataProviders.RemoveAt(index); + } + + public void RemoveAt(int index) => this._dataProviders.RemoveAt(index); + + public object this[int index] + { + get => this._dataProviders[index].GetProperty("Title"); + set => throw new NotImplementedException(); + } + + public void CopyTo(Array array, int index) => throw new NotImplementedException(); + + public int Count => this._dataProviders.Count; + + public bool IsSynchronized => ((ICollection)this._dataProviders).IsSynchronized; + + public object SyncRoot => ((ICollection)this._dataProviders).SyncRoot; + + public IEnumerator GetEnumerator() + { + for (int i = 0; i < this._dataProviders.Count; ++i) + yield return this._dataProviders[i].GetProperty("Title"); + } + } +} diff --git a/ZuneUI/DatapointInfo.cs b/ZuneUI/DatapointInfo.cs new file mode 100644 index 0000000..b52dc63 --- /dev/null +++ b/ZuneUI/DatapointInfo.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DatapointInfo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal class DatapointInfo + { + private ETelemetryEvent _event; + private string _typeName; + private bool _fSession; + + public DatapointInfo(ETelemetryEvent evt) + { + this._event = evt; + this._typeName = ""; + this._fSession = false; + } + + public DatapointInfo(ETelemetryEvent evt, string typeName, bool fSess) + { + this._event = evt; + this._typeName = typeName; + this._fSession = fSess; + } + + public ETelemetryEvent Event + { + get => this._event; + set => this._event = value; + } + + public string TypeName + { + get => this._typeName; + set => this._typeName = value; + } + + public bool IsSession + { + get => this._fSession; + set => this._fSession = value; + } + } +} diff --git a/ZuneUI/DatePropertyDescriptor.cs b/ZuneUI/DatePropertyDescriptor.cs new file mode 100644 index 0000000..8f06fa1 --- /dev/null +++ b/ZuneUI/DatePropertyDescriptor.cs @@ -0,0 +1,49 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DatePropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class DatePropertyDescriptor : PropertyDescriptor + { + private DateTimeKind timeZoneOverride; + + public DatePropertyDescriptor(string name, string multiValueString, string unknownString) + : base(name, multiValueString, unknownString, 1000, false, (object)DateTime.MinValue) + { + } + + public DatePropertyDescriptor( + string name, + string multiValueString, + string unknownString, + DateTimeKind timeZoneOverride) + : base(name, multiValueString, unknownString, 1000, false, (object)DateTime.MinValue) + { + this.timeZoneOverride = timeZoneOverride; + } + + public DatePropertyDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : base(name, multiValueString, unknownString, 1000, required, (object)DateTime.MinValue) + { + } + + public override string ConvertToString(object value) => StringFormatHelper.FormatShortDate((DateTime)value, this.UnknownString); + + public override object ConvertFromString(string value) + { + DateTime dateTime; + return StringParserHelper.TryParseDate(value, this.timeZoneOverride, out dateTime) ? (object)dateTime : (object)DateTime.MinValue; + } + + public override bool IsValidInternal(string value) => StringParserHelper.IsNullOrEmptyOrBlank(value) || StringParserHelper.TryParseDate(value, out DateTime _); + } +} diff --git a/ZuneUI/DateTimeFormatType.cs b/ZuneUI/DateTimeFormatType.cs new file mode 100644 index 0000000..152d62e --- /dev/null +++ b/ZuneUI/DateTimeFormatType.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DateTimeFormatType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum DateTimeFormatType + { + ShortDate, + LongDate, + FullLongDateLongTime, + MonthDay, + ShortTime, + LongTime, + YearMonth, + } +} diff --git a/ZuneUI/DateTimeHelper.cs b/ZuneUI/DateTimeHelper.cs new file mode 100644 index 0000000..34fe728 --- /dev/null +++ b/ZuneUI/DateTimeHelper.cs @@ -0,0 +1,110 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DateTimeHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Globalization; +using System.Text.RegularExpressions; + +namespace ZuneUI +{ + public static class DateTimeHelper + { + private static string _unknown = Shell.LoadString(StringId.IDS_TYPE_UNKNOWN); + + public static bool IsEmpty(DateTime date) => date == DateTime.MinValue; + + public static DateTime Empty => DateTime.MinValue; + + public static string GetDisplayPattern(string cultureString) + { + string str1 = (string)null; + CultureInfo cultureInfo = (CultureInfo)null; + if (!string.IsNullOrEmpty(cultureString)) + { + try + { + cultureInfo = new CultureInfo(cultureString, false); + } + catch + { + } + } + if (cultureInfo == null) + cultureInfo = CultureInfo.CurrentUICulture; + if (cultureInfo != null) + { + string newValue = Shell.LoadString(StringId.IDS_DATETIME_YEAR_ABBREVIATION); + string str2 = Shell.LoadString(StringId.IDS_DATETIME_MONTH_ABBREVIATION); + string str3 = Shell.LoadString(StringId.IDS_DATETIME_DAY_ABBREVIATION); + str1 = Regex.Replace(Regex.Replace(cultureInfo.DateTimeFormat.ShortDatePattern.Replace("y", newValue), "M{1,2}", str2 + str2), "d{1,2}", str3 + str3); + } + return str1; + } + + public static bool TryParse(string dateTimeString, string cultureString, out DateTime dateTime) + { + bool flag = false; + CultureInfo culture = CultureHelper.GetCulture(cultureString); + dateTime = DateTime.MaxValue; + if (culture != null) + { + string format = Regex.Replace(Regex.Replace(culture.DateTimeFormat.ShortDatePattern, "M{1,2}", "M"), "d{1,2}", "d"); + flag = DateTime.TryParseExact(dateTimeString, format, (IFormatProvider)culture, DateTimeStyles.None, out dateTime); + } + return flag; + } + + public static string ToString(DateTime dateTime, DateTimeFormatType format) => DateTimeHelper.ToString(dateTime, (string)null, format); + + public static string ToString( + DateTime dateTime, + string cultureString, + DateTimeFormatType format) + { + string str = (string)null; + CultureInfo culture = CultureHelper.GetCulture(cultureString); + try + { + if (culture != null) + { + string format1; + switch (format) + { + case DateTimeFormatType.ShortDate: + format1 = culture.DateTimeFormat.ShortDatePattern; + break; + case DateTimeFormatType.LongDate: + format1 = culture.DateTimeFormat.LongDatePattern; + break; + case DateTimeFormatType.FullLongDateLongTime: + format1 = culture.DateTimeFormat.FullDateTimePattern; + break; + case DateTimeFormatType.MonthDay: + format1 = culture.DateTimeFormat.MonthDayPattern; + break; + case DateTimeFormatType.ShortTime: + format1 = culture.DateTimeFormat.ShortTimePattern; + break; + case DateTimeFormatType.LongTime: + format1 = culture.DateTimeFormat.LongTimePattern; + break; + case DateTimeFormatType.YearMonth: + format1 = culture.DateTimeFormat.YearMonthPattern; + break; + default: + throw new ArgumentException(); + } + str = dateTime.ToString(format1, (IFormatProvider)culture); + } + } + catch (ArgumentOutOfRangeException ex) + { + str = DateTimeHelper._unknown; + } + return str; + } + } +} diff --git a/ZuneUI/DefaultExperienceNavigationCommandHandler.cs b/ZuneUI/DefaultExperienceNavigationCommandHandler.cs new file mode 100644 index 0000000..13d5f85 --- /dev/null +++ b/ZuneUI/DefaultExperienceNavigationCommandHandler.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DefaultExperienceNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class DefaultExperienceNavigationCommandHandler : ICommandHandler + { + private Experience _experience; + + public Experience Experience + { + get => this._experience; + set => this._experience = value; + } + + public void Execute(string command, IDictionary commandArgs) => ((Command)this._experience.Nodes.ChosenValue).Invoke(); + } +} diff --git a/ZuneUI/DelegateFuture`1.cs b/ZuneUI/DelegateFuture`1.cs new file mode 100644 index 0000000..0ba1551 --- /dev/null +++ b/ZuneUI/DelegateFuture`1.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DelegateFuture`1 +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DelegateFuture : FutureBase + { + private ZuneUI.CalculateValue _delegate; + + public DelegateFuture(ZuneUI.CalculateValue calculateMethod) => this._delegate = calculateMethod; + + protected override T CalculateValue() => this._delegate(); + } +} diff --git a/ZuneUI/DeleteSubscriptionDownloadsDialog.cs b/ZuneUI/DeleteSubscriptionDownloadsDialog.cs new file mode 100644 index 0000000..a723849 --- /dev/null +++ b/ZuneUI/DeleteSubscriptionDownloadsDialog.cs @@ -0,0 +1,80 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeleteSubscriptionDownloadsDialog +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using UIXControls; + +namespace ZuneUI +{ + public class DeleteSubscriptionDownloadsDialog : DialogHelper + { + private Command m_delete; + private string m_title; + private bool m_enabled; + + public static void ShowDialog() + { + string subscriptionDirectory = ZuneApplication.Service.GetSubscriptionDirectory(); + if (string.IsNullOrEmpty(subscriptionDirectory)) + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_ACCOUNT_CLEAR_SUB_FAIL_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_ACCOUNT_CLEAR_SUB_NO_DIRECTORY), (EventHandler)null); + else + new DeleteSubscriptionDownloadsDialog(subscriptionDirectory).Show(); + } + + public Command Delete => this.m_delete; + + public bool Enabled + { + get => this.m_enabled; + private set + { + if (this.m_enabled == value) + return; + this.Delete.Available = value; + this.Cancel.Available = value; + this.m_enabled = value; + this.FirePropertyChanged(nameof(Enabled)); + } + } + + public string Title => this.m_title; + + protected DeleteSubscriptionDownloadsDialog(string subscriptionDirectory) + : base("res://ZuneShellResources!ManagementAccount.uix#DeleteSubscriptionDownloadsDialogContentUI") + { + this.m_enabled = true; + this.m_title = ZuneUI.Shell.LoadString(StringId.IDS_ACCOUNT_CLEAR_SUBSCRIPTION_TITLE); + this.Description = string.Format(ZuneUI.Shell.LoadString(StringId.IDS_ACCOUNT_CLEAR_SUBSCRIPTION_CONFIRM), (object)subscriptionDirectory); + this.m_delete = new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_DIALOG_OK), new EventHandler(this.OnDeleteInvoked)); + this.Cancel.Invoked += new EventHandler(this.OnCancel); + } + + private void OnCancel(object sender, EventArgs args) => this.Hide(); + + private void OnDeleteInvoked(object sender, EventArgs args) + { + if (!this.Enabled) + return; + this.Enabled = false; + ZuneApplication.Service.DeleteSubscriptionDownloads(new AsyncCompleteHandler(this.OnDeleteComplete)); + } + + private void OnDeleteComplete(HRESULT hr) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredDeleteCompleteEvent), (object)hr); + + private void DeferredDeleteCompleteEvent(object arg) + { + this.Enabled = true; + HRESULT hresult = (HRESULT)arg; + this.Hide(); + if (!hresult.IsError) + return; + ZuneUI.Shell.ShowErrorDialog(hresult.Int, StringId.IDS_ACCOUNT_CLEAR_SUB_FAIL_TITLE, StringId.IDS_ACCOUNT_CLEAR_SUB_FAIL_MESSAGE); + } + } +} diff --git a/ZuneUI/DetailsBackedSchemaSyncGroup.cs b/ZuneUI/DetailsBackedSchemaSyncGroup.cs new file mode 100644 index 0000000..0406285 --- /dev/null +++ b/ZuneUI/DetailsBackedSchemaSyncGroup.cs @@ -0,0 +1,169 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DetailsBackedSchemaSyncGroup +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; + +namespace ZuneUI +{ + public class DetailsBackedSchemaSyncGroup : SchemaSyncGroup + { + private SyncRulesView _view; + private int _index; + private SyncRuleDetails _model; + private bool _inOverfill; + private System.Collections.Generic.List _masterList; + private System.Collections.Generic.List _sortedList; + private Timer _resortTimer; + private bool _active; + private bool _updatingActive; + + public DetailsBackedSchemaSyncGroup( + SyncGroupList list, + SyncRulesView view, + SyncCategory type, + bool inOverfill) + : base(list, type) + { + this._view = view; + this._index = -1; + this._inOverfill = inOverfill; + this._resortTimer = new Timer((IModelItemOwner)this); + this._resortTimer.AutoRepeat = false; + this._resortTimer.Tick += new EventHandler(this.OnResortTimerTick); + this._resortTimer.Interval = 527; + this._masterList = new System.Collections.Generic.List(); + this._sortedList = new System.Collections.Generic.List(); + this._active = true; + } + + public override long Size => this.State != SyncGroupState.Calculated ? -1L : this._model.totalSize; + + public override int Count => this.State != SyncGroupState.Calculated ? -1 : (int)this._model.totalItems; + + public override SyncGroupState State => this._model == null || !this._model.calculated ? SyncGroupState.Uncalculated : SyncGroupState.Calculated; + + public override bool IsActive + { + get => this._active; + set + { + if (this._active == value) + return; + this._active = value; + this._updatingActive = true; + foreach (SyncGroup master in this._masterList) + { + if (master.IsVisible) + master.IsActive = this._active; + } + this._updatingActive = false; + this.Sort(true); + this.FirePropertyChanged(nameof(IsActive)); + } + } + + public override bool IsVisible => true; + + public System.Collections.Generic.List List + { + get => this._sortedList; + private set + { + if (this._sortedList == value) + return; + this._sortedList = value; + this.FirePropertyChanged(nameof(List)); + } + } + + public override void CommitChanges() + { + foreach (SyncGroup master in this._masterList) + master.CommitChanges(); + } + + public override void CancelChanges() + { + foreach (SyncGroup master in this._masterList) + master.CancelChanges(); + } + + public override void DataUpdated() + { + if (this._index == -1) + return; + this._model = this._view.GetItem(this._index); + this.FirePropertyChanged("Size"); + this.FirePropertyChanged("Count"); + this.FirePropertyChanged("State"); + this.FirePropertyChanged("IsActive"); + } + + public void AssignDetails(int index) + { + this._index = index; + this.DataUpdated(); + } + + public void Add(SyncGroup group) + { + this._masterList.Add(group); + this._sortedList.Add(group); + this.Sort(false); + } + + public void Sort(bool immediately) + { + if (!immediately) + { + if (this._resortTimer.Enabled) + return; + this._resortTimer.Start(); + } + else + { + this._resortTimer.Stop(); + System.Collections.Generic.List syncGroupList = new System.Collections.Generic.List(this._masterList.Count); + foreach (SyncGroup master in this._masterList) + { + if ((master.IsActive || this._inOverfill) && master.IsVisible) + syncGroupList.Add(master); + } + syncGroupList.Sort(); + this.List = syncGroupList; + if (this.List.Count != 0) + return; + this.IsExpanded = false; + } + } + + public void UpdateActiveState() + { + if (this._updatingActive) + return; + bool flag1 = false; + bool flag2 = false; + foreach (SyncGroup master in this._masterList) + { + if (master.IsVisible) + { + flag2 = true; + if (master.IsActive) + { + flag1 = true; + break; + } + } + } + this._active = flag1 || !flag2; + this.FirePropertyChanged("IsActive"); + } + + private void OnResortTimerTick(object sender, EventArgs e) => this.Sort(true); + } +} diff --git a/ZuneUI/DeviceAwareNavigationHandler.cs b/ZuneUI/DeviceAwareNavigationHandler.cs new file mode 100644 index 0000000..e9a72f4 --- /dev/null +++ b/ZuneUI/DeviceAwareNavigationHandler.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceAwareNavigationHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class DeviceAwareNavigationHandler : NavigationCommandHandlerBase + { + private bool _showDeviceContents; + + public bool ShowDeviceContents + { + get => this._showDeviceContents; + set => this._showDeviceContents = value; + } + } +} diff --git a/ZuneUI/DeviceBranding.cs b/ZuneUI/DeviceBranding.cs new file mode 100644 index 0000000..07d9310 --- /dev/null +++ b/ZuneUI/DeviceBranding.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceBranding +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum DeviceBranding + { + Zune, + WindowsPhone, + Kin, + } +} diff --git a/ZuneUI/DeviceChoice.cs b/ZuneUI/DeviceChoice.cs new file mode 100644 index 0000000..018ba00 --- /dev/null +++ b/ZuneUI/DeviceChoice.cs @@ -0,0 +1,78 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceChoice +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public class DeviceChoice : Choice + { + public DeviceChoice() + : this((IModelItemOwner)null) + { + } + + public DeviceChoice(IModelItemOwner owner) + : base(owner) + { + UIDeviceList instance = SingletonModelItem.Instance; + instance.DeviceAddedEvent += new DeviceListEventHandler(this.ListChanged); + instance.DeviceRemovedEvent += new DeviceListEventHandler(this.ListChanged); + SyncControls.Instance.PropertyChanged += new PropertyChangedEventHandler(this.OnSyncPropertyChanged); + this.BuildOptions(); + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + SyncControls.Instance.PropertyChanged -= new PropertyChangedEventHandler(this.OnSyncPropertyChanged); + UIDeviceList instance = SingletonModelItem.Instance; + instance.DeviceAddedEvent -= new DeviceListEventHandler(this.ListChanged); + instance.DeviceRemovedEvent -= new DeviceListEventHandler(this.ListChanged); + } + base.OnDispose(disposing); + } + + private void ListChanged(object sender, DeviceListEventArgs args) => this.BuildOptions(); + + private void OnSyncPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "CurrentDevice")) + return; + for (int index = 0; index < this.Options.Count; ++index) + { + if ((UIDevice)this.Options[index] == SyncControls.Instance.CurrentDevice) + { + this.ChosenIndex = index; + break; + } + } + } + + private void BuildOptions() + { + UIDeviceList instance = SingletonModelItem.Instance; + this.Options = (IList)new ArrayListDataSet((IModelItemOwner)this); + foreach (UIDevice uiDevice in instance) + { + this.Options.Add((object)uiDevice); + if (uiDevice == SyncControls.Instance.CurrentDevice) + this.ChosenValue = (object)uiDevice; + } + } + + protected override void OnChosenChanged() + { + base.OnChosenChanged(); + if (this.ChosenValue == null) + return; + SyncControls.Instance.SetCurrentDevice((UIDevice)this.ChosenValue); + } + } +} diff --git a/ZuneUI/DeviceClass.cs b/ZuneUI/DeviceClass.cs new file mode 100644 index 0000000..97980a5 --- /dev/null +++ b/ZuneUI/DeviceClass.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceClass +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum DeviceClass + { + Invalid = -1, // 0xFFFFFFFF + Reserved = 0, + Classic = 1, + ZuneHD = 2, + WindowsPhone = 4, + Kin = 5, + } +} diff --git a/ZuneUI/DeviceComparerForRental.cs b/ZuneUI/DeviceComparerForRental.cs new file mode 100644 index 0000000..86eb2ae --- /dev/null +++ b/ZuneUI/DeviceComparerForRental.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceComparerForRental +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class DeviceComparerForRental : IComparer + { + public int Compare(object x, object y) + { + int num = 0; + UIDevice uiDevice1 = x as UIDevice; + UIDevice uiDevice2 = y as UIDevice; + if (uiDevice1 != null && uiDevice2 != null) + { + bool supportsRental1 = uiDevice1.SupportsRental; + bool supportsRental2 = uiDevice2.SupportsRental; + num = !supportsRental1 || supportsRental2 ? (!supportsRental2 || supportsRental1 ? uiDevice1.Name.CompareTo(uiDevice2.Name) : 1) : -1; + } + return num; + } + } +} diff --git a/ZuneUI/DeviceConnectionHandledEventArgs.cs b/ZuneUI/DeviceConnectionHandledEventArgs.cs new file mode 100644 index 0000000..fe3a4b4 --- /dev/null +++ b/ZuneUI/DeviceConnectionHandledEventArgs.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceConnectionHandledEventArgs +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal class DeviceConnectionHandledEventArgs + { + public readonly UIDevice Device; + public readonly bool IsFirstConnect; + + public DeviceConnectionHandledEventArgs(UIDevice device, bool isFirstConnect) + { + this.Device = device; + this.IsFirstConnect = isFirstConnect; + } + } +} diff --git a/ZuneUI/DeviceConnectionHandledEventHandler.cs b/ZuneUI/DeviceConnectionHandledEventHandler.cs new file mode 100644 index 0000000..ab77279 --- /dev/null +++ b/ZuneUI/DeviceConnectionHandledEventHandler.cs @@ -0,0 +1,12 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceConnectionHandledEventHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal delegate void DeviceConnectionHandledEventHandler( + object sender, + DeviceConnectionHandledEventArgs args); +} diff --git a/ZuneUI/DeviceExperience.cs b/ZuneUI/DeviceExperience.cs new file mode 100644 index 0000000..ee7f205 --- /dev/null +++ b/ZuneUI/DeviceExperience.cs @@ -0,0 +1,120 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceExperience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public class DeviceExperience : CollectionExperience + { + private ArrayListDataSet _nodes; + private Node _status; + private Node _friends; + + public DeviceExperience(Frame frameOwner) + : base(frameOwner, true) + => SyncControls.Instance.PropertyChanged += new PropertyChangedEventHandler(this.OnSyncPropertyChanged); + + protected override void OnDispose(bool disposing) + { + SyncControls.Instance.PropertyChanged -= new PropertyChangedEventHandler(this.OnSyncPropertyChanged); + base.OnDispose(disposing); + } + + public override IList NodesList + { + get + { + if (this._nodes == null) + { + this._nodes = new ArrayListDataSet((IModelItemOwner)this); + this._nodes.Add((object)this.Status); + this._nodes.Add((object)this.Music); + this._nodes.Add((object)this.Videos); + this._nodes.Add((object)this.Photos); + this._nodes.Add((object)this.Podcasts); + this.UpdateDeviceDependentPivots(); + } + return (IList)this._nodes; + } + } + + public Node Status + { + get + { + if (this._status == null) + this._status = new Node((Experience)this, StringId.IDS_SYNC_STATUS_PIVOT, "Device\\Status", SQMDataId.DeviceStatusClicks); + return this._status; + } + } + + public Node Friends + { + get + { + if (this._friends == null) + this._friends = new Node((Experience)this, StringId.IDS_FRIENDS_PIVOT, "Device\\Friends", SQMDataId.DeviceFriendsClicks); + return this._friends; + } + } + + protected override void OnInvoked() + { + ((MainFrame)this.Frame).ShowDevice(true); + base.OnInvoked(); + } + + protected override void OnIsCurrentChanged() + { + this.UpdateShowDevice(); + base.OnIsCurrentChanged(); + } + + public void UpdateShowDevice() => ((MainFrame)this.Frame).ShowDevice(this.IsCurrent || this.AreAnyDevicesConnected()); + + public bool AreAnyDevicesConnected() + { + foreach (UIDevice uiDevice in SingletonModelItem.Instance) + { + if (uiDevice.IsConnectedToPC) + return true; + } + return false; + } + + private void OnSyncPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "CurrentDevice")) + return; + this.UpdateDeviceDependentPivots(); + this.Description = SyncControls.Instance.CurrentDevice.PivotDescription; + } + + private void UpdateDeviceDependentPivots() + { + UIDevice currentDevice = SyncControls.Instance.CurrentDevice; + if (this.NodesList.Contains((object)this.Applications)) + this.NodesList.Remove((object)this.Applications); + if (this.NodesList.Contains((object)this.Friends)) + this.NodesList.Remove((object)this.Friends); + if (this.NodesList.Contains((object)this.Channels)) + this.NodesList.Remove((object)this.Channels); + if (FeatureEnablement.IsFeatureEnabled(Features.eSocial) && currentDevice.SupportsUserCards) + this.NodesList.Add((object)this.Friends); + if (FeatureEnablement.IsFeatureEnabled(Features.eChannels) && currentDevice.SupportsChannels) + this.NodesList.Add((object)this.Channels); + if (!FeatureEnablement.IsFeatureEnabled(Features.eGames) || !currentDevice.SupportsSyncApplications) + return; + this.NodesList.Add((object)this.Applications); + } + + public override string DefaultUIPath => "Device\\Status"; + } +} diff --git a/ZuneUI/DeviceIconSetFactory.cs b/ZuneUI/DeviceIconSetFactory.cs new file mode 100644 index 0000000..0f623cd --- /dev/null +++ b/ZuneUI/DeviceIconSetFactory.cs @@ -0,0 +1,620 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceIconSetFactory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; +using System.Collections.Generic; +using System.IO; + +namespace ZuneUI +{ + internal static class DeviceIconSetFactory + { + private const int _reasonableMaximumSurfaceSize = 1024; + private static List _builders = new List(); + private static DeviceIconSetFactory.DeviceIconSizeConstraint _backgroundConstraint = new DeviceIconSetFactory.DeviceIconSizeConstraint(2, 1023, 2, 1023); + private static DeviceIconSetFactory.DeviceIconSizeConstraint _largeConstraint = new DeviceIconSetFactory.DeviceIconSizeConstraint(100, 225, 265, 400); + private static DeviceIconSetFactory.DeviceIconSizeConstraint _mediumConstraint = new DeviceIconSetFactory.DeviceIconSizeConstraint(50, 110, 50, 200); + private static DeviceIconSetFactory.DeviceIconSizeConstraint _smallConstraint = new DeviceIconSetFactory.DeviceIconSizeConstraint(15, 42, 25, 49); + private static DeviceIconSetFactory.DeviceIconSet _defaultIconSet = new DeviceIconSetFactory.DeviceIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Large.Default.png"), new Image("res://ZuneShellResources!DefaultDevice.Large.Disconnected.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Medium.Default.png"), new Image("res://ZuneShellResources!DefaultDevice.Medium.Unsupported.png")), (IInteractiveDeviceIconSet)new DeviceIconSetFactory.InteractiveIconSet((IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Default.png"), new Image("res://ZuneShellResources!DefaultDevice.Disconnected.Default.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Default.Dark.png"), new Image("res://ZuneShellResources!DefaultDevice.Disconnected.Default.Dark.png"))), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Hover.png"), new Image("res://ZuneShellResources!DefaultDevice.Disconnected.Hover.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Hover.Dark.png"), new Image("res://ZuneShellResources!DefaultDevice.Disconnected.Hover.Dark.png"))), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Drag.png"), new Image("res://ZuneShellResources!DefaultDevice.Disconnected.Drag.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Drag.Dark.png"), new Image("res://ZuneShellResources!DefaultDevice.Disconnected.Drag.Dark.png"))), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Click.png"), new Image("res://ZuneShellResources!DefaultDevice.Disconnected.Click.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Click.Dark.png"), new Image("res://ZuneShellResources!DefaultDevice.Disconnected.Click.Dark.png"))), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Syncing.png"), new Image("res://ZuneShellResources!DefaultDevice.Connected.Syncing.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!DefaultDevice.Connected.Syncing.Dark.png"), new Image("res://ZuneShellResources!DefaultDevice.Connected.Syncing.Dark.png")))), new Image("res://ZuneShellResources!DefaultDevice.Background.png"), (IColorSet)new DeviceIconSetFactory.ColorSet((IDeviceColor)new DeviceIconSetFactory.DeviceColor((byte)87, (byte)87, (byte)87), (IDeviceColor)new DeviceIconSetFactory.DeviceColor((byte)0, (byte)0, (byte)2), (IDeviceColor)new DeviceIconSetFactory.DeviceColor((byte)0, (byte)0, (byte)2), (IDeviceColor)new DeviceIconSetFactory.DeviceColor((byte)0, (byte)0, (byte)2))); + private static DeviceIconSetFactory.DeviceIconSet _unloadedIconSet = new DeviceIconSetFactory.DeviceIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Large.Default.png"), new Image("res://ZuneShellResources!Unloaded.Large.Disconnected.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Medium.Default.png"), new Image("res://ZuneShellResources!Unloaded.Medium.Unsupported.png")), (IInteractiveDeviceIconSet)new DeviceIconSetFactory.InteractiveIconSet((IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Default.png"), new Image("res://ZuneShellResources!Unloaded.Disconnected.Default.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Default.Dark.png"), new Image("res://ZuneShellResources!Unloaded.Disconnected.Default.Dark.png"))), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Hover.png"), new Image("res://ZuneShellResources!Unloaded.Disconnected.Hover.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Hover.Dark.png"), new Image("res://ZuneShellResources!Unloaded.Disconnected.Hover.Dark.png"))), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Drag.png"), new Image("res://ZuneShellResources!Unloaded.Disconnected.Drag.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Drag.Dark.png"), new Image("res://ZuneShellResources!Unloaded.Disconnected.Drag.Dark.png"))), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Click.png"), new Image("res://ZuneShellResources!Unloaded.Disconnected.Click.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Click.Dark.png"), new Image("res://ZuneShellResources!Unloaded.Disconnected.Click.Dark.png"))), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Syncing.png"), new Image("res://ZuneShellResources!Unloaded.Connected.Syncing.png")), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(new Image("res://ZuneShellResources!Unloaded.Connected.Syncing.Dark.png"), new Image("res://ZuneShellResources!Unloaded.Connected.Syncing.Dark.png")))), new Image("res://ZuneShellResources!Unloaded.Background.png"), (IColorSet)new DeviceIconSetFactory.ColorSet((IDeviceColor)new DeviceIconSetFactory.DeviceColor((byte)87, (byte)87, (byte)87), (IDeviceColor)new DeviceIconSetFactory.DeviceColor((byte)0, (byte)0, (byte)2), (IDeviceColor)new DeviceIconSetFactory.DeviceColor((byte)0, (byte)0, (byte)2), (IDeviceColor)new DeviceIconSetFactory.DeviceColor((byte)0, (byte)0, (byte)2))); + + public static IDeviceIconSet BuildDeviceIconSet( + DeviceAssetSet assetSet, + DeviceIconSetFactory.DeviceIconSetConstructionCompletedCallback callback) + { + DeviceIconSetFactory.DeviceIconSetBuilder builder = new DeviceIconSetFactory.DeviceIconSetBuilder(); + DeviceIconSetFactory._builders.Add(builder); + builder.BuildIconSet(assetSet, (DeviceIconSetFactory.DeviceIconSetConstructionCompletedCallback)(result => + { + callback(result); + DeviceIconSetFactory._builders.Remove(builder); + })); + return DeviceIconSetFactory.UnloadedIconSet; + } + + public static IDeviceIconSet DefaultIconSet => (IDeviceIconSet)DeviceIconSetFactory._defaultIconSet; + + private static IDeviceIconSet UnloadedIconSet => (IDeviceIconSet)DeviceIconSetFactory._unloadedIconSet; + + internal delegate void DeviceIconSetConstructionCompletedCallback(IDeviceIconSet iconSet); + + private class DeviceIconSetBuilder + { + private DeviceAssetSet _assetSet; + private DeviceIconSetFactory.DeviceIconSetConstructionCompletedCallback _callback; + private DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier _loader; + private IInteractiveDeviceIconSet _smallImageSubset; + private DeviceIconSetFactory.DeviceIconSetBuilder.DetailedImages _detailedImageSubset; + private DeviceIconSetFactory.DeviceIconSetBuilder.BackgroundImageAndColors _backgroundImageAndColorSubset; + private static readonly DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint[] _smallImagesToLoad = new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint[18] + { + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedDefault, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageDisconnectedDefault, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedDefaultDark, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageDisconnectedDefaultDark, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedHover, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageDisconnectedHover, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedHoverDark, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageDisconnectedHoverDark, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedDrag, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageDisconnectedDrag, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedDragDark, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageDisconnectedDragDark, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedClick, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageDisconnectedClick, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedClickDark, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageDisconnectedClickDark, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedSyncing, DeviceIconSetFactory._smallConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageConnectedSyncingDark, DeviceIconSetFactory._smallConstraint) + }; + private static readonly DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint[] _detailedImagesToLoad = new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint[4] + { + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageMediumDefault, DeviceIconSetFactory._mediumConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageMediumUnsupported, DeviceIconSetFactory._mediumConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageLargeDefault, DeviceIconSetFactory._largeConstraint), + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageLargeDisconnected, DeviceIconSetFactory._largeConstraint) + }; + private static readonly DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint[] _backgroundImagesToLoad = new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint[1] + { + new DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint(DeviceAssetImages.eDeviceAssetImageBackground, DeviceIconSetFactory._backgroundConstraint) + }; + + public DeviceIconSetBuilder() => this._loader = new DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier(); + + public void BuildIconSet( + DeviceAssetSet assetSet, + DeviceIconSetFactory.DeviceIconSetConstructionCompletedCallback callback) + { + if (!Application.IsApplicationThread) + throw new Exception("DeviceIconSet loading is only supported on the application thread. This feature is not thread-safe."); + if (this._assetSet != null) + throw new Exception("BuildIconSet was called while a set was already being built. Calls to BuildIconSet cannot be reentrant."); + if (assetSet == null) + throw new ArgumentNullException(nameof(assetSet)); + if (callback == null) + throw new ArgumentNullException(nameof(callback)); + this._assetSet = assetSet; + this._callback = callback; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.LoadSmallImages(); + }, (object)null); + } + + private void End() + { + DeviceIconSetFactory.DeviceIconSetConstructionCompletedCallback callback = this._callback; + IDeviceIconSet result = (IDeviceIconSet)null; + result = this._smallImageSubset == null || this._detailedImageSubset == null || this._backgroundImageAndColorSubset == null ? DeviceIconSetFactory.DefaultIconSet : (IDeviceIconSet)new DeviceIconSetFactory.DeviceIconSet(this._detailedImageSubset.LargeImages, this._detailedImageSubset.MediumImages, this._smallImageSubset, this._backgroundImageAndColorSubset.BackgroundImage, this._backgroundImageAndColorSubset.Colors); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + callback(result); + }, (object)null); + this._assetSet = (DeviceAssetSet)null; + this._callback = (DeviceIconSetFactory.DeviceIconSetConstructionCompletedCallback)null; + } + + private void LoadSmallImages() => this._loader.LoadAndVerify((IList)this._assetSet.ImageUris, (IList)DeviceIconSetFactory.DeviceIconSetBuilder._smallImagesToLoad, new DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler(this.SmallCustomImageLoadComplete)); + + private void SmallCustomImageLoadComplete(IDictionary images) + { + if (images != null) + { + this._smallImageSubset = this.ConstructSmallImageSubset(images); + this.LoadDetailedImages(); + } + else + this._loader.LoadAndVerify((IList)this._assetSet.DefaultImageUris, (IList)DeviceIconSetFactory.DeviceIconSetBuilder._smallImagesToLoad, new DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler(this.SmallDefaultImageLoadComplete)); + } + + private void SmallDefaultImageLoadComplete(IDictionary images) + { + this._smallImageSubset = images == null ? DeviceIconSetFactory.DefaultIconSet.Small : this.ConstructSmallImageSubset(images); + this.LoadDetailedImages(); + } + + private IInteractiveDeviceIconSet ConstructSmallImageSubset( + IDictionary images) + { + return (IInteractiveDeviceIconSet)new DeviceIconSetFactory.InteractiveIconSet((IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedDefault], images[DeviceAssetImages.eDeviceAssetImageDisconnectedDefault]), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedDefaultDark], images[DeviceAssetImages.eDeviceAssetImageDisconnectedDefaultDark])), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedHover], images[DeviceAssetImages.eDeviceAssetImageDisconnectedHover]), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedHoverDark], images[DeviceAssetImages.eDeviceAssetImageDisconnectedHoverDark])), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedDrag], images[DeviceAssetImages.eDeviceAssetImageDisconnectedDrag]), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedDragDark], images[DeviceAssetImages.eDeviceAssetImageDisconnectedDragDark])), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedClick], images[DeviceAssetImages.eDeviceAssetImageDisconnectedClick]), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedClickDark], images[DeviceAssetImages.eDeviceAssetImageDisconnectedClickDark])), (IBackgroundAwareDeviceIconSet)new DeviceIconSetFactory.BackgroundAwareIconSet((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedSyncing], images[DeviceAssetImages.eDeviceAssetImageConnectedSyncing]), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageConnectedSyncingDark], images[DeviceAssetImages.eDeviceAssetImageConnectedSyncingDark]))); + } + + private void LoadDetailedImages() => this._loader.LoadAndVerify((IList)this._assetSet.ImageUris, (IList)DeviceIconSetFactory.DeviceIconSetBuilder._detailedImagesToLoad, new DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler(this.DetailedCustomImageLoadComplete)); + + private void DetailedCustomImageLoadComplete(IDictionary images) + { + if (images != null) + { + this._detailedImageSubset = this.ConstructDetailedImageSubset(images); + this.LoadBackgroundImageAndColors(); + } + else + this._loader.LoadAndVerify((IList)this._assetSet.DefaultImageUris, (IList)DeviceIconSetFactory.DeviceIconSetBuilder._detailedImagesToLoad, new DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler(this.DetailedDefaultImageLoadComplete)); + } + + private void DetailedDefaultImageLoadComplete(IDictionary images) + { + this._detailedImageSubset = images == null ? new DeviceIconSetFactory.DeviceIconSetBuilder.DetailedImages(DeviceIconSetFactory.DefaultIconSet.Medium, DeviceIconSetFactory.DefaultIconSet.Large) : this.ConstructDetailedImageSubset(images); + this.LoadBackgroundImageAndColors(); + } + + private DeviceIconSetFactory.DeviceIconSetBuilder.DetailedImages ConstructDetailedImageSubset( + IDictionary images) + { + return new DeviceIconSetFactory.DeviceIconSetBuilder.DetailedImages((ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageMediumDefault], images[DeviceAssetImages.eDeviceAssetImageMediumUnsupported]), (ISimpleDeviceIconSet)new DeviceIconSetFactory.SimpleIconSet(images[DeviceAssetImages.eDeviceAssetImageLargeDefault], images[DeviceAssetImages.eDeviceAssetImageLargeDisconnected])); + } + + private void LoadBackgroundImageAndColors() => this._loader.LoadAndVerify((IList)this._assetSet.ImageUris, (IList)DeviceIconSetFactory.DeviceIconSetBuilder._backgroundImagesToLoad, new DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler(this.BackgroundCustomImageLoadComplete)); + + private void BackgroundCustomImageLoadComplete(IDictionary images) + { + if (images != null) + { + this._backgroundImageAndColorSubset = this.ConstructBackgroundImageAndColorsSubset(images); + this.End(); + } + else + this._loader.LoadAndVerify((IList)this._assetSet.DefaultImageUris, (IList)DeviceIconSetFactory.DeviceIconSetBuilder._backgroundImagesToLoad, new DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler(this.BackgroundDefaultImageLoadComplete)); + } + + private void BackgroundDefaultImageLoadComplete(IDictionary images) + { + this._backgroundImageAndColorSubset = images == null ? new DeviceIconSetFactory.DeviceIconSetBuilder.BackgroundImageAndColors(DeviceIconSetFactory.DefaultIconSet.Background, DeviceIconSetFactory.DefaultIconSet.Colors) : this.ConstructBackgroundImageAndColorsSubset(images); + this.End(); + } + + private DeviceIconSetFactory.DeviceIconSetBuilder.BackgroundImageAndColors ConstructBackgroundImageAndColorsSubset( + IDictionary images) + { + return new DeviceIconSetFactory.DeviceIconSetBuilder.BackgroundImageAndColors(images[DeviceAssetImages.eDeviceAssetImageBackground], (IColorSet)new DeviceIconSetFactory.ColorSet((IDeviceColor)new DeviceIconSetFactory.DeviceColor(this._assetSet.Colors[0]), (IDeviceColor)new DeviceIconSetFactory.DeviceColor(this._assetSet.Colors[1]), (IDeviceColor)new DeviceIconSetFactory.DeviceColor(this._assetSet.Colors[2]), (IDeviceColor)new DeviceIconSetFactory.DeviceColor(this._assetSet.Colors[3]))); + } + + private class ImageIdAndConstraint + { + private DeviceAssetImages _id; + private DeviceIconSetFactory.DeviceIconSizeConstraint _constraint; + + public ImageIdAndConstraint( + DeviceAssetImages id, + DeviceIconSetFactory.DeviceIconSizeConstraint constraint) + { + this._id = id; + this._constraint = constraint; + } + + public DeviceAssetImages ID => this._id; + + public DeviceIconSetFactory.DeviceIconSizeConstraint Constraint => this._constraint; + } + + private class DetailedImages + { + private ISimpleDeviceIconSet _mediumImages; + private ISimpleDeviceIconSet _largeImages; + + public DetailedImages(ISimpleDeviceIconSet mediumImages, ISimpleDeviceIconSet largeImages) + { + this._mediumImages = mediumImages; + this._largeImages = largeImages; + } + + public ISimpleDeviceIconSet MediumImages => this._mediumImages; + + public ISimpleDeviceIconSet LargeImages => this._largeImages; + } + + private class BackgroundImageAndColors + { + private Image _backgroundImage; + private IColorSet _colors; + + public BackgroundImageAndColors(Image backgroundImage, IColorSet colors) + { + this._backgroundImage = backgroundImage; + this._colors = colors; + } + + public Image BackgroundImage => this._backgroundImage; + + public IColorSet Colors => this._colors; + } + + private class ImageListLoaderAndVerifier + { + private IList _paths; + private IList _imagesToLoad; + private DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler _callback; + private int _asynchronousLoadsRemaining; + private bool _imagesAreValid; + private Dictionary _images; + + public void LoadAndVerify( + IList paths, + IList imagesToLoad, + DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler callback) + { + if (!Application.IsApplicationThread) + throw new Exception("DeviceIconSet loading is only supported on the application thread. This feature is not thread-safe."); + if (this._paths != null) + throw new Exception("LoadAndVerify was called while a set was already being built. Calls to LoadAndVerify cannot be reentrant."); + if (paths == null) + throw new ArgumentNullException("path"); + if (imagesToLoad == null) + throw new ArgumentNullException(nameof(imagesToLoad)); + if (callback == null) + throw new ArgumentNullException(nameof(callback)); + this._paths = paths; + this._imagesToLoad = imagesToLoad; + this._callback = callback; + this._asynchronousLoadsRemaining = 0; + this._imagesAreValid = true; + this._images = new Dictionary(23, (IEqualityComparer)DeviceIconSetFactory.DeviceIconSetBuilder.DeviceAssetImagesEqualityComparer.Instance); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.LoadAndVerifyWorker(); + }, (object)null); + } + + private void LoadAndVerifyWorker() + { + int num = 0; + foreach (DeviceIconSetFactory.DeviceIconSetBuilder.ImageIdAndConstraint imageIdAndConstraint in (IEnumerable)this._imagesToLoad) + { + if (this.LoadAndVerifyImage(imageIdAndConstraint.ID, imageIdAndConstraint.Constraint)) + ++num; + if (!this._imagesAreValid) + break; + } + this.SetAsynchronousLoadsRemaining(num); + } + + private bool LoadAndVerifyImage( + DeviceAssetImages imageId, + DeviceIconSetFactory.DeviceIconSizeConstraint constraint) + { + int index = (int)imageId; + bool flag1 = false; + if (index >= this._paths.Count) + { + this._imagesAreValid = false; + } + else + { + string path = this._paths[index]; + if (path == null) + this._imagesAreValid = false; + else if (!this.IsPathValid(path)) + { + this._imagesAreValid = false; + } + else + { + Image tempImage = (Image)null; + bool flag2 = false; + try + { + Image.RemoveCache(path, 1024, 1024); + tempImage = new Image(path, 1024, 1024); + flag2 = tempImage.Load(); + } + catch (Exception ex) + { + this._imagesAreValid = false; + } + if (tempImage == null) + this._imagesAreValid = false; + else if (this._imagesAreValid) + { + if (flag2) + { + DeviceAssetImages tempImageId = imageId; + DeviceIconSetFactory.DeviceIconSizeConstraint tempConstraint = constraint; + tempImage.ImageLoadComplete += (ImageLoadCompleteHandler)delegate + { + this.VerifyImage(tempImage, tempImageId, tempConstraint); + this.DecrementAsynchronousLoadsRemaining(); + }; + flag1 = true; + } + else + this.VerifyImage(tempImage, imageId, constraint); + } + } + } + return flag1; + } + + private bool IsPathValid(string path) + { + if (string.IsNullOrEmpty(path)) + return false; + return !path.StartsWith("file://") || File.Exists(path.Substring("file://".Length)); + } + + private void VerifyImage( + Image image, + DeviceAssetImages imageId, + DeviceIconSetFactory.DeviceIconSizeConstraint constraint) + { + if (DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.ImageFitsConstraint(image, constraint)) + this._images[imageId] = image; + else + this._imagesAreValid = false; + } + + private void SetAsynchronousLoadsRemaining(int value) + { + this._asynchronousLoadsRemaining = value; + this.CheckForAsynchronousPortionCompleted(); + } + + private void DecrementAsynchronousLoadsRemaining() + { + --this._asynchronousLoadsRemaining; + this.CheckForAsynchronousPortionCompleted(); + } + + private void CheckForAsynchronousPortionCompleted() + { + if (this._asynchronousLoadsRemaining != 0) + return; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.LoadingComplete(); + }, (object)null); + } + + private void LoadingComplete() + { + DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler callback = this._callback; + IDictionary result = this._imagesAreValid ? (IDictionary)this._images : (IDictionary)null; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + callback(result); + }, (object)null); + this._paths = (IList)null; + this._imagesToLoad = (IList)null; + this._callback = (DeviceIconSetFactory.DeviceIconSetBuilder.ImageListLoaderAndVerifier.LoadAndVerificationCompletedHandler)null; + } + + private static bool ImageFitsConstraint( + Image image, + DeviceIconSetFactory.DeviceIconSizeConstraint constraint) + { + return image != null && constraint != null && (image.Width >= constraint.MinWidth && image.Width <= constraint.MaxWidth) && image.Height >= constraint.MinHeight && image.Height <= constraint.MaxHeight; + } + + public delegate void LoadAndVerificationCompletedHandler( + IDictionary images); + } + + private class DeviceAssetImagesEqualityComparer : IEqualityComparer + { + public static DeviceIconSetFactory.DeviceIconSetBuilder.DeviceAssetImagesEqualityComparer Instance = new DeviceIconSetFactory.DeviceIconSetBuilder.DeviceAssetImagesEqualityComparer(); + + private DeviceAssetImagesEqualityComparer() + { + } + + public bool Equals(DeviceAssetImages x, DeviceAssetImages y) => x == y; + + public int GetHashCode(DeviceAssetImages obj) => obj.GetHashCode(); + } + } + + private class DeviceIconSizeConstraint + { + private int _minWidth; + private int _maxWidth; + private int _minHeight; + private int _maxHeight; + + public DeviceIconSizeConstraint(int minWidth, int maxWidth, int minHeight, int maxHeight) + { + this._minWidth = minWidth; + this._maxWidth = maxWidth; + this._minHeight = minHeight; + this._maxHeight = maxHeight; + } + + public int MinWidth => this._minWidth; + + public int MaxWidth => this._maxWidth; + + public int MinHeight => this._minHeight; + + public int MaxHeight => this._maxHeight; + } + + private class DeviceIconSet : IDeviceIconSet + { + private ISimpleDeviceIconSet _large; + private ISimpleDeviceIconSet _medium; + private IInteractiveDeviceIconSet _small; + private Image _background; + private IColorSet _colors; + + public DeviceIconSet( + ISimpleDeviceIconSet large, + ISimpleDeviceIconSet medium, + IInteractiveDeviceIconSet small, + Image background, + IColorSet colors) + { + this._large = large; + this._medium = medium; + this._small = small; + this._background = background; + this._colors = colors; + } + + public ISimpleDeviceIconSet Large => this._large; + + public ISimpleDeviceIconSet Medium => this._medium; + + public IInteractiveDeviceIconSet Small => this._small; + + public Image Background => this._background; + + public IColorSet Colors => this._colors; + } + + private class ColorSet : IColorSet + { + private IDeviceColor _light; + private IDeviceColor _dark; + private IDeviceColor _text; + private IDeviceColor _hoverText; + + public ColorSet( + IDeviceColor light, + IDeviceColor dark, + IDeviceColor text, + IDeviceColor hoverText) + { + this._light = light; + this._dark = dark; + this._text = text; + this._hoverText = hoverText; + } + + public IDeviceColor Light => this._light; + + public IDeviceColor Dark => this._dark; + + public IDeviceColor Text => this._text; + + public IDeviceColor HoverText => this._hoverText; + } + + private class DeviceColor : IDeviceColor + { + private float _r; + private float _g; + private float _b; + + public DeviceColor(uint packedColor) + { + this._r = (float)(int)((packedColor & 16711680U) >> 16) / (float)byte.MaxValue; + this._g = (float)(int)((packedColor & 65280U) >> 8) / (float)byte.MaxValue; + this._b = (float)((int)packedColor & (int)byte.MaxValue) / (float)byte.MaxValue; + } + + public DeviceColor(byte r, byte g, byte b) + { + this._r = (float)r / 250f; + this._g = (float)g / 250f; + this._b = (float)b / 250f; + } + + public DeviceColor(float r, float g, float b) + { + this._r = r; + this._g = g; + this._b = b; + } + + public float R => this._r; + + public float G => this._g; + + public float B => this._b; + } + + private class SimpleIconSet : ISimpleDeviceIconSet + { + private Image _connected; + private Image _disconnected; + + public SimpleIconSet(Image connected, Image disconnected) + { + this._connected = connected; + this._disconnected = disconnected; + } + + public Image Connected => this._connected; + + public Image Disconnected => this._disconnected; + + public Image GetImageForConnectedness(bool isConnected) => !isConnected ? this.Disconnected : this.Connected; + } + + private class BackgroundAwareIconSet : IBackgroundAwareDeviceIconSet + { + private ISimpleDeviceIconSet _forLightBackground; + private ISimpleDeviceIconSet _forDarkBackground; + + public BackgroundAwareIconSet( + ISimpleDeviceIconSet forLightBackground, + ISimpleDeviceIconSet forDarkBackground) + { + this._forLightBackground = forLightBackground; + this._forDarkBackground = forDarkBackground; + } + + public ISimpleDeviceIconSet ForLightBackground => this._forLightBackground; + + public ISimpleDeviceIconSet ForDarkBackground => this._forDarkBackground; + + public ISimpleDeviceIconSet GetSetForBackground(bool backgroundIsDark) => !backgroundIsDark ? this.ForLightBackground : this.ForDarkBackground; + } + + private class InteractiveIconSet : IInteractiveDeviceIconSet + { + private IBackgroundAwareDeviceIconSet _default; + private IBackgroundAwareDeviceIconSet _hover; + private IBackgroundAwareDeviceIconSet _drag; + private IBackgroundAwareDeviceIconSet _click; + private IBackgroundAwareDeviceIconSet _syncing; + + public InteractiveIconSet( + IBackgroundAwareDeviceIconSet defaultSet, + IBackgroundAwareDeviceIconSet hover, + IBackgroundAwareDeviceIconSet drag, + IBackgroundAwareDeviceIconSet click, + IBackgroundAwareDeviceIconSet syncing) + { + this._default = defaultSet; + this._hover = hover; + this._drag = drag; + this._click = click; + this._syncing = syncing; + } + + public IBackgroundAwareDeviceIconSet Default => this._default; + + public IBackgroundAwareDeviceIconSet Hover => this._hover; + + public IBackgroundAwareDeviceIconSet Drag => this._drag; + + public IBackgroundAwareDeviceIconSet Click => this._click; + + public IBackgroundAwareDeviceIconSet Syncing => this._syncing; + } + } +} diff --git a/ZuneUI/DeviceListEventArgs.cs b/ZuneUI/DeviceListEventArgs.cs new file mode 100644 index 0000000..52451e4 --- /dev/null +++ b/ZuneUI/DeviceListEventArgs.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceListEventArgs +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public struct DeviceListEventArgs + { + public UIDevice Device; + + public DeviceListEventArgs(UIDevice device) => this.Device = device; + } +} diff --git a/ZuneUI/DeviceListEventHandler.cs b/ZuneUI/DeviceListEventHandler.cs new file mode 100644 index 0000000..7342ee0 --- /dev/null +++ b/ZuneUI/DeviceListEventHandler.cs @@ -0,0 +1,10 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceListEventHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public delegate void DeviceListEventHandler(object sender, DeviceListEventArgs args); +} diff --git a/ZuneUI/DeviceManagement.cs b/ZuneUI/DeviceManagement.cs new file mode 100644 index 0000000..e95f9a9 --- /dev/null +++ b/ZuneUI/DeviceManagement.cs @@ -0,0 +1,1198 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceManagement +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; +using UIXControls; + +namespace ZuneUI +{ + public class DeviceManagement : ModelItem + { + private static UIDevice _setupDevice; + private static bool _setupQueueHandlingLocked = false; + private static MessageBox _deviceOOBEIncompleteDialog; + private int[] _defaultBitRates = new int[5] + { + 96, + 128, + 192, + 256, + 320 + }; + private string errorMessage; + private bool validatingCreds; + private string _friendlyNameOnDevice; + private int _deviceNameMaxLength = 32; + private Choice _enableMarketplaceChoice; + private BooleanChoice _enableMarketplacePurchase; + private MarketplaceCredentialsForDevice _marketplaceCredentials; + private float _reservedSpaceOnDevice = float.NaN; + private Choice _musicSyncChoice; + private Choice _videoSyncChoice; + private Choice _photoSyncChoice; + private Choice _podcastSyncChoice; + private Choice _friendSyncChoice; + private Choice _channelSyncChoice; + private Choice _applicationSyncChoice; + private BooleanChoice _dontSyncDislikedContent; + private Command _formatNotifier; + private int _transcodeSizeLimit = -1; + private bool _transcodeInBG; + private bool _transcodeInBGIsSet; + private string _transcodedFilesCachePath; + private IList _bitRateList; + private Choice _audioConversionChoice; + private IList _audioConversionOptions; + private string _audioThresholdBitRate; + private string _audioTargetBitRate; + private Choice _videoConversionChoice; + private IList _videoConversionOptions; + private string _cameraRollDestinationPath; + private string _savedFolderDestinationPath; + private Choice _deleteAfterReverseSyncChoice; + private IList _deleteAfterReverseSyncOptions; + private Choice _imageQualitySyncChoice; + private IList _imageQualitySyncOptions; + private SyncGroupList _syncGroups; + private BooleanChoice _privacyChoice; + public static bool NavigatingToWizard = false; + internal static DeviceSetupHashtable SetupQueue = new DeviceSetupHashtable(); + + private UIDevice ActiveDevice => SyncControls.Instance.CurrentDeviceOverride; + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + SignIn.Instance.TempPasswordStorage = (string)null; + WirelessSync.Instance = (WirelessSync)null; + SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignInStatusUpdatedEvent); + } + + internal static event DeviceConnectionHandledEventHandler DeviceConnectionHandled; + + public string ErrorMessage + { + get => this.errorMessage; + set + { + if (!(this.errorMessage != value)) + return; + this.errorMessage = value; + this.FirePropertyChanged(nameof(ErrorMessage)); + } + } + + public bool ValidatingCredentials + { + get => this.validatingCreds; + set + { + if (this.validatingCreds == value) + return; + this.validatingCreds = value; + this.FirePropertyChanged(nameof(ValidatingCredentials)); + } + } + + public static void NavigateToWizardMode(CategoryPageNode node, Category category) + { + Management management = ZuneShell.DefaultInstance.Management; + if (management.HasPendingCommits) + { + Command yesCommand = new Command((IModelItemOwner)null, Shell.LoadString(StringId.IDS_DIALOG_YES), (EventHandler)null); + yesCommand.Invoked += (EventHandler)((sender, args) => + { + management.CommitListSave(); + DeviceManagement.NavigateToWizardMode(node, category); + }); + Command noCommand = new Command((IModelItemOwner)null, Shell.LoadString(StringId.IDS_DIALOG_NO), (EventHandler)null); + noCommand.Invoked += (EventHandler)((sender, args) => + { + management.CommitList = (CommitListHashtable)null; + DeviceManagement.NavigateToWizardMode(node, category); + }); + MessageBox.Show(Shell.LoadString(StringId.IDS_SAVE_CHANGES_DIALOG_TITLE), Shell.LoadString(StringId.IDS_SAVE_CHANGES_ON_BACK_DIALOG_TEXT), yesCommand, noCommand, (BooleanChoice)null); + } + else + { + DeviceManagement.NavigatingToWizard = true; + if (Shell.SettingsFrame.IsCurrent && !Shell.SettingsFrame.Wizard.FUE.IsCurrent) + management.CurrentCategoryPage.CancelAndExit(); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (category != null) + node.Invoke(category); + else + node.Invoke(); + }, (object)null); + } + } + + public static UIDevice SetupDevice + { + get => DeviceManagement._setupDevice; + set + { + if (DeviceManagement._setupDevice == value) + return; + if (value == null) + { + DeviceManagement._setupQueueHandlingLocked = false; + DeviceManagement.SetupQueue.Remove((object)DeviceManagement._setupDevice.ID); + } + DeviceManagement._setupDevice = value; + if (DeviceManagement._setupDevice == null || Shell.SettingsFrame.IsCurrent) + return; + PhoneBrandingStringMap.Instance.BrandingEnabled = DeviceManagement._setupDevice.SupportsBrandingType(DeviceBranding.WindowsPhone); + KinBrandingStringMap.Instance.BrandingEnabled = DeviceManagement._setupDevice.SupportsBrandingType(DeviceBranding.Kin); + } + } + + internal static void HandleSetupQueue() + { + if (DeviceManagement._setupQueueHandlingLocked) + return; + DeviceManagement._setupQueueHandlingLocked = true; + DeviceManagement.SetupDevice = (UIDevice)null; + List intList = new List(); + foreach (DictionaryEntry setup in (Hashtable)DeviceManagement.SetupQueue) + { + UIDevice uiDevice = (UIDevice)setup.Value; + if (!uiDevice.IsConnectedToClient) + { + intList.Add(uiDevice.ID); + } + else + { + DeviceManagement.SetupDevice = uiDevice; + break; + } + } + foreach (int num in intList) + DeviceManagement.SetupQueue.Remove((object)num); + if (DeviceManagement.SetupDevice == null) + DeviceManagement._setupQueueHandlingLocked = false; + else + DeviceManagement.HandleCurrentSetupDevice(); + } + + public static void HandleCurrentSetupDevice() + { + if (DeviceManagement.SetupDevice == null) + return; + if (DeviceManagement.SetupDevice.SupportsOOBECompleted) + { + if (!DeviceManagement.SetupDevice.OOBECompleted) + { + SingletonModelItem.Instance.HideDevice(DeviceManagement.SetupDevice); + DeviceManagement.ShowDeviceOOBEIncompleteDialog(); + DeviceManagement.SetupDevice = (UIDevice)null; + return; + } + DeviceManagement.HideDeviceOOBEIncompleteDialog(); + } + if (DeviceManagement.SetupDevice.RequiresClientUpdate) + { + SingletonModelItem.Instance.HideDevice(DeviceManagement.SetupDevice); + MessageBox.Show(Shell.LoadString(StringId.IDS_CLIENT_UPDATE_HEADER), Shell.LoadString(StringId.IDS_CLIENT_UPDATE_DESC), (EventHandler)((sender, args) => ClientUpdate.Instance.InvokeClientUpdate())); + DeviceManagement.SetupDevice = (UIDevice)null; + } + else if (!UIDeviceList.IsSuitableForConnection(DeviceManagement.SetupDevice)) + { + if (DeviceManagement.SetupDevice.RequiresAutoRestore) + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)new AutoRestoreLandPage()); + else + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)new FirstConnectLandPage()); + } + else + { + UIFirmwareUpdater uiFirmwareUpdater = DeviceManagement.SetupDevice.UIFirmwareUpdater; + if (uiFirmwareUpdater != null) + { + bool launchWizardIfUpdatesFound = DeviceManagement.SetupDevice.SupportsBrandingType(DeviceBranding.WindowsPhone); + uiFirmwareUpdater.StartCheckForUpdates(DeviceManagement.SetupDevice.RequiresFirmwareUpdate, launchWizardIfUpdatesFound); + } + DeviceManagement.EndDeviceHandling(false, true); + } + } + + public static void HideSetupDevice() + { + SingletonModelItem.Instance.HideDevice(DeviceManagement.SetupDevice); + DeviceManagement.SetupDevice = (UIDevice)null; + } + + public void SetupComplete(bool navigateToLandingPage) + { + if (DeviceManagement.SetupDevice == null) + return; + if (this.ActiveDevice.IsValid) + { + this.ActiveDevice.PromptForAccountLinkage = true; + SyncControls.Instance.ChangeIntoSetupDevice = false; + DeviceManagement.EndDeviceHandling(true, navigateToLandingPage); + ZuneShell.DefaultInstance.Management.DisposeDeviceManagement(false); + } + else + this.ErrorMessage = Shell.LoadString(StringId.IDS_SYNC_SETUP_COMPLETION_ERROR); + } + + private static void EndDeviceHandling(bool comingOutOfFirstConnect, bool navigateToLandingPage) + { + if (DeviceManagement.SetupDevice == null) + return; + DeviceManagement.SetupDevice.Enumerate(); + SyncControls instance = SyncControls.Instance; + if (!Shell.SettingsFrame.IsCurrent || comingOutOfFirstConnect) + instance.SetCurrentDeviceIfNecessary(DeviceManagement.SetupDevice, comingOutOfFirstConnect); + if (!DeviceManagement.SetupDevice.IsGuest && DeviceManagement.SetupDevice.HasFailedLogin) + instance.AddDeviceToFailedSignInQueue(DeviceManagement.SetupDevice); + if (DeviceManagement.SetupDevice.SupportsBrandingType(DeviceBranding.WindowsPhone) || DeviceManagement.SetupDevice.SupportsBrandingType(DeviceBranding.Kin)) + { + instance.ShowPhoneWelcomeMessage = true; + ClientConfiguration.Devices.HasPhoneBeenConnected = true; + } + if (navigateToLandingPage && comingOutOfFirstConnect && !(ZuneShell.DefaultInstance.CurrentPage is Deviceland)) + Shell.MainFrame.Device.Invoke(); + instance.ShowSyncInstructionsToast = true; + if (DeviceManagement.DeviceConnectionHandled != null) + DeviceManagement.DeviceConnectionHandled((object)null, new DeviceConnectionHandledEventArgs(DeviceManagement.SetupDevice, comingOutOfFirstConnect)); + DeviceManagement.SetupDevice = (UIDevice)null; + } + + internal static void ShowDeviceOOBEIncompleteDialog() + { + if (DeviceManagement._deviceOOBEIncompleteDialog != null) + return; + DeviceManagement._deviceOOBEIncompleteDialog = MessageBox.Show(Shell.LoadString(StringId.IDS_PHONE_OOBE_INCOMPLETE_TITLE), Shell.LoadString(StringId.IDS_PHONE_OOBE_INCOMPLETE_DESCRIPTION), (EventHandler)null, (EventHandler)null, (EventHandler)null, (EventHandler)((sender, args) => DeviceManagement.HideDeviceOOBEIncompleteDialog()), (BooleanChoice)null); + } + + internal static void HideDeviceOOBEIncompleteDialog() + { + if (DeviceManagement._deviceOOBEIncompleteDialog == null) + return; + DeviceManagement._deviceOOBEIncompleteDialog.Hide(); + DeviceManagement._deviceOOBEIncompleteDialog = (MessageBox)null; + } + + public Choice MusicSyncChoice + { + get + { + if (this._musicSyncChoice == null) + this._musicSyncChoice = this.GenerateSyncModeChoice(SyncCategory.Music); + return this._musicSyncChoice; + } + private set + { + if (this._musicSyncChoice == value) + return; + this._musicSyncChoice = value; + this.FirePropertyChanged(nameof(MusicSyncChoice)); + } + } + + public Choice VideoSyncChoice + { + get + { + if (this._videoSyncChoice == null) + this._videoSyncChoice = this.GenerateSyncModeChoice(SyncCategory.Video); + return this._videoSyncChoice; + } + private set + { + if (this._videoSyncChoice == value) + return; + this._videoSyncChoice = value; + this.FirePropertyChanged(nameof(VideoSyncChoice)); + } + } + + public Choice PhotoSyncChoice + { + get + { + if (this._photoSyncChoice == null) + this._photoSyncChoice = this.GenerateSyncModeChoice(SyncCategory.Photo); + return this._photoSyncChoice; + } + private set + { + if (this._photoSyncChoice == value) + return; + this._photoSyncChoice = value; + this.FirePropertyChanged(nameof(PhotoSyncChoice)); + } + } + + public Choice PodcastSyncChoice + { + get + { + if (this._podcastSyncChoice == null) + this._podcastSyncChoice = this.GenerateSyncModeChoice(SyncCategory.Podcast); + return this._podcastSyncChoice; + } + private set + { + if (this._podcastSyncChoice == value) + return; + this._podcastSyncChoice = value; + this.FirePropertyChanged(nameof(PodcastSyncChoice)); + } + } + + public Choice FriendSyncChoice + { + get + { + if (this._friendSyncChoice == null) + this._friendSyncChoice = this.GenerateSyncModeChoice(SyncCategory.Friend); + return this._friendSyncChoice; + } + private set + { + if (this._friendSyncChoice == value) + return; + this._friendSyncChoice = value; + this.FirePropertyChanged(nameof(FriendSyncChoice)); + } + } + + public Choice ChannelSyncChoice + { + get + { + if (this._channelSyncChoice == null) + this._channelSyncChoice = this.GenerateSyncModeChoice(SyncCategory.Channel); + return this._channelSyncChoice; + } + private set + { + if (this._channelSyncChoice == value) + return; + this._channelSyncChoice = value; + this.FirePropertyChanged(nameof(ChannelSyncChoice)); + } + } + + public Choice ApplicationSyncChoice + { + get + { + if (this._applicationSyncChoice == null) + this._applicationSyncChoice = this.GenerateSyncModeChoice(SyncCategory.Application); + return this._applicationSyncChoice; + } + private set + { + if (this._applicationSyncChoice == value) + return; + this._applicationSyncChoice = value; + this.FirePropertyChanged(nameof(ApplicationSyncChoice)); + } + } + + private Choice GenerateSyncModeChoice(SyncCategory syncType) + { + Choice choice = new Choice((IModelItemOwner)this); + List syncModeOptionPairList = new List(); + string name1 = ""; + string name2 = ""; + string name3 = (string)null; + EventHandler eventHandler = (EventHandler)null; + switch (syncType) + { + case SyncCategory.Music: + name1 = Shell.LoadString(StringId.IDS_SYNC_ALL_OPTION_MUSIC); + name2 = Shell.LoadString(StringId.IDS_LET_ME_CHOOSE_OPTION_MUSIC); + name3 = Shell.LoadString(StringId.IDS_MANUAL_OPTION_MUSIC); + eventHandler = new EventHandler(this.HandleMusicSyncOptionChanged); + break; + case SyncCategory.Video: + name1 = Shell.LoadString(StringId.IDS_SYNC_ALL_OPTION_VIDEOS); + name2 = Shell.LoadString(StringId.IDS_LET_ME_CHOOSE_OPTION_VIDEOS); + name3 = Shell.LoadString(StringId.IDS_MANUAL_OPTION_VIDEOS); + eventHandler = new EventHandler(this.HandleVideoSyncOptionChanged); + break; + case SyncCategory.Photo: + name1 = Shell.LoadString(StringId.IDS_SYNC_ALL_OPTION_PICTURES); + name2 = Shell.LoadString(StringId.IDS_LET_ME_CHOOSE_OPTION_PICTURES); + name3 = Shell.LoadString(StringId.IDS_MANUAL_OPTION_PICTURES); + eventHandler = new EventHandler(this.HandlePhotoSyncOptionChanged); + break; + case SyncCategory.Podcast: + name1 = Shell.LoadString(StringId.IDS_SYNC_ALL_OPTION_PODCASTS); + name2 = Shell.LoadString(StringId.IDS_LET_ME_CHOOSE_OPTION_PODCASTS); + eventHandler = new EventHandler(this.HandlePodcastSyncOptionChanged); + break; + case SyncCategory.Friend: + name1 = Shell.LoadString(StringId.IDS_SYNC_ALL_OPTION_FRIENDS); + name2 = Shell.LoadString(StringId.IDS_LET_ME_CHOOSE_OPTION_FRIENDS); + eventHandler = new EventHandler(this.HandleFriendSyncOptionChanged); + break; + case SyncCategory.Channel: + name1 = Shell.LoadString(StringId.IDS_SYNC_ALL_OPTION_CHANNELS); + name2 = Shell.LoadString(StringId.IDS_LET_ME_CHOOSE_OPTION_CHANNELS); + eventHandler = new EventHandler(this.HandleChannelSyncOptionChanged); + break; + case SyncCategory.Application: + name1 = Shell.LoadString(StringId.IDS_SYNC_ALL_OPTION_APPLICATIONS); + name2 = Shell.LoadString(StringId.IDS_LET_ME_CHOOSE_OPTION_APPLICATIONS); + name3 = Shell.LoadString(StringId.IDS_MANUAL_OPTION_APPLICATIONS); + eventHandler = new EventHandler(this.HandleApplicationSyncOptionChanged); + break; + } + SyncModeOptionPair syncModeOptionPair1 = new SyncModeOptionPair(name1, SyncMode.SyncAll); + syncModeOptionPairList.Add(syncModeOptionPair1); + SyncModeOptionPair syncModeOptionPair2 = new SyncModeOptionPair(name2, SyncMode.LetMeChoose); + syncModeOptionPairList.Add(syncModeOptionPair2); + if (!string.IsNullOrEmpty(name3)) + { + SyncModeOptionPair syncModeOptionPair3 = new SyncModeOptionPair(name3, SyncMode.Manual); + syncModeOptionPairList.Add(syncModeOptionPair3); + } + bool flag1 = this.ActiveDevice.IsSyncAllFor(syncType, true); + bool flag2 = !string.IsNullOrEmpty(name3) && this.ActiveDevice.IsManualFor(syncType, true); + choice.Options = (IList)syncModeOptionPairList; + choice.ChosenIndex = flag2 ? 2 : (flag1 ? 0 : 1); + if (eventHandler != null) + choice.ChosenChanged += eventHandler; + return choice; + } + + private void HandleMusicSyncOptionChanged(object sender, EventArgs args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnMusicSyncChoiceCommit)] = (object)this.CommitDeviceID; + + private void OnMusicSyncChoiceCommit(object data) => this.OnCategorySyncChoiceCommit(SyncCategory.Music, ((SyncModeOptionPair)this._musicSyncChoice.ChosenValue).Mode); + + private void HandleVideoSyncOptionChanged(object sender, EventArgs args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnVideoSyncChoiceCommit)] = (object)this.CommitDeviceID; + + private void OnVideoSyncChoiceCommit(object data) => this.OnCategorySyncChoiceCommit(SyncCategory.Video, ((SyncModeOptionPair)this._videoSyncChoice.ChosenValue).Mode); + + private void HandlePhotoSyncOptionChanged(object sender, EventArgs args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnPhotoSyncChoiceCommit)] = (object)this.CommitDeviceID; + + private void OnPhotoSyncChoiceCommit(object data) => this.OnCategorySyncChoiceCommit(SyncCategory.Photo, ((SyncModeOptionPair)this._photoSyncChoice.ChosenValue).Mode); + + private void HandlePodcastSyncOptionChanged(object sender, EventArgs args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnPodcastSyncChoiceCommit)] = (object)this.CommitDeviceID; + + private void OnPodcastSyncChoiceCommit(object data) => this.OnCategorySyncChoiceCommit(SyncCategory.Podcast, ((SyncModeOptionPair)this._podcastSyncChoice.ChosenValue).Mode); + + private void HandleFriendSyncOptionChanged(object sender, EventArgs args) + { + if (((SyncModeOptionPair)this._friendSyncChoice.ChosenValue).Mode == SyncMode.SyncAll) + UIDevice.WarnUserAboutFriendSyncSize(); + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnFriendSyncChoiceCommit)] = (object)this.CommitDeviceID; + } + + private void OnFriendSyncChoiceCommit(object data) + { + if (!this.DeviceHasTag) + return; + this.OnCategorySyncChoiceCommit(SyncCategory.Friend, ((SyncModeOptionPair)this._friendSyncChoice.ChosenValue).Mode); + } + + private void HandleChannelSyncOptionChanged(object sender, EventArgs args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnChannelSyncChoiceCommit)] = (object)this.CommitDeviceID; + + private void OnChannelSyncChoiceCommit(object data) + { + if (!this.DeviceHasTag) + return; + this.OnCategorySyncChoiceCommit(SyncCategory.Channel, ((SyncModeOptionPair)this._channelSyncChoice.ChosenValue).Mode); + } + + private void HandleApplicationSyncOptionChanged(object sender, EventArgs args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnApplicationSyncChoiceCommit)] = (object)this.CommitDeviceID; + + private void OnApplicationSyncChoiceCommit(object data) => this.OnCategorySyncChoiceCommit(SyncCategory.Application, ((SyncModeOptionPair)this._applicationSyncChoice.ChosenValue).Mode); + + private void OnCategorySyncChoiceCommit(SyncCategory cat, SyncMode mode) + { + if (!this.ActiveDevice.IsValid) + return; + SyncMode syncMode = this.ActiveDevice.GetSyncMode(cat); + this.ActiveDevice.SetSyncMode(cat, mode); + this.HandleSyncOptionChanges(syncMode, mode); + } + + private void HandleSyncOptionChanges(SyncMode oldMode, SyncMode mode) + { + if (mode == oldMode) + return; + CategoryPage currentCategoryPage = ZuneShell.DefaultInstance.Management.CurrentCategoryPage; + } + + public void FormatCurrentDevice() => MessageBox.Show(Shell.LoadString(StringId.IDS_FORMAT_DIALOG_TITLE), Shell.LoadString(StringId.IDS_FORMAT_DIALOG_TEXT), new EventHandler(this.ConfirmedFormatDevice), (EventHandler)null); + + private void ConfirmedFormatDevice(object sender, EventArgs e) + { + this.FormatBegun.Invoke(); + SyncControls.Instance.CurrentDevice.Format(); + } + + public Command FormatBegun + { + get + { + if (this._formatNotifier == null) + this._formatNotifier = new Command((IModelItemOwner)this); + return this._formatNotifier; + } + } + + public BooleanChoice DontSyncDislikedContentChoice + { + get + { + if (this._dontSyncDislikedContent == null) + { + this._dontSyncDislikedContent = new BooleanChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_DONT_SYNC_DISLIKED_CONTENT)); + this._dontSyncDislikedContent.Value = this.ActiveDevice.ExcludeDislikedContent; + this._dontSyncDislikedContent.ChosenChanged += (EventHandler)((sender, args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnDontSyncDislikedContentChoiceCommit)] = (object)this.CommitDeviceID); + } + return this._dontSyncDislikedContent; + } + } + + private void OnDontSyncDislikedContentChoiceCommit(object data) => this.ActiveDevice.ExcludeDislikedContent = this.DontSyncDislikedContentChoice.Value; + + public Choice DeleteAfterReverseSyncChoice + { + get + { + if (this._deleteAfterReverseSyncChoice == null) + { + this._deleteAfterReverseSyncOptions = (IList)new List(); + this._deleteAfterReverseSyncOptions.Add(new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_PHOTOS_SETTINGS_LEAVE_AFTER_REVERSE_SYNC), (EventHandler)null)); + this._deleteAfterReverseSyncOptions.Add(new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_PHOTOS_SETTINGS_DELETE_AFTER_REVERSE_SYNC), (EventHandler)null)); + this._deleteAfterReverseSyncChoice = new Choice((IModelItemOwner)this); + this._deleteAfterReverseSyncChoice.Options = (IList)this._deleteAfterReverseSyncOptions; + this._deleteAfterReverseSyncChoice.DefaultIndex = this.ActiveDevice.DeletePicsFromPhoneAfterReverseSync ? 1 : 0; + this._deleteAfterReverseSyncChoice.DefaultValue(); + this._deleteAfterReverseSyncChoice.ChosenChanged += (EventHandler)((sender, args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnDeleteAfterReverseSyncCommit)] = (object)this.CommitDeviceID); + } + return this._deleteAfterReverseSyncChoice; + } + } + + private void OnDeleteAfterReverseSyncCommit(object data) => this.ActiveDevice.DeletePicsFromPhoneAfterReverseSync = this.DeleteAfterReverseSyncChoice.ChosenIndex == 1; + + public string FriendlyNameOnDevice + { + get + { + if (this._friendlyNameOnDevice == null) + this._friendlyNameOnDevice = this.ActiveDevice.Name; + return this._friendlyNameOnDevice; + } + set + { + string errorMessage; + if (this.IsDeviceNameValid(value, out errorMessage)) + { + if (this._friendlyNameOnDevice != value) + { + this._friendlyNameOnDevice = value; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnFriendlyNameOnDeviceCommit)] = (object)this.CommitDeviceID; + this.FirePropertyChanged(nameof(FriendlyNameOnDevice)); + } + this.ErrorMessage = (string)null; + } + else + this.ErrorMessage = errorMessage; + } + } + + private void OnFriendlyNameOnDeviceCommit(object data) => this.ActiveDevice.Name = this._friendlyNameOnDevice.Trim(); + + private bool IsDeviceNameValid(string name, out string errorMessage) + { + if (string.IsNullOrEmpty(name)) + { + errorMessage = Shell.LoadString(StringId.IDS_DEVICE_NAME_EMPTY); + return false; + } + if (name.Length > this._deviceNameMaxLength) + { + errorMessage = Shell.LoadString(StringId.IDS_DEVICE_NAME_TOO_LONG); + return false; + } + if (this.DeviceNameHasInvalidCharacters(name)) + { + errorMessage = Shell.LoadString(StringId.IDS_DEVICE_NAME_INVALID_CHARS); + return false; + } + errorMessage = (string)null; + return true; + } + + private bool DeviceNameHasInvalidCharacters(string name) + { + if (this.ActiveDevice.SupportsBrandingType(DeviceBranding.WindowsPhone)) + { + if (name.IndexOfAny(Path.GetInvalidFileNameChars()) != -1) + return true; + } + try + { + new UnicodeEncoding(false, false, true).GetBytes(name); + return false; + } + catch (EncoderFallbackException ex) + { + return true; + } + catch (ArgumentException ex) + { + return true; + } + } + + public void CheckForAutomatedRequirements() + { + } + + public MarketplaceCredentialsForDevice MarketplaceCredentials => this._marketplaceCredentials; + + public Choice EnableMarketplaceChoice + { + get + { + if (this._enableMarketplaceChoice == null) + { + this._enableMarketplaceChoice = new Choice((IModelItemOwner)this); + this._enableMarketplaceChoice.Options = (IList)new Command[2] + { + new Command((IModelItemOwner) this, Shell.LoadString(StringId.IDS_SKIP_FOR_NOW_OPTION), (EventHandler) null), + new Command((IModelItemOwner) this, Shell.LoadString(StringId.IDS_ENABLE_ZUNE_MARKETPLACE_OPTION), (EventHandler) null) + }; + this._marketplaceCredentials = new MarketplaceCredentialsForDevice((string)null, (string)null, this.ActiveDevice.PurchaseEnabled, !Shell.SettingsFrame.Wizard.IsCurrent && !string.IsNullOrEmpty(this.ActiveDevice.ZuneTag), this.ActiveDevice.ZuneTag, this._enableMarketplaceChoice); + if (Shell.SettingsFrame.Wizard.IsCurrent) + { + this.MarketplaceCredentials.Email = SignIn.GetPassportIdFromUserId(SignIn.Instance.LastSignedInUserId); + this._enableMarketplaceChoice.DefaultIndex = string.IsNullOrEmpty(this.MarketplaceCredentials.Email) ? 0 : 1; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnMarketplaceCredentialsCommit)] = (object)this.CommitDeviceID; + } + else + this._enableMarketplaceChoice.DefaultIndex = string.IsNullOrEmpty(this.ActiveDevice.ZuneTag) ? 0 : 1; + this._enableMarketplaceChoice.DefaultValue(); + this._enableMarketplaceChoice.ChosenChanged += (EventHandler)((sender, args) => + { + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnMarketplaceCredentialsCommit)] = (object)this.CommitDeviceID; + this.FirePropertyChanged(nameof(EnableMarketplaceChoice)); + }); + } + return this._enableMarketplaceChoice; + } + } + + private void OnMarketplaceCredentialsCommit(object data) + { + if (this.EnableMarketplaceChoice.ChosenIndex == 0) + { + this.ActiveDevice.ClearAccountAssociation(); + } + else + { + this.ActiveDevice.SetGeoId(); + this.ActiveDevice.PurchaseEnabled = this._marketplaceCredentials.PurchaseEnabled; + if (this.ActiveDevice.AssociateWithAccount(this._marketplaceCredentials.UserGuid, this._marketplaceCredentials.ZuneTag).IsSuccess) + this.ActiveDevice.SendMarketplaceCredentials(this._marketplaceCredentials.Email, this._marketplaceCredentials.Password); + else + this.ActiveDevice.ClearAccountAssociation(); + } + } + + public bool IsDevicePurchaseEnabled + { + get + { + if (this.MarketplaceCredentials == null) + return this.ActiveDevice.PurchaseEnabled; + return this.MarketplaceCredentials.IsAssociated && this.MarketplaceCredentials.PurchaseEnabled; + } + } + + public bool IsAssociated => this.MarketplaceCredentials != null ? this.MarketplaceCredentials.IsAssociated : !string.IsNullOrEmpty(this.ActiveDevice.ZuneTag); + + public bool DeviceHasTag + { + get + { + bool flag = false; + if (this.IsPartnered) + { + flag = SyncControls.Instance.CurrentDeviceOverride.UserId > 0; + if (!flag) + flag = this.IsAssociated; + } + return flag; + } + } + + public BooleanChoice EnableMarketplacePurchase + { + get + { + if (this._enableMarketplacePurchase == null) + { + this._enableMarketplacePurchase = new BooleanChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_ENABLE_DEVICE_PURCHASE)); + this._enableMarketplacePurchase.Value = this.MarketplaceCredentials.PurchaseEnabled; + this._enableMarketplacePurchase.ChosenChanged += (EventHandler)((sender, args) => this.MarketplaceCredentials.PurchaseEnabled = this._enableMarketplacePurchase.Value); + } + return this._enableMarketplacePurchase; + } + } + + public void ValidatePassportAccount(string email, string password) + { + if (email == string.Empty || password == string.Empty) + { + this.ErrorMessage = Shell.LoadString(StringId.IDS_VERIFY_CREDS_ERROR); + this.MarketplaceCredentials.PurchaseEnabled = false; + this.MarketplaceCredentials.ZuneTag = string.Empty; + this.FirePropertyChanged("MarketplaceCredentials"); + } + else + { + this.ErrorMessage = string.Empty; + this.ValidatingCredentials = true; + this.MarketplaceCredentials.Email = email; + this.MarketplaceCredentials.Password = password; + SignIn.Instance.SignOut(); + SignIn.Instance.SignInStatusUpdatedEvent += new EventHandler(this.OnSignInStatusUpdatedEvent); + SignIn.Instance.SignInUser(email, password); + } + } + + private void OnSignInStatusUpdatedEvent(object sender, EventArgs e) + { + if (SignIn.Instance.SigningIn || !SignIn.Instance.SignInError.IsError && !SignIn.Instance.SignedIn) + return; + SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignInStatusUpdatedEvent); + this.MarketplaceCredentials.hr = SignIn.Instance.SignInError.hr; + if (SignIn.Instance.SignInError.IsError) + { + this.ErrorMessage = Shell.LoadString(StringId.IDS_VERIFY_CREDS_ERROR); + this.MarketplaceCredentials.PurchaseEnabled = false; + this.MarketplaceCredentials.ZuneTag = string.Empty; + } + else + { + this.ErrorMessage = string.Empty; + this.MarketplaceCredentials.ZuneTag = SignIn.Instance.ZuneTag; + this.MarketplaceCredentials.UserGuid = SignIn.Instance.UserGuid; + } + if (!Shell.SettingsFrame.Wizard.IsCurrent) + this.OnMarketplaceCredentialsCommit((object)null); + this.ValidatingCredentials = false; + this.FirePropertyChanged("MarketplaceCredentials"); + } + + public bool CredentialValidationRequested + { + get => true; + set => this.FirePropertyChanged(nameof(CredentialValidationRequested)); + } + + public DeviceRelationship DevicePartnership + { + get + { + Management management = ZuneShell.DefaultInstance.Management; + if (management.CommitList.ContainsValue((object)"OnSyncPartnershipCommit")) + return DeviceRelationship.Permanent; + DeviceRelationship deviceRelationship = this.ActiveDevice.Relationship; + if (this.ActiveDevice.IsValid && deviceRelationship == DeviceRelationship.None) + { + management.CommitList[(object)new ProxySettingDelegate(this.OnSyncPartnershipCommit)] = (object)"OnSyncPartnershipCommit"; + deviceRelationship = DeviceRelationship.Permanent; + } + return deviceRelationship; + } + set + { + Management management = ZuneShell.DefaultInstance.Management; + if (value == DeviceRelationship.Permanent) + { + management.CommitList[(object)new ProxySettingDelegate(this.OnSyncPartnershipCommit)] = (object)"OnSyncPartnershipCommit"; + } + else + { + management.CommitList[(object)new ProxySettingDelegate(this.OnSyncPartnershipCommit)] = (object)null; + this.ActiveDevice.Relationship = value; + } + this.FirePropertyChanged(nameof(DevicePartnership)); + this.FirePropertyChanged("IsPartnered"); + } + } + + public bool IsPartnered => this.DevicePartnership == DeviceRelationship.Permanent; + + public bool IsCurrentDeviceNull => this.ActiveDevice == UIDeviceList.NullDevice; + + private void OnSyncPartnershipCommit(object data) + { + if (!this.ActiveDevice.IsValid || data == null || this.ActiveDevice.Relationship == DeviceRelationship.Permanent) + return; + this.ActiveDevice.Relationship = DeviceRelationship.Permanent; + if (!this.ActiveDevice.SupportsWirelessSetupMethod1 && !this.ActiveDevice.SupportsWirelessSetupMethod2) + return; + WirelessSync.Instance.ClearWirelessOnDevice(); + } + + public string TranscodeSizeLimit + { + get + { + string transcodedFilesCachePath = this.TranscodedFilesCachePath; + if (this._transcodeSizeLimit == -1) + this._transcodeSizeLimit = SingletonModelItem.Instance.TranscodedFilesCacheSize; + return this._transcodeSizeLimit.ToString(); + } + set + { + int result = 1; + if (string.IsNullOrEmpty(value) || int.TryParse(value, out result)) + { + if (result < 1) + result = 1; + else if (result > 999999) + result = 999999; + if (this._transcodeSizeLimit != result) + { + this._transcodeSizeLimit = result; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnTranscodeSizeLimitCommit)] = (object)this.CommitDeviceID; + } + } + this.FirePropertyChanged(nameof(TranscodeSizeLimit)); + } + } + + private void OnTranscodeSizeLimitCommit(object data) => SingletonModelItem.Instance.TranscodedFilesCacheSize = this._transcodeSizeLimit; + + public string TranscodedFilesCachePath + { + get + { + if (this._transcodedFilesCachePath == null) + this._transcodedFilesCachePath = SingletonModelItem.Instance.TranscodedFilesCachePath; + return this._transcodedFilesCachePath; + } + private set + { + if (!(this._transcodedFilesCachePath != value)) + return; + this._transcodedFilesCachePath = value; + this.FirePropertyChanged(nameof(TranscodedFilesCachePath)); + } + } + + public string CameraRollDestinationPath + { + get + { + if (this._cameraRollDestinationPath == null) + this._cameraRollDestinationPath = this.ActiveDevice.CameraRollDestinationPath; + return this._cameraRollDestinationPath; + } + private set + { + if (!(this._cameraRollDestinationPath != value)) + return; + this._cameraRollDestinationPath = value; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnCameraRollDestinationPathCommit)] = (object)this.CommitDeviceID; + this.FirePropertyChanged(nameof(CameraRollDestinationPath)); + } + } + + public void OnCameraRollDestinationPathCommit(object data) => this.ActiveDevice.CameraRollDestinationPath = this._cameraRollDestinationPath; + + public string SavedFolderDestinationPath + { + get + { + if (this._savedFolderDestinationPath == null) + this._savedFolderDestinationPath = this.ActiveDevice.SavedFolderDestinationPath; + return this._savedFolderDestinationPath; + } + private set + { + if (!(this._savedFolderDestinationPath != value)) + return; + this._savedFolderDestinationPath = value; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnSavedFolderDestinationPathCommit)] = (object)this.CommitDeviceID; + this.FirePropertyChanged(nameof(SavedFolderDestinationPath)); + } + } + + public void OnSavedFolderDestinationPathCommit(object data) => this.ActiveDevice.SavedFolderDestinationPath = this._savedFolderDestinationPath; + + public bool TranscodeInBG + { + get + { + if (!this._transcodeInBGIsSet) + { + this._transcodeInBG = ClientConfiguration.Transcode.BackgroundTranscode; + this._transcodeInBGIsSet = true; + } + return this._transcodeInBG; + } + set + { + if (this._transcodeInBG == value) + return; + this._transcodeInBG = value; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnTranscodeInBGCommit)] = (object)null; + this.FirePropertyChanged(nameof(TranscodeInBG)); + this._transcodeInBGIsSet = true; + } + } + + private void OnTranscodeInBGCommit(object data) => ClientConfiguration.Transcode.BackgroundTranscode = this._transcodeInBG; + + public void ChangeTranscodeFolder() => FolderBrowseDialog.Show("", (DeferredInvokeHandler)(args => + { + if (args == null) + return; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnChangeTranscodeFolderCommit)] = (object)null; + this.TranscodedFilesCachePath = (string)args; + }), true); + + private void OnChangeTranscodeFolderCommit(object data) => SingletonModelItem.Instance.TranscodedFilesCachePath = this._transcodedFilesCachePath; + + public void ClearTranscodeFolder() + { + if (!this.ActiveDevice.IsValid) + return; + HRESULT hresult = SingletonModelItem.Instance.ClearTranscodeCache(); + if (!hresult.IsError) + return; + Shell.ShowErrorDialog(hresult.Int, StringId.IDS_CACHE_CLEAR_FAILED); + } + + public void ChangeCameraRollDestinationPath() + { + if (!this.ActiveDevice.IsValid) + return; + FolderBrowseDialog.Show("", (DeferredInvokeHandler)(args => + { + if (args == null) + return; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnChangeCameraRollDestinationPathCommit)] = (object)this.CommitDeviceID; + this.CameraRollDestinationPath = (string)args; + }), true); + } + + private void OnChangeCameraRollDestinationPathCommit(object data) => this.ActiveDevice.CameraRollDestinationPath = this._transcodedFilesCachePath; + + public Choice ImageQualitySyncChoice + { + get + { + if (this._imageQualitySyncChoice == null) + { + this._imageQualitySyncOptions = (IList)new List(); + this._imageQualitySyncOptions.Add(new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_PHOTOS_SETTINGS_QUALITY_DEFAULT), (EventHandler)null)); + this._imageQualitySyncOptions.Add(new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_PHOTOS_SETTINGS_QUALITY_ORIGINAL), (EventHandler)null)); + this._imageQualitySyncOptions.Add(new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_PHOTOS_SETTINGS_QUALITY_VGA), (EventHandler)null)); + this._imageQualitySyncChoice = new Choice((IModelItemOwner)this); + this._imageQualitySyncChoice.Options = (IList)this._imageQualitySyncOptions; + this._imageQualitySyncChoice.DefaultIndex = this.ActiveDevice.ImageTranscodeQuality > ETranscodePhotoSetting.tsPhotoSettingDevicePreferred ? (int)this.ActiveDevice.ImageTranscodeQuality : 0; + this._imageQualitySyncChoice.DefaultValue(); + this._imageQualitySyncChoice.ChosenChanged += (EventHandler)((sender, args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnImageQualitySyncChoiceCommit)] = (object)this.CommitDeviceID); + } + return this._imageQualitySyncChoice; + } + private set + { + if (this._imageQualitySyncChoice == value) + return; + this._imageQualitySyncChoice = value; + this.FirePropertyChanged(nameof(ImageQualitySyncChoice)); + } + } + + private void OnImageQualitySyncChoiceCommit(object data) => this.ActiveDevice.ImageTranscodeQuality = (ETranscodePhotoSetting)this._imageQualitySyncChoice.ChosenIndex; + + public Choice AudioConversionChoice + { + get + { + if (this._audioConversionChoice == null) + { + this._audioConversionOptions = (IList)new List(); + this._audioConversionOptions.Add(new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_TRANSCODE_AUDIO_NOSUPPORT_OPTION), (EventHandler)null)); + this._audioConversionOptions.Add(new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_TRANSCODE_AUDIO_EXCEEDS_OPTION), (EventHandler)null)); + this._audioConversionChoice = new Choice((IModelItemOwner)this); + this._audioConversionChoice.Options = (IList)this._audioConversionOptions; + this._audioConversionChoice.DefaultIndex = this.ActiveDevice.AudioTranscodeLimit > 0 ? 1 : 0; + this._audioConversionChoice.DefaultValue(); + this._audioConversionChoice.ChosenChanged += (EventHandler)((sender, args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnAudioConversionChoiceCommit)] = (object)this.CommitDeviceID); + } + return this._audioConversionChoice; + } + private set + { + if (this._audioConversionChoice == value) + return; + this._audioConversionChoice = value; + this.FirePropertyChanged(nameof(AudioConversionChoice)); + } + } + + public string AudioThresholdBitRate + { + get + { + if (this._audioThresholdBitRate == null) + this._audioThresholdBitRate = this.ActiveDevice.AudioTranscodeLimit.ToString(); + return this._audioThresholdBitRate; + } + set + { + if (!(this._audioThresholdBitRate != value)) + return; + this._audioThresholdBitRate = value; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnAudioConversionChoiceCommit)] = (object)this.CommitDeviceID; + this.FirePropertyChanged(nameof(AudioThresholdBitRate)); + } + } + + public string AudioTargetBitRate + { + get + { + if (this._audioTargetBitRate == null) + this._audioTargetBitRate = this.ActiveDevice.AudioTranscodeTarget.ToString(); + return this._audioTargetBitRate; + } + set + { + if (!(this._audioTargetBitRate != value)) + return; + this._audioTargetBitRate = value; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnAudioConversionChoiceCommit)] = (object)this.CommitDeviceID; + this.FirePropertyChanged(nameof(AudioTargetBitRate)); + } + } + + private void OnAudioConversionChoiceCommit(object data) + { + int result = 0; + if (this.AudioConversionChoice.ChosenIndex == 1) + { + int.TryParse(this._audioThresholdBitRate, out result); + this.ActiveDevice.AudioTranscodeLimit = result; + } + else + this.ActiveDevice.AudioTranscodeLimit = -1; + int.TryParse(this._audioTargetBitRate, out result); + this.ActiveDevice.AudioTranscodeTarget = result; + } + + public Choice VideoConversionChoice + { + get + { + if (this._videoConversionChoice == null) + { + this._videoConversionOptions = (IList)new List(); + this._videoConversionOptions.Add(new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_TRANSCODE_VIDEO_PLAYBACK_OPTION), (EventHandler)null)); + this._videoConversionOptions.Add(new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_TRANSCODE_VIDEO_TV_OUT_OPTION), (EventHandler)null)); + this._videoConversionChoice = new Choice((IModelItemOwner)this); + this._videoConversionChoice.Options = (IList)this._videoConversionOptions; + this._videoConversionChoice.DefaultIndex = this.ActiveDevice.OptimizeVideoForTV ? 1 : 0; + this._videoConversionChoice.DefaultValue(); + this._videoConversionChoice.ChosenChanged += (EventHandler)((sender, args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnVideoConversionChoiceCommit)] = (object)this.CommitDeviceID); + } + return this._videoConversionChoice; + } + private set + { + if (this._videoConversionChoice == value) + return; + this._videoConversionChoice = value; + this.FirePropertyChanged(nameof(VideoConversionChoice)); + } + } + + private void OnVideoConversionChoiceCommit(object data) => this.ActiveDevice.OptimizeVideoForTV = this._videoConversionChoice.ChosenIndex == 1; + + public IList BitRateList + { + get + { + if (this._bitRateList == null) + { + this._bitRateList = (IList)new List(this._defaultBitRates.Length); + for (int index = 0; index < this._defaultBitRates.Length; ++index) + this._bitRateList.Add(new Command((IModelItemOwner)null, this._defaultBitRates[index].ToString(), (EventHandler)null)); + } + return this._bitRateList; + } + } + + public float ReservedSpaceOnDevice + { + get + { + if (float.IsNaN(this._reservedSpaceOnDevice)) + this._reservedSpaceOnDevice = (float)this.ActiveDevice.PercentReserved; + return this._reservedSpaceOnDevice; + } + set + { + if ((double)this._reservedSpaceOnDevice == (double)value) + return; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnReservedSpaceOnDeviceCommit)] = (object)this.CommitDeviceID; + this._reservedSpaceOnDevice = value; + } + } + + private void OnReservedSpaceOnDeviceCommit(object data) => this.ActiveDevice.PercentReserved = (int)this._reservedSpaceOnDevice; + + public SyncGroupList SyncGroupList + { + get + { + if (this._syncGroups == null) + this._syncGroups = this.ActiveDevice.GenerateSyncGroupList((IModelItemOwner)this, false); + return this._syncGroups; + } + } + + public BooleanChoice PrivacyChoice + { + get + { + if (this._privacyChoice == null) + { + this._privacyChoice = new BooleanChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_DEVICE_USAGE_DATA_CHECK)); + this._privacyChoice.Value = this.ActiveDevice.EnableWatson; + this._privacyChoice.ChosenChanged += (EventHandler)((sender, args) => ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnPrivacyChoiceCommit)] = (object)this.CommitDeviceID); + } + return this._privacyChoice; + } + } + + private void OnPrivacyChoiceCommit(object data) => this.ActiveDevice.EnableWatson = this.PrivacyChoice.Value; + + public void AutomatePrivacy(bool enable) + { + this.ActiveDevice.EnableWatson = enable; + ZuneShell.DefaultInstance.Management.CommitList[(object)new ProxySettingDelegate(this.OnPrivacyChoiceCommit)] = (object)this.CommitDeviceID; + } + + private int CommitDeviceID => !this.ActiveDevice.IsGuest ? this.ActiveDevice.ID : -1; + } +} diff --git a/ZuneUI/DeviceOverfillLand.cs b/ZuneUI/DeviceOverfillLand.cs new file mode 100644 index 0000000..28b37c3 --- /dev/null +++ b/ZuneUI/DeviceOverfillLand.cs @@ -0,0 +1,94 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceOverfillLand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class DeviceOverfillLand : DialogPage + { + private UIDevice _device; + private SyncGroupList _list; + private bool _deviceWasLocked; + + public DeviceOverfillLand(UIDevice device) + { + this._device = device; + this._list = this.Device.GenerateSyncGroupList((IModelItemOwner)this, true); + Deviceland.InitDevicePage((ZunePage)this); + this.ShowBackArrow = false; + this.ShowComputerIcon = ComputerIconState.Hide; + this.ShowNowPlayingX = false; + this.ShowPivots = false; + this.ShowSearch = false; + this.ShowSettings = false; + this.UI = "res://ZuneShellResources!DeviceSyncGroups.uix#SyncGroupsPage"; + this.BottomBarUI = "res://ZuneShellResources!DeviceSyncGroups.uix#GasGauge"; + } + + public UIDevice Device => this._device; + + public SyncGroupList List => this._list; + + public override bool IsWizard => false; + + public override bool AllowAdvance + { + get => true; + set => throw new NotSupportedException(); + } + + public override bool AllowCancel + { + get => true; + set => throw new NotSupportedException(); + } + + public override bool RequireSecurityIcon + { + get => false; + set => throw new NotSupportedException(); + } + + public override void NavigatePage(bool forward) => throw new NotSupportedException(); + + public override bool NavigationAvailable(bool forward) => false; + + public override void Save() + { + this.List.CommitChanges((object)null); + if (this._deviceWasLocked) + return; + this.Device.IsLockedAgainstSyncing = false; + if (this.List.GasGauge.FreeSpace < 0L) + return; + this.Device.BeginSync(true, false); + } + + public override void Exit() => ZuneShell.DefaultInstance.NavigateBack(); + + public override void SaveAndExit() + { + this.Save(); + this.Exit(); + } + + public override void CancelAndExit() + { + this.Device.IsLockedAgainstSyncing = this._deviceWasLocked; + this.Exit(); + } + + protected override void OnNavigatedToWorker() + { + this._deviceWasLocked = this.Device.IsLockedAgainstSyncing; + if (!this._deviceWasLocked) + this.Device.IsLockedAgainstSyncing = true; + base.OnNavigatedToWorker(); + } + } +} diff --git a/ZuneUI/DevicePivotManagingPageState.cs b/ZuneUI/DevicePivotManagingPageState.cs new file mode 100644 index 0000000..051eff4 --- /dev/null +++ b/ZuneUI/DevicePivotManagingPageState.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DevicePivotManagingPageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DevicePivotManagingPageState : IPageState + { + private IDeviceContentsPage _page; + + public DevicePivotManagingPageState(IDeviceContentsPage page) => this._page = page; + + public virtual IPage RestoreAndRelease() + { + if (this._page.ShowDeviceContents) + Shell.MainFrame.ShowDevice(true); + return (IPage)this._page; + } + + public void Release() => this._page.Release(); + + public bool CanBeTrimmed => false; + + protected IDeviceContentsPage Page => this._page; + } +} diff --git a/ZuneUI/DeviceRelationship.cs b/ZuneUI/DeviceRelationship.cs new file mode 100644 index 0000000..bd1febf --- /dev/null +++ b/ZuneUI/DeviceRelationship.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRelationship +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum DeviceRelationship + { + None = 0, + Permanent = 2, + Guest = 3, + } +} diff --git a/ZuneUI/DeviceRestoreBatteryPowerPage.cs b/ZuneUI/DeviceRestoreBatteryPowerPage.cs new file mode 100644 index 0000000..47ea3f6 --- /dev/null +++ b/ZuneUI/DeviceRestoreBatteryPowerPage.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRestoreBatteryPowerPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRestoreBatteryPowerPage : WizardPage + { + internal DeviceRestoreBatteryPowerPage(DeviceRestoreWizard wizard) + : base((Wizard)wizard) + => this.Description = Shell.LoadString(StringId.IDS_AC_POWER_WARNING_TITLE); + + public override bool IsEnabled + { + get + { + DeviceRestoreWizard owner = (DeviceRestoreWizard)this._owner; + return owner.UIFirmwareRestorer == null || owner.UIFirmwareRestorer.IsOnBatteryPower; + } + } + + public override string UI => "res://ZuneShellResources!DeviceRestore.uix#DeviceRestoreBatteryPowerPage"; + } +} diff --git a/ZuneUI/DeviceRestoreConfirmationPage.cs b/ZuneUI/DeviceRestoreConfirmationPage.cs new file mode 100644 index 0000000..2afaebf --- /dev/null +++ b/ZuneUI/DeviceRestoreConfirmationPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRestoreConfirmationPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRestoreConfirmationPage : DeviceRestorePage + { + internal DeviceRestoreConfirmationPage(DeviceRestoreWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_DEVICE_RESTORE_YOUR_PHONE); + + public override string UI => "res://ZuneShellResources!DeviceRestore.uix#DeviceRestoreConfirmationPage"; + } +} diff --git a/ZuneUI/DeviceRestoreErrorPage.cs b/ZuneUI/DeviceRestoreErrorPage.cs new file mode 100644 index 0000000..dabd371 --- /dev/null +++ b/ZuneUI/DeviceRestoreErrorPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRestoreErrorPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRestoreErrorPage : WizardErrorPage + { + internal DeviceRestoreErrorPage(DeviceRestoreWizard wizard) + : base((Wizard)wizard) + => this.Description = Shell.LoadString(StringId.IDS_DEVICE_RESTORE_ERROR_TITLE); + + public override string UI => "res://ZuneShellResources!DeviceRestore.uix#DeviceRestoreErrorPage"; + } +} diff --git a/ZuneUI/DeviceRestoreLandPage.cs b/ZuneUI/DeviceRestoreLandPage.cs new file mode 100644 index 0000000..fb42f66 --- /dev/null +++ b/ZuneUI/DeviceRestoreLandPage.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRestoreLandPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class DeviceRestoreLandPage : SetupLandPage + { + public DeviceRestoreLandPage() => this.UI = "res://ZuneShellResources!SetupLand.uix#DeviceRestore"; + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + SyncControls.Instance.CurrentDeviceOverride.Enumerate(); + DeviceManagement.HandleSetupQueue(); + }, DeferredInvokePriority.Low); + } + } +} diff --git a/ZuneUI/DeviceRestorePage.cs b/ZuneUI/DeviceRestorePage.cs new file mode 100644 index 0000000..118f112 --- /dev/null +++ b/ZuneUI/DeviceRestorePage.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRestorePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class DeviceRestorePage : WizardPage + { + protected DeviceRestorePage(DeviceRestoreWizard wizard) + : base((ZuneUI.Wizard)wizard) + { + } + + protected DeviceRestoreWizard Wizard => (DeviceRestoreWizard)this._owner; + } +} diff --git a/ZuneUI/DeviceRestoreProgressPage.cs b/ZuneUI/DeviceRestoreProgressPage.cs new file mode 100644 index 0000000..1459d34 --- /dev/null +++ b/ZuneUI/DeviceRestoreProgressPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRestoreProgressPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRestoreProgressPage : DeviceRestorePage + { + internal DeviceRestoreProgressPage(DeviceRestoreWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_DEVICE_RESTORE_IN_PROGRESS); + + public override string UI => "res://ZuneShellResources!DeviceRestore.uix#DeviceRestoreProgressPage"; + } +} diff --git a/ZuneUI/DeviceRestoreSummaryPage.cs b/ZuneUI/DeviceRestoreSummaryPage.cs new file mode 100644 index 0000000..63d61b4 --- /dev/null +++ b/ZuneUI/DeviceRestoreSummaryPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRestoreSummaryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRestoreSummaryPage : DeviceRestorePage + { + internal DeviceRestoreSummaryPage(DeviceRestoreWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_DEVICE_RESTORE_SUCCESS); + + public override string UI => "res://ZuneShellResources!DeviceRestore.uix#DeviceRestoreSummaryPage"; + } +} diff --git a/ZuneUI/DeviceRestoreSyncingPage.cs b/ZuneUI/DeviceRestoreSyncingPage.cs new file mode 100644 index 0000000..a955df5 --- /dev/null +++ b/ZuneUI/DeviceRestoreSyncingPage.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRestoreSyncingPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRestoreSyncingPage : DeviceRestorePage + { + private bool _isLockedAgainstSyncing; + + internal DeviceRestoreSyncingPage(DeviceRestoreWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_DEVICE_RESTORE_YOUR_PHONE); + + public override string UI => "res://ZuneShellResources!DeviceRestore.uix#DeviceRestoreSyncingPage"; + + internal override void Activate() + { + base.Activate(); + this._isLockedAgainstSyncing = this.Wizard.ActiveDevice.IsLockedAgainstSyncing; + } + + internal override void Deactivate() + { + this.Wizard.ActiveDevice.EndSync(); + this.Wizard.ActiveDevice.IsLockedAgainstSyncing = this._isLockedAgainstSyncing; + base.Deactivate(); + } + + public override bool IsEnabled => this.Wizard.ActiveDevice.SupportsBrandingType(DeviceBranding.WindowsPhone) && !this.Wizard.ActiveDevice.IsGuest && this.Wizard.ActiveDevice.InStandardMode; + + public override bool CanCancel => true; + + public bool BeginSync() + { + if (!this.Wizard.ActiveDevice.IsReadyForSync) + return false; + this.Wizard.ActiveDevice.IsLockedAgainstSyncing = false; + this.Wizard.ActiveDevice.BeginSync(true, false); + return true; + } + } +} diff --git a/ZuneUI/DeviceRestoreWizard.cs b/ZuneUI/DeviceRestoreWizard.cs new file mode 100644 index 0000000..33dcb83 --- /dev/null +++ b/ZuneUI/DeviceRestoreWizard.cs @@ -0,0 +1,42 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRestoreWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRestoreWizard : DeviceWizard + { + private UIFirmwareRestorer _restorer; + + public DeviceRestoreWizard() + { + this.AddPage((WizardPage)new DeviceRestoreConfirmationPage(this)); + this.AddPage((WizardPage)new DeviceRestoreBatteryPowerPage(this)); + this.AddPage((WizardPage)new DeviceRestoreSyncingPage(this)); + this.AddPage((WizardPage)new DeviceRestoreProgressPage(this)); + this.AddPage((WizardPage)new DeviceRestoreSummaryPage(this)); + this.AddPage((WizardPage)new DeviceRestoreErrorPage(this)); + } + + public UIFirmwareRestorer UIFirmwareRestorer + { + get => this._restorer; + set + { + if (this._restorer == value) + return; + this._restorer = value; + this.FirePropertyChanged(nameof(UIFirmwareRestorer)); + } + } + + public override void Cancel() + { + if (this._restorer != null && this._restorer.RestoreInProgress) + this._restorer.CancelFirmwareRestore(); + base.Cancel(); + } + } +} diff --git a/ZuneUI/DeviceRollbackErrorPage.cs b/ZuneUI/DeviceRollbackErrorPage.cs new file mode 100644 index 0000000..e8309ff --- /dev/null +++ b/ZuneUI/DeviceRollbackErrorPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRollbackErrorPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRollbackErrorPage : WizardErrorPage + { + internal DeviceRollbackErrorPage(DeviceRollbackWizard wizard) + : base((Wizard)wizard) + => this.Description = Shell.LoadString(StringId.IDS_DEVICE_RESTORE_ERROR_TITLE); + + public override string UI => "res://ZuneShellResources!DeviceRollback.uix#DeviceRollbackErrorPage"; + } +} diff --git a/ZuneUI/DeviceRollbackPage.cs b/ZuneUI/DeviceRollbackPage.cs new file mode 100644 index 0000000..145fcfa --- /dev/null +++ b/ZuneUI/DeviceRollbackPage.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRollbackPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class DeviceRollbackPage : WizardPage + { + protected DeviceRollbackPage(DeviceRollbackWizard wizard) + : base((ZuneUI.Wizard)wizard) + { + } + + protected DeviceRollbackWizard Wizard => (DeviceRollbackWizard)this._owner; + + public override bool CanCancel => this.Wizard.UIFirmwareUpdater != null && this.Wizard.UIFirmwareUpdater.CanCancel; + } +} diff --git a/ZuneUI/DeviceRollbackProgressPage.cs b/ZuneUI/DeviceRollbackProgressPage.cs new file mode 100644 index 0000000..bd5bdb3 --- /dev/null +++ b/ZuneUI/DeviceRollbackProgressPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRollbackProgressPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRollbackProgressPage : DeviceRollbackPage + { + internal DeviceRollbackProgressPage(DeviceRollbackWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_DEVICE_ROLLBACK_IN_PROGRESS); + + public override string UI => "res://ZuneShellResources!DeviceRollback.uix#DeviceRollbackProgressPage"; + } +} diff --git a/ZuneUI/DeviceRollbackSummaryPage.cs b/ZuneUI/DeviceRollbackSummaryPage.cs new file mode 100644 index 0000000..0d5b90e --- /dev/null +++ b/ZuneUI/DeviceRollbackSummaryPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRollbackSummaryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRollbackSummaryPage : DeviceRollbackPage + { + internal DeviceRollbackSummaryPage(DeviceRollbackWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_DEVICE_ROLLBACK_COMPLETE_TITLE); + + public override string UI => "res://ZuneShellResources!DeviceRollback.uix#DeviceRollbackSummaryPage"; + } +} diff --git a/ZuneUI/DeviceRollbackWizard.cs b/ZuneUI/DeviceRollbackWizard.cs new file mode 100644 index 0000000..b2ca3fb --- /dev/null +++ b/ZuneUI/DeviceRollbackWizard.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceRollbackWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceRollbackWizard : Wizard + { + private UIFirmwareUpdater _updater; + + public DeviceRollbackWizard() + { + this.AddPage((WizardPage)new DeviceRollbackProgressPage(this)); + this.AddPage((WizardPage)new DeviceRollbackSummaryPage(this)); + this.AddPage((WizardPage)new DeviceRollbackErrorPage(this)); + } + + public UIFirmwareUpdater UIFirmwareUpdater + { + get => this._updater; + set + { + if (this._updater == value) + return; + this._updater = value; + this.FirePropertyChanged(nameof(UIFirmwareUpdater)); + } + } + } +} diff --git a/ZuneUI/DeviceSetupHashtable.cs b/ZuneUI/DeviceSetupHashtable.cs new file mode 100644 index 0000000..b92e91c --- /dev/null +++ b/ZuneUI/DeviceSetupHashtable.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceSetupHashtable +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class DeviceSetupHashtable : Hashtable + { + public override object this[object key] + { + get => base[key]; + set + { + base[key] = value; + DeviceManagement.HandleSetupQueue(); + } + } + } +} diff --git a/ZuneUI/DeviceUpdateBatteryPowerPage.cs b/ZuneUI/DeviceUpdateBatteryPowerPage.cs new file mode 100644 index 0000000..7341a7f --- /dev/null +++ b/ZuneUI/DeviceUpdateBatteryPowerPage.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateBatteryPowerPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceUpdateBatteryPowerPage : DeviceUpdatePage + { + internal DeviceUpdateBatteryPowerPage(DeviceUpdateWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_AC_POWER_WARNING_TITLE); + + public override bool IsEnabled + { + get + { + DeviceUpdateWizard owner = (DeviceUpdateWizard)this._owner; + return !owner.IsChainedUpdate && (owner.UIFirmwareUpdater == null || owner.UIFirmwareUpdater.IsOnBatteryPower); + } + } + + public override string UI => "res://ZuneShellResources!DeviceUpdate.uix#DeviceUpdateBatteryPowerPage"; + } +} diff --git a/ZuneUI/DeviceUpdateCheckingPage.cs b/ZuneUI/DeviceUpdateCheckingPage.cs new file mode 100644 index 0000000..a8170be --- /dev/null +++ b/ZuneUI/DeviceUpdateCheckingPage.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateCheckingPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceUpdateCheckingPage : DeviceUpdatePage + { + internal DeviceUpdateCheckingPage(DeviceUpdateWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_PHONE_UPDATE_CHECKING_TITLE); + + public override bool IsEnabled => this.Wizard.ActiveDevice.SupportsBrandingType(DeviceBranding.WindowsPhone); + + public override string UI => "res://ZuneShellResources!DeviceUpdate.uix#DeviceUpdateCheckingPage"; + + internal override bool OnMovingNext() + { + if (SoftwareUpdates.Instance.LastUpdateCheckResult == null || !SoftwareUpdates.Instance.LastUpdateCheckResult.UpdateFound) + return base.OnMovingNext(); + SoftwareUpdates.Instance.InstallUpdates(); + return false; + } + } +} diff --git a/ZuneUI/DeviceUpdateDiskSpaceErrorPage.cs b/ZuneUI/DeviceUpdateDiskSpaceErrorPage.cs new file mode 100644 index 0000000..ccfc99b --- /dev/null +++ b/ZuneUI/DeviceUpdateDiskSpaceErrorPage.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateDiskSpaceErrorPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class DeviceUpdateDiskSpaceErrorPage : DeviceUpdatePage + { + internal DeviceUpdateDiskSpaceErrorPage(DeviceUpdateWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_FIRMWARE_UPDATE_IN_PROGRESS_HEADER); + + public override string UI => "res://ZuneShellResources!DeviceUpdate.uix#DeviceUpdateDiskSpaceErrorPage"; + + public override bool IsEnabled => this.Wizard.ActiveDevice.SupportsBrandingType(DeviceBranding.WindowsPhone) && this.Wizard.UIFirmwareUpdater != null; + + internal override void Activate() + { + base.Activate(); + if (this.Wizard.ActiveDevice.SkipFutureBackupRequests) + { + this.Wizard.UIFirmwareUpdater.UpdateOption = FirmwareUpdateOption.NoBackup; + this.Wizard.MoveNext(); + } + else + this.Wizard.UIFirmwareUpdater.StartCheckForDiskSpace(); + } + + public override bool CanCancel => true; + } +} diff --git a/ZuneUI/DeviceUpdateEULAPage.cs b/ZuneUI/DeviceUpdateEULAPage.cs new file mode 100644 index 0000000..c722cec --- /dev/null +++ b/ZuneUI/DeviceUpdateEULAPage.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateEULAPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceUpdateEULAPage : DeviceUpdatePage + { + internal DeviceUpdateEULAPage(DeviceUpdateWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(SyncControls.Instance.CurrentDeviceOverride.RequiresFirmwareUpdate ? StringId.IDS_EULA_DIALOG_TITLE_REQUIRED : StringId.IDS_EULA_DIALOG_TITLE); + + public override string UI => "res://ZuneShellResources!DeviceUpdate.uix#DeviceUpdateEULAPage"; + + public override bool IsEnabled + { + get + { + bool flag = true; + if (this.Wizard.ActiveDevice.SupportsBrandingType(DeviceBranding.WindowsPhone)) + flag = !this.Wizard.IsChainedUpdate && (this.Wizard.UIFirmwareUpdater != null && !string.IsNullOrEmpty(this.Wizard.UIFirmwareUpdater.NewFirmwareEULAContent)); + return flag; + } + } + } +} diff --git a/ZuneUI/DeviceUpdateErrorPage.cs b/ZuneUI/DeviceUpdateErrorPage.cs new file mode 100644 index 0000000..019a110 --- /dev/null +++ b/ZuneUI/DeviceUpdateErrorPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateErrorPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceUpdateErrorPage : WizardErrorPage + { + internal DeviceUpdateErrorPage(DeviceUpdateWizard wizard) + : base((Wizard)wizard) + => this.Description = Shell.LoadString(StringId.IDS_FIRMWARE_UPDATE_ERROR_TITLE); + + public override string UI => "res://ZuneShellResources!DeviceUpdate.uix#DeviceUpdateErrorPage"; + } +} diff --git a/ZuneUI/DeviceUpdateGuestWarningPage.cs b/ZuneUI/DeviceUpdateGuestWarningPage.cs new file mode 100644 index 0000000..60406e7 --- /dev/null +++ b/ZuneUI/DeviceUpdateGuestWarningPage.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateGuestWarningPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceUpdateGuestWarningPage : DeviceUpdatePage + { + internal DeviceUpdateGuestWarningPage(DeviceUpdateWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_PHONE_UPDATE_GUEST_WARNING_TITLE); + + public override string UI => "res://ZuneShellResources!DeviceUpdate.uix#DeviceUpdateGuestWarningPage"; + + public override bool IsEnabled => this.Wizard.ActiveDevice.SupportsBrandingType(DeviceBranding.WindowsPhone) && this.Wizard.ActiveDevice.IsGuest && !this.Wizard.IsChainedUpdate; + + public override bool CanCancel => true; + } +} diff --git a/ZuneUI/DeviceUpdateLandPage.cs b/ZuneUI/DeviceUpdateLandPage.cs new file mode 100644 index 0000000..1d24d6e --- /dev/null +++ b/ZuneUI/DeviceUpdateLandPage.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateLandPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class DeviceUpdateLandPage : SetupLandPage + { + public DeviceUpdateLandPage() => this.UI = "res://ZuneShellResources!SetupLand.uix#DeviceUpdate"; + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + SyncControls.Instance.CurrentDeviceOverride.Enumerate(); + DeviceManagement.HandleSetupQueue(); + }, DeferredInvokePriority.Low); + } + } +} diff --git a/ZuneUI/DeviceUpdatePage.cs b/ZuneUI/DeviceUpdatePage.cs new file mode 100644 index 0000000..bcced6f --- /dev/null +++ b/ZuneUI/DeviceUpdatePage.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdatePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class DeviceUpdatePage : WizardPage + { + protected DeviceUpdatePage(DeviceUpdateWizard wizard) + : base((ZuneUI.Wizard)wizard) + { + } + + protected DeviceUpdateWizard Wizard => (DeviceUpdateWizard)this._owner; + + public override bool CanCancel + { + get + { + if (this.Wizard.Disconnected) + return true; + return this.Wizard.UIFirmwareUpdater != null && this.Wizard.UIFirmwareUpdater.CanCancel; + } + } + } +} diff --git a/ZuneUI/DeviceUpdateProgressPage.cs b/ZuneUI/DeviceUpdateProgressPage.cs new file mode 100644 index 0000000..9b5688f --- /dev/null +++ b/ZuneUI/DeviceUpdateProgressPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateProgressPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceUpdateProgressPage : DeviceUpdatePage + { + internal DeviceUpdateProgressPage(DeviceUpdateWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_FIRMWARE_UPDATE_IN_PROGRESS_HEADER); + + public override string UI => "res://ZuneShellResources!DeviceUpdate.uix#DeviceUpdateProgressPage"; + } +} diff --git a/ZuneUI/DeviceUpdateSummaryPage.cs b/ZuneUI/DeviceUpdateSummaryPage.cs new file mode 100644 index 0000000..ea471e0 --- /dev/null +++ b/ZuneUI/DeviceUpdateSummaryPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateSummaryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceUpdateSummaryPage : DeviceUpdatePage + { + internal DeviceUpdateSummaryPage(DeviceUpdateWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_FIRMWARE_UPDATE_SUCCESSFUL_HEADER); + + public override string UI => "res://ZuneShellResources!DeviceUpdate.uix#DeviceUpdateSummaryPage"; + } +} diff --git a/ZuneUI/DeviceUpdateSyncingPage.cs b/ZuneUI/DeviceUpdateSyncingPage.cs new file mode 100644 index 0000000..c0bfd5d --- /dev/null +++ b/ZuneUI/DeviceUpdateSyncingPage.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateSyncingPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class DeviceUpdateSyncingPage : DeviceUpdatePage + { + private bool _isLockedAgainstSyncing; + + internal DeviceUpdateSyncingPage(DeviceUpdateWizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_FIRMWARE_UPDATE_IN_PROGRESS_HEADER); + + public override string UI => "res://ZuneShellResources!DeviceUpdate.uix#DeviceUpdateSyncingPage"; + + internal override void Activate() + { + base.Activate(); + this._isLockedAgainstSyncing = this.Wizard.ActiveDevice.IsLockedAgainstSyncing; + } + + internal override void Deactivate() + { + this.Wizard.ActiveDevice.EndSync(); + this.Wizard.ActiveDevice.IsLockedAgainstSyncing = this._isLockedAgainstSyncing; + base.Deactivate(); + } + + public override bool IsEnabled => this.Wizard.ActiveDevice.SupportsBrandingType(DeviceBranding.WindowsPhone) && !this.Wizard.ActiveDevice.IsGuest && (this.Wizard.UIFirmwareUpdater != null && this.Wizard.UIFirmwareUpdater.RequiresSyncBeforeUpdate) && !this.Wizard.IsChainedUpdate; + + public override bool CanCancel => true; + + public bool BeginSync() + { + if (!this.Wizard.ActiveDevice.IsReadyForSync) + return false; + this.Wizard.ActiveDevice.IsLockedAgainstSyncing = false; + this.Wizard.ActiveDevice.BeginSync(true, false); + return true; + } + } +} diff --git a/ZuneUI/DeviceUpdateWizard.cs b/ZuneUI/DeviceUpdateWizard.cs new file mode 100644 index 0000000..6eed39e --- /dev/null +++ b/ZuneUI/DeviceUpdateWizard.cs @@ -0,0 +1,118 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceUpdateWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class DeviceUpdateWizard : DeviceWizard + { + private UIFirmwareUpdater _updater; + private bool _isUpdateAvailable; + private bool _isLiveIdSignInSuccess; + private bool _chainedUpdate; + + public DeviceUpdateWizard() => this.AddPages(); + + protected virtual void AddPages() + { + this.AddPage((WizardPage)new DeviceUpdateCheckingPage(this)); + this.AddPage((WizardPage)new DeviceUpdateEULAPage(this)); + this.AddPage((WizardPage)new DeviceUpdateBatteryPowerPage(this)); + this.AddPage((WizardPage)new DeviceUpdateGuestWarningPage(this)); + this.AddPage((WizardPage)new DeviceUpdateSyncingPage(this)); + this.AddPage((WizardPage)new DeviceUpdateDiskSpaceErrorPage(this)); + this.AddPage((WizardPage)new DeviceUpdateProgressPage(this)); + this.AddPage((WizardPage)new DeviceUpdateSummaryPage(this)); + this.AddPage((WizardPage)new DeviceUpdateErrorPage(this)); + } + + public UIFirmwareUpdater UIFirmwareUpdater + { + get => this._updater; + set + { + if (this._updater == value) + return; + this._updater = value; + this.FirePropertyChanged(nameof(UIFirmwareUpdater)); + this.IsUpdateAvailable = this._updater.IsUpdateAvailable; + } + } + + public bool IsUpdateAvailable + { + get => this._isUpdateAvailable; + set + { + if (this._isUpdateAvailable == value) + return; + this._isUpdateAvailable = value; + this.FirePropertyChanged(nameof(IsUpdateAvailable)); + } + } + + public bool IsChainedUpdate + { + get => this._chainedUpdate; + set + { + if (this._chainedUpdate == value) + return; + this._chainedUpdate = value; + this.FirePropertyChanged(nameof(IsChainedUpdate)); + } + } + + public bool IsLiveIdSignInSuccess + { + get => this._isLiveIdSignInSuccess; + set + { + this._isLiveIdSignInSuccess = value; + this.FirePropertyChanged(nameof(IsLiveIdSignInSuccess)); + } + } + + public override void Cancel() + { + if (this._updater != null && this._updater.UpdateInProgress) + this._updater.CancelFirmwareUpdate(); + if (this.ActiveDevice != null && this.ActiveDevice != UIDeviceList.NullDevice) + { + this.ActiveDevice.SequentialUpdatesInstalled = 0; + this.ActiveDevice.SkipFutureBackupRequests = false; + } + if (this.CurrentPage is DeviceUpdatePage && (this.ActiveDevice == UIDeviceList.NullDevice || !this.ActiveDevice.RequiresFirmwareUpdate) || this.CurrentPage is DeviceUpdateErrorPage) + this.OnCommitChanges(); + else + base.Cancel(); + } + + public void SignInWithDeviceLiveId(UIDevice device, string password) + { + SignIn.Instance.SignOut(); + SignIn.Instance.CancelSignIn(); + if (string.IsNullOrEmpty(device.LiveId) || string.IsNullOrEmpty(password)) + { + this.IsLiveIdSignInSuccess = false; + } + else + { + SignIn.Instance.SignInStatusUpdatedEvent += new EventHandler(this.OnSignInStatusUpdatedEvent); + SignIn.Instance.SignInUser(device.LiveId, password); + } + } + + private void OnSignInStatusUpdatedEvent(object sender, EventArgs e) + { + if (SignIn.Instance.SigningIn || !SignIn.Instance.SignInError.IsError && !SignIn.Instance.SignedIn) + return; + SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignInStatusUpdatedEvent); + this.IsLiveIdSignInSuccess = SignIn.Instance.SignInError.IsSuccess; + } + } +} diff --git a/ZuneUI/DeviceWizard.cs b/ZuneUI/DeviceWizard.cs new file mode 100644 index 0000000..1698014 --- /dev/null +++ b/ZuneUI/DeviceWizard.cs @@ -0,0 +1,67 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DeviceWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class DeviceWizard : Wizard + { + private bool _disconnected; + private UIDevice _activeDevice; + + public DeviceWizard() => SingletonModelItem.Instance.DeviceDisconnectedEvent += new DeviceListEventHandler(this.OnDeviceDisconnected); + + public UIDevice ActiveDevice + { + get + { + if (this._activeDevice == null) + this._activeDevice = DeviceManagement.SetupDevice != null ? DeviceManagement.SetupDevice : SyncControls.Instance.CurrentDeviceOverride; + return this._activeDevice; + } + } + + public bool Disconnected + { + get => this._disconnected; + set + { + if (this._disconnected == value) + return; + this._disconnected = value; + this.FirePropertyChanged(nameof(Disconnected)); + } + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + SingletonModelItem.Instance.DeviceDisconnectedEvent -= new DeviceListEventHandler(this.OnDeviceDisconnected); + base.OnDispose(disposing); + } + + public override void Cancel() + { + this.CancelSettings(); + if (this.ActiveDevice != UIDeviceList.NullDevice && (this.ActiveDevice.RequiresFirmwareUpdate || this.ActiveDevice.Relationship == DeviceRelationship.None || !this.ActiveDevice.InStandardMode)) + { + SingletonModelItem.Instance.HideDevice(this.ActiveDevice); + } + else + { + if (this.ActiveDevice.Relationship != DeviceRelationship.Guest) + return; + ZuneShell.DefaultInstance.Management.DisposeDeviceManagement(false); + } + } + + private void OnDeviceDisconnected(object sender, DeviceListEventArgs args) + { + if (this.ActiveDevice != args.Device) + return; + this.Disconnected = true; + } + } +} diff --git a/ZuneUI/Deviceland.cs b/ZuneUI/Deviceland.cs new file mode 100644 index 0000000..b129448 --- /dev/null +++ b/ZuneUI/Deviceland.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Deviceland +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class Deviceland : ZunePage, IDeviceContentsPage, IPage + { + public Deviceland() + { + this.PivotPreference = Shell.MainFrame.Device.Status; + this.UI = "res://ZuneShellResources!DeviceSummary.uix#DeviceSummary"; + this.UIPath = "Device\\Summary"; + this.IsRootPage = true; + Deviceland.InitDevicePage((ZunePage)this); + this.ShowComputerIcon = ComputerIconState.Show; + } + + public static void InitDevicePage(ZunePage page) + { + page.BackgroundUI = "res://ZuneShellResources!DevicelandElements.uix#DeviceBackground"; + page.TransportControlStyle = TransportControlStyle.None; + page.ShowCDIcon = false; + page.ShowDeviceIcon = false; + page.ShowPlaylistIcon = false; + page.ShowComputerIcon = ComputerIconState.ShowAsDropTarget; + page.NotificationAreaVisible = false; + page.TransportControlsVisible = false; + page.BottomBarUI = "res://ZuneShellResources!DevicelandElements.uix#GasGauge"; + page.ShowAppBackground = false; + page.ShowNowPlayingBackgroundOnIdle = false; + } + + public override void InvokeSettings() => Shell.SettingsFrame.Settings.Device.Invoke(); + + protected override void OnNavigatedToWorker() + { + base.OnNavigatedToWorker(); + Management management = ZuneShell.DefaultInstance.Management; + if (management.AlertedDeviceCategory == null) + return; + management.AlertedDeviceCategory = (Category)null; + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)new FirstConnectLandPage()); + } + + public override IPageState SaveAndRelease() => (IPageState)new DevicePivotManagingPageState((IDeviceContentsPage)this); + + bool IDeviceContentsPage.ShowDeviceContents => true; + } +} diff --git a/ZuneUI/DialogPage.cs b/ZuneUI/DialogPage.cs new file mode 100644 index 0000000..7ce26da --- /dev/null +++ b/ZuneUI/DialogPage.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DialogPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class DialogPage : ZunePage + { + public abstract bool IsWizard { get; } + + public abstract bool AllowAdvance { get; set; } + + public abstract bool AllowCancel { get; set; } + + public abstract bool RequireSecurityIcon { get; set; } + + public abstract void Save(); + + public abstract void Exit(); + + public abstract void SaveAndExit(); + + public abstract void CancelAndExit(); + + public abstract void NavigatePage(bool forward); + + public abstract bool NavigationAvailable(bool forward); + } +} diff --git a/ZuneUI/DictionaryCommandHandler.cs b/ZuneUI/DictionaryCommandHandler.cs new file mode 100644 index 0000000..43f6884 --- /dev/null +++ b/ZuneUI/DictionaryCommandHandler.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DictionaryCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class DictionaryCommandHandler : ICommandHandler + { + private Dictionary _handlers; + private string _divider; + + public DictionaryCommandHandler() + { + this._handlers = new Dictionary(); + this._divider = "\\"; + } + + public IDictionary Handlers => (IDictionary)this._handlers; + + public string Divider + { + get => this._divider; + set => this._divider = !string.IsNullOrEmpty(value) ? value : throw new ArgumentException("Must provide a non-empty divider.", nameof(value)); + } + + public void Execute(string command, IDictionary commandArgs) + { + string prefix; + string suffix; + this.SplitCommand(command, out prefix, out suffix); + ICommandHandler commandHandler = (ICommandHandler)null; + if (this._handlers.ContainsKey(prefix)) + commandHandler = this._handlers[prefix]; + if (commandHandler == null) + throw new ArgumentException("Unknown prefix: " + prefix, "prefix"); + commandHandler.Execute(suffix, commandArgs); + } + + private void SplitCommand(string command, out string prefix, out string suffix) + { + int length = !string.IsNullOrEmpty(command) ? command.IndexOf(this._divider) : throw new ArgumentException("Must provide a non-empty command", nameof(command)); + if (length < 0) + { + prefix = command; + suffix = (string)null; + } + else + { + prefix = command.Substring(0, length); + suffix = command.Substring(length + this._divider.Length); + } + } + } +} diff --git a/ZuneUI/DiscExperience.cs b/ZuneUI/DiscExperience.cs new file mode 100644 index 0000000..bcbac4d --- /dev/null +++ b/ZuneUI/DiscExperience.cs @@ -0,0 +1,97 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DiscExperience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System.Collections; + +namespace ZuneUI +{ + public class DiscExperience : Experience + { + private ArrayListDataSet _nodes = new ArrayListDataSet(); + private CDAlbumCommand _burnList; + private CDAlbumCommand _noCD; + + public DiscExperience(Frame frameOwner) + : base(frameOwner, StringId.IDS_DISC_PIVOT, SQMDataId.DiscClicks) + { + } + + public override IList NodesList => (IList)this._nodes; + + public CDAlbumCommand BurnList + { + get + { + if (this._burnList == null) + this._burnList = new CDAlbumCommand((Experience)this, StringId.IDS_PLAYLIST_BURN_LIST); + return this._burnList; + } + } + + public CDAlbumCommand NoCD + { + get + { + if (this._noCD == null) + this._noCD = new CDAlbumCommand((Experience)this, StringId.IDS_NO_CD); + return this._noCD; + } + } + + public bool HasCD => this._nodes == null || this._nodes[0] != this.NoCD; + + protected override void OnIsCurrentChanged() => this.UpdateShowDisc(); + + public void UpdateShowDisc() => ((MainFrame)this.Frame).ShowDisc(this.IsCurrent || CDAccess.Instance.HasLoadedMedia || !CDAccess.Instance.IsBurnListEmpty); + + public void RecalculateAvailableNodes() + { + this._nodes.Clear(); + foreach (CDAlbumCommand cd in (ListDataSet)CDAccess.Instance.CDs) + { + if (cd != null && cd.TOC != null) + this._nodes.Add((object)cd); + } + if (CDAccess.Instance.BurnListId >= 0) + this._nodes.Add((object)this.BurnList); + if (this._nodes.Count == 0) + this._nodes.Add((object)this.NoCD); + this.UpdateShowDisc(); + } + + public void UpdateNodes(CDAccess cdAccess, char changedLetter, bool mediaArrived) + { + this.RecalculateAvailableNodes(); + CDAlbumCommand nodes1 = (CDAlbumCommand)this.NodesList[0]; + if (this.IsCurrent) + { + if (!(ZuneShell.DefaultInstance.CurrentPage is CDLand currentPage)) + return; + bool flag = false; + if (currentPage.Album.CDDevice != null && (int)currentPage.Album.CDDevice.DrivePath == (int)changedLetter) + flag = true; + if (!flag && (!mediaArrived || !this.NoCD.IsCurrent)) + return; + nodes1.Invoke(); + } + else + { + if (!mediaArrived) + return; + foreach (CDAlbumCommand nodes2 in (IEnumerable)this.NodesList) + { + if (nodes2.CDDevice != null && (int)nodes2.CDDevice.DrivePath == (int)changedLetter) + { + this.Nodes.ChosenValue = (object)nodes2; + break; + } + } + } + } + } +} diff --git a/ZuneUI/DocumentHelper.cs b/ZuneUI/DocumentHelper.cs new file mode 100644 index 0000000..077d8e9 --- /dev/null +++ b/ZuneUI/DocumentHelper.cs @@ -0,0 +1,44 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DocumentHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text; + +namespace ZuneUI +{ + public static class DocumentHelper + { + public static string SeparateParagraphs(string content) + { + if (content != null) + content = content.Replace("\r\n", "\r\n\r\n"); + return content; + } + + public static string CleanseWhitespace(string str) + { + if (string.IsNullOrEmpty(str)) + return str; + char[] chArray = new char[4] { ' ', '\n', '\r', '\t' }; + StringBuilder stringBuilder = new StringBuilder(); + string[] strArray = str.Split(chArray); + bool flag = false; + foreach (string str1 in strArray) + { + if (flag) + { + stringBuilder.Append(" "); + flag = false; + } + if (!string.IsNullOrEmpty(str1)) + { + stringBuilder.Append(str1); + flag = true; + } + } + return stringBuilder.ToString(); + } + } +} diff --git a/ZuneUI/Download.cs b/ZuneUI/Download.cs new file mode 100644 index 0000000..7cf25e0 --- /dev/null +++ b/ZuneUI/Download.cs @@ -0,0 +1,383 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Download +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using ZuneXml; + +namespace ZuneUI +{ + public class Download : ModelItem + { + private bool m_disposed; + private bool m_updatePending; + private ProgressNotification m_notification; + private Dictionary m_errors = new Dictionary(); + private Dictionary m_historyErrors = new Dictionary(); + private Microsoft.Zune.Service.EDownloadContextEvent m_clientContextEvent; + private string m_clientContextEventValue; + private static Download s_instance; + private static object s_cs = new object(); + private static string s_downloadCompleteMessage = ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD_COMPLETE_NOTIFICATION); + private static string s_downloadFailedMessage = ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD_FAILED_NOTIFICATION); + private static string s_downloadProgressMessage = ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD_PROGRESS_NOTIFICATION); + private static string s_downloadCurrentMessage = ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD_CURRENT_NOTIFICATION); + private static string s_downloadPausedMessage = ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD_PAUSED_NOTIFICATION); + private static string s_downloadMBRPausedMessage = ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD_MBR_PAUSED_NOTIFICATION); + private static string s_downloadSignInMessage = ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD_SIGNIN_NOTIFICATION); + + public event DownloadEventHandler DownloadEvent; + + public event DownloadEventProgressHandler DownloadProgressEvent; + + public event EventHandler DownloadAllPendingEvent; + + public static Download Instance + { + get + { + if (Download.s_instance == null) + { + lock (Download.s_cs) + { + if (Download.s_instance == null) + Download.s_instance = new Download(); + } + } + return Download.s_instance; + } + } + + public static bool IsCreated => Download.s_instance != null; + + public void DownloadContent(IList items, Microsoft.Zune.Service.EDownloadFlags eDownloadFlags) => this.DownloadContent(items, eDownloadFlags, (string)null); + + internal void DownloadContent( + IList items, + Microsoft.Zune.Service.EDownloadFlags eDownloadFlags, + string deviceEndpointId) + { + this.DownloadContent(items, eDownloadFlags, deviceEndpointId, new EventHandler(this.OnAllPending)); + } + + public void DownloadContent( + IList items, + Microsoft.Zune.Service.EDownloadFlags eDownloadFlags, + string deviceEndpointId, + EventHandler onAllPending) + { + ZuneApplication.Service.Download(items, eDownloadFlags, deviceEndpointId, this.ClientContextEvent, this.ClientContextEventValue, new DownloadEventHandler(this.OnDownloadEvent), new DownloadEventProgressHandler(this.OnDownloadProgressEvent), onAllPending); + if ((eDownloadFlags & ~(Microsoft.Zune.Service.EDownloadFlags.CanBeOffline | Microsoft.Zune.Service.EDownloadFlags.Subscription)) != Microsoft.Zune.Service.EDownloadFlags.None) + return; + bool flag = ZuneShell.DefaultInstance.CurrentPage is InboxPage; + if ((eDownloadFlags & Microsoft.Zune.Service.EDownloadFlags.Subscription) != Microsoft.Zune.Service.EDownloadFlags.None) + SQMLog.Log(flag ? SQMDataId.InboxDownload : SQMDataId.MarketplaceDownload, 1); + else + SQMLog.Log(flag ? SQMDataId.InboxPurchase : SQMDataId.MarketplacePurchase, 1); + } + + public void AddToCollection(IList items) + { + ZuneApplication.Service.Download(items, Microsoft.Zune.Service.EDownloadFlags.Subscription, (string)null, this.ClientContextEvent, this.ClientContextEventValue, new DownloadEventHandler(this.OnDownloadEvent), new DownloadEventProgressHandler(this.OnDownloadProgressEvent), new EventHandler(this.OnAllPending)); + foreach (object obj in (IEnumerable)items) + { + if (obj is DataProviderObject) + { + DataProviderObject dataProviderObject = (DataProviderObject)obj; + if (dataProviderObject.TypeName == "PlaylistContentItem") + { + PlaylistManager.GetPlaylistId((int)dataProviderObject.GetProperty("LibraryId")); + UsageDataService.ReportTrackAddToCollection((Guid)dataProviderObject.GetProperty("ZuneMediaId"), PlaylistManager.GetFieldValue((int)dataProviderObject.GetProperty("MediaId"), EListType.eTrackList, 358, 0).ToString()); + } + else if (dataProviderObject is Track) + { + Track track = (Track)dataProviderObject; + UsageDataService.ReportTrackAddToCollection(track.Id, track.ReferrerContext); + } + } + } + } + + public bool IsDownloadingOrPending(Guid mediaId, Microsoft.Zune.Service.EContentType eContentType) + { + bool fPending; + return this.IsDownloading(mediaId, eContentType, out fPending) || fPending; + } + + public bool IsDownloading(Guid mediaId, Microsoft.Zune.Service.EContentType eContentType, out bool fPending) + { + bool fIsHidden = false; + return ZuneApplication.Service.IsDownloading(mediaId, eContentType, out fPending, out fIsHidden); + } + + public void CancelDownload(Guid mediaId) => ZuneApplication.Service.CancelDownload(mediaId, Microsoft.Zune.Service.EContentType.MusicTrack); + + public int ErrorCount => this.m_errors.Count; + + public int GetErrorCode(Guid mediaId) + { + int num; + if (!this.m_errors.TryGetValue(mediaId, out num)) + num = 0; + return num; + } + + internal void SetErrorCode(Guid mediaId, int errorCode) + { + this.m_errors[mediaId] = errorCode; + this.FirePropertyChanged("ErrorCount"); + } + + internal void Phase2Init() => DownloadManager.CreateInstance(); + + internal void Phase3Init() + { + DownloadManager.Instance.OnProgressChanged += new DownloadManagerUpdateHandler(this.OnProgressChanged); + ZuneApplication.Service.RegisterForDownloadNotification(new DownloadEventHandler(this.OnDownloadEvent), new DownloadEventProgressHandler(this.OnDownloadProgressEvent), new EventHandler(this.OnAllPending)); + SingletonModelItem.Instance.PropertyChanged += new PropertyChangedEventHandler(this.OnTransportControlPropertyChanged); + } + + private void ClearErrorCode(Guid mediaId) + { + this.m_errors.Remove(mediaId); + this.FirePropertyChanged("ErrorCount"); + } + + public int HistoryErrorCount => this.m_historyErrors.Count; + + public int GetHistoryErrorCode(Guid mediaId) + { + int num; + if (!this.m_historyErrors.TryGetValue(mediaId, out num)) + num = 0; + return num; + } + + internal void SetHistoryErrorCode(Guid mediaId, int errorCode) + { + this.m_historyErrors[mediaId] = errorCode; + this.FirePropertyChanged("HistoryErrorCount"); + } + + private void OnDownloadEvent(Guid mediaId, HRESULT hr) + { + if (this.m_disposed) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredDownloadEvent), (object)new object[2] + { + (object) mediaId, + (object) hr + }); + } + + private void OnAllPending(object sender, EventArgs e) + { + if (this.m_disposed) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DefferedAllPending), (object)null); + } + + private void DeferredDownloadEvent(object arg) + { + object[] objArray = (object[])arg; + Guid mediaId = (Guid)objArray[0]; + HRESULT hr = (HRESULT)objArray[1]; + if (hr.IsSuccess || hr == HRESULT._E_ABORT || (hr == HRESULT._E_PENDING || hr == HRESULT._E_ALREADY_EXISTS)) + this.ClearErrorCode(mediaId); + else + this.SetErrorCode(mediaId, hr.hr); + if (this.DownloadEvent == null) + return; + this.DownloadEvent(mediaId, hr); + this.FirePropertyChanged("DownloadEvent"); + } + + private void DefferedAllPending(object notUsed) + { + if (this.DownloadAllPendingEvent == null) + return; + this.DownloadAllPendingEvent((object)this, (EventArgs)null); + } + + private void OnDownloadProgressEvent(Guid mediaId, float percent) + { + if (this.m_disposed) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredDownloadProgressEvent), (object)new object[2] + { + (object) mediaId, + (object) percent + }); + } + + private void DeferredDownloadProgressEvent(object arg) + { + if (this.DownloadProgressEvent == null) + return; + object[] objArray = (object[])arg; + this.DownloadProgressEvent((Guid)objArray[0], (float)objArray[1]); + this.FirePropertyChanged("DownloadProgressEvent"); + } + + public ProgressNotification Notification + { + get => this.m_notification; + private set + { + if (this.m_notification == value) + return; + if (this.m_notification != null) + NotificationArea.Instance.Remove((ZuneUI.Notification)this.m_notification); + this.m_notification = value; + if (this.m_notification != null) + NotificationArea.Instance.Add((ZuneUI.Notification)this.m_notification); + this.FirePropertyChanged(nameof(Notification)); + } + } + + public DownloadTaskList DownloadTaskList => DownloadTaskList.Instance; + + private void OnTransportControlPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "SupressDownloads")) + return; + if (SingletonModelItem.Instance.SupressDownloads) + DownloadManager.Instance.PauseQueue(); + else + DownloadManager.Instance.ResumeQueue(); + } + + private void ShowCompletedMessage(bool cancellations, bool failures) + { + if (this.Notification == null || this.Notification.Type == NotificationState.Completed) + return; + this.Notification.Type = NotificationState.Completed; + if (failures) + { + this.Notification.Message = Download.s_downloadFailedMessage; + } + else + { + this.Notification.Message = Download.s_downloadCompleteMessage; + this.Notification.Percentage = 100; + } + this.Notification.SubMessage = (string)null; + Application.DeferredInvoke(new DeferredInvokeHandler(this.HideCompletedMessage), (object)null, TimeSpan.FromSeconds(5.0)); + } + + private void HideCompletedMessage(object args) + { + if (this.Notification == null || this.Notification.Type != NotificationState.Completed) + return; + this.Notification = (ProgressNotification)null; + } + + private void OnProgressChanged(DownloadManagerUpdateArguments args) + { + if (this.m_updatePending) + return; + this.m_updatePending = true; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.m_updatePending = false; + int totalItems = DownloadManager.Instance.TotalItems; + int activeItem = DownloadManager.Instance.ActiveItem; + if (totalItems == 0) + { + this.Notification = (ProgressNotification)null; + } + else + { + if (this.Notification == null) + { + this.Notification = new ProgressNotification(Download.s_downloadProgressMessage, NotificationTask.Download, NotificationState.Normal, 0); + } + else + { + this.Notification.Type = NotificationState.Normal; + this.Notification.Message = Download.s_downloadProgressMessage; + } + if (DownloadManager.Instance.Finished) + { + this.ShowCompletedMessage(DownloadManager.Instance.HadCancellations, DownloadManager.Instance.HadFailures); + } + else + { + this.Notification.Percentage = (int)DownloadManager.Instance.Percentage; + this.Notification.SubMessage = string.Format(Download.s_downloadCurrentMessage, (object)activeItem, (object)totalItems); + if (DownloadManager.Instance.IsQueuePaused) + { + if (SingletonModelItem.Instance.IsStreamingVideo) + this.Notification.Message = Download.s_downloadMBRPausedMessage; + else + this.Notification.Message = Download.s_downloadPausedMessage; + } + else if (!SignIn.Instance.SignedIn && DownloadManager.Instance.SignInRequired()) + this.Notification.Message = Download.s_downloadSignInMessage; + } + } + bool show = !DownloadManager.Instance.Finished || DownloadManager.Instance.FailedDownloads.Count > 0 || DownloadManager.Instance.HadFailures; + ZuneUI.Shell.MainFrame.Marketplace.UpdateDownloadPivot(show); + ZuneUI.Shell.MainFrame.Collection.UpdateDownloadPivot(show); + if (show || !(ZuneShell.DefaultInstance.CurrentPage is DownloadsPage)) + return; + ZuneShell.DefaultInstance.NavigateBack(); + }, (object)null); + } + + private Download() + { + } + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + if (fDisposing) + { + DownloadManager.Instance.OnProgressChanged -= new DownloadManagerUpdateHandler(this.OnProgressChanged); + SingletonModelItem.Instance.PropertyChanged -= new PropertyChangedEventHandler(this.OnTransportControlPropertyChanged); + } + this.m_disposed = true; + } + + public Microsoft.Zune.Service.EDownloadContextEvent ClientContextEvent => !this.ShouldTrackUsage() ? Microsoft.Zune.Service.EDownloadContextEvent.Unknown : this.m_clientContextEvent; + + public string ClientContextEventValue => !this.ShouldTrackUsage() ? (string)null : this.m_clientContextEventValue; + + private bool ShouldTrackUsage() => ClientConfiguration.SQM.UsageTracking && ClientConfiguration.FUE.AcceptedPrivacyStatement; + + public void ReportClientContextEvent( + Microsoft.Zune.Service.EDownloadContextEvent clientContextEvent, + Guid clientContextEventValue) + { + Microsoft.Zune.Service.EDownloadContextEvent edownloadContextEvent = Microsoft.Zune.Service.EDownloadContextEvent.Unknown; + string str = (string)null; + if (clientContextEventValue != Guid.Empty) + { + edownloadContextEvent = clientContextEvent; + str = clientContextEventValue.ToString(); + } + bool flag1 = this.m_clientContextEvent != edownloadContextEvent; + bool flag2 = this.m_clientContextEventValue != str; + if (flag1) + { + this.m_clientContextEvent = edownloadContextEvent; + this.FirePropertyChanged("ClientContextEvent"); + } + if (!flag1 && !flag2) + return; + this.m_clientContextEventValue = str; + this.FirePropertyChanged("ClientContextEventValue"); + } + } +} diff --git a/ZuneUI/DownloadCommand.cs b/ZuneUI/DownloadCommand.cs new file mode 100644 index 0000000..69a2640 --- /dev/null +++ b/ZuneUI/DownloadCommand.cs @@ -0,0 +1,140 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DownloadCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public abstract class DownloadCommand : ProgressCommand + { + private DownloadProgressHandler m_progressHandler; + private EDownloadTaskState m_downloadState = EDownloadTaskState.DLTaskNone; + private DownloadTask m_downloadTask; + private string m_taskId; + private int m_progress; + private volatile object m_myLock; + + public string TaskId + { + set + { + this.m_taskId = value; + this.Refresh(); + } + } + + public DownloadCommand(IModelItem owner) + : base(owner) + { + this.Progress = -1f; + this.m_progressHandler = new DownloadProgressHandler(this.OnProgressChanged); + this.m_myLock = new object(); + } + + public void Refresh() + { + lock (this.m_myLock) + { + this.m_downloadState = this.GetDownloadState(); + if (this.m_downloadState == EDownloadTaskState.DLTaskDownloading) + this.UpdateDownloadTask(); + } + this.UpdateCommandState((object)null); + } + + protected abstract EDownloadTaskState GetDownloadState(); + + protected virtual string GetDownloadString(EDownloadTaskState downloadState) + { + string str; + switch (downloadState) + { + case EDownloadTaskState.DLTaskPendingAttach: + case EDownloadTaskState.DLTaskPending: + str = Shell.LoadString(StringId.IDS_PENDING); + break; + case EDownloadTaskState.DLTaskDownloading: + case EDownloadTaskState.DLTaskPaused: + str = string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_PROGRESS), (object)this.m_progress.ToString()); + break; + case EDownloadTaskState.DLTaskComplete: + str = Shell.LoadString(StringId.IDS_INCOLLECTION); + break; + default: + str = Shell.LoadString(StringId.IDS_DOWNLOAD); + break; + } + return str; + } + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing) + return; + lock (this.m_myLock) + { + if (this.m_downloadTask == null) + return; + this.m_downloadTask.OnProgressChanged -= this.m_progressHandler; + this.m_downloadTask = (DownloadTask)null; + } + } + + protected virtual void OnProgressChanged(DownloadEventArguments args) + { + lock (this.m_myLock) + { + this.m_downloadState = args.State; + this.m_progress = (int)args.Progress; + if (this.m_downloadState != EDownloadTaskState.DLTaskDownloading) + { + if (this.m_downloadState != EDownloadTaskState.DLTaskPaused) + { + if (this.m_downloadState != EDownloadTaskState.DLTaskPending) + { + if (this.m_downloadState != EDownloadTaskState.DLTaskPendingAttach) + { + this.m_downloadTask = (DownloadTask)null; + this.m_downloadState = this.GetDownloadState(); + } + } + } + } + } + Application.DeferredInvoke(new DeferredInvokeHandler(this.UpdateCommandState), DeferredInvokePriority.Normal); + } + + private void UpdateCommandState(object args) + { + this.Description = this.GetDownloadString(this.m_downloadState); + this.Available = this.m_downloadState != EDownloadTaskState.DLTaskComplete; + if (this.m_downloadState == EDownloadTaskState.DLTaskDownloading || this.m_downloadState == EDownloadTaskState.DLTaskPaused) + this.Progress = (float)this.m_progress / 100f; + else + this.Progress = -1f; + } + + private void UpdateDownloadTask() + { + if (this.m_downloadTask == null) + { + if (this.m_taskId == null) + return; + this.m_downloadTask = DownloadManager.Instance.GetTask(this.m_taskId); + if (this.m_downloadTask == null) + return; + if (this.m_downloadState == EDownloadTaskState.DLTaskPendingAttach || this.m_downloadState == EDownloadTaskState.DLTaskPending || (this.m_downloadState == EDownloadTaskState.DLTaskDownloading || this.m_downloadState == EDownloadTaskState.DLTaskPaused)) + this.m_downloadTask.OnProgressChanged += this.m_progressHandler; + this.m_progress = (int)this.m_downloadTask.GetProgress(); + this.m_downloadState = this.m_downloadTask.GetState(); + } + else + this.m_downloadState = this.m_downloadTask.GetState(); + } + } +} diff --git a/ZuneUI/DownloadManagerHelper.cs b/ZuneUI/DownloadManagerHelper.cs new file mode 100644 index 0000000..bcab695 --- /dev/null +++ b/ZuneUI/DownloadManagerHelper.cs @@ -0,0 +1,68 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DownloadManagerHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public static class DownloadManagerHelper + { + public static void RetryDownloading(IList items) + { + if (items == null || items.Count == 0) + return; + ArrayList arrayList1 = new ArrayList(items.Count); + ArrayList arrayList2 = new ArrayList(items.Count); + Microsoft.Zune.Service.EDownloadFlags eDownloadFlags = Microsoft.Zune.Service.EDownloadFlags.None; + string str = (string)null; + for (int index = 0; index < items.Count; ++index) + { + if (items[index] is DownloadTask task) + { + switch (task.GetState()) + { + case EDownloadTaskState.DLTaskCancelled: + case EDownloadTaskState.DLTaskFailed: + switch (Microsoft.Zune.Service.Service.Instance.GetContentType(task.GetProperty("Type"))) + { + case Microsoft.Zune.Service.EContentType.MusicTrack: + case Microsoft.Zune.Service.EContentType.Video: + case Microsoft.Zune.Service.EContentType.App: + Microsoft.Zune.Service.EDownloadFlags propertyInt = (Microsoft.Zune.Service.EDownloadFlags)task.GetPropertyInt("DownloadFlags"); + string property = task.GetProperty("DeviceEndpointId"); + bool flag1 = index == 0; + bool flag2 = eDownloadFlags == propertyInt; + bool flag3 = string.Equals(str, property, StringComparison.InvariantCultureIgnoreCase); + if (flag1 || flag2 && flag3) + { + eDownloadFlags = propertyInt; + str = property; + arrayList2.Add((object)task); + DownloadManager.Instance.RemoveFailed(task); + continue; + } + arrayList1.Add((object)task); + continue; + case Microsoft.Zune.Service.EContentType.PodcastEpisode: + EpisodeDownloadCommand.DownloadEpisode(task.GetPropertyInt("SubscriptionId"), task.GetPropertyInt("MediaId")); + DownloadManager.Instance.RemoveFailed(task); + continue; + default: + continue; + } + default: + continue; + } + } + } + if (arrayList2.Count > 0) + Download.Instance.DownloadContent((IList)arrayList2, eDownloadFlags, str); + DownloadManagerHelper.RetryDownloading((IList)arrayList1); + } + } +} diff --git a/ZuneUI/DownloadProgress.cs b/ZuneUI/DownloadProgress.cs new file mode 100644 index 0000000..df2c3c9 --- /dev/null +++ b/ZuneUI/DownloadProgress.cs @@ -0,0 +1,185 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DownloadProgress +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public class DownloadProgress : ProgressCommand + { + private EDownloadTaskState m_downloadState = EDownloadTaskState.DLTaskNone; + private DownloadTask m_downloadTask; + + public DownloadProgress(DownloadTask downloadTask) + : base(downloadTask) + { + this.m_downloadTask = downloadTask; + this.m_downloadState = this.m_downloadTask.GetState(); + this.m_downloadTask.OnProgressChanged += new DownloadProgressHandler(this.OnProgressChanged); + this.Available = false; + this.UpdateState((object)null); + } + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing || this.m_downloadTask == null) + return; + this.m_downloadTask.OnProgressChanged -= new DownloadProgressHandler(this.OnProgressChanged); + this.m_downloadTask = (DownloadTask)null; + } + + protected Microsoft.Zune.Service.EContentType ContentType + { + get + { + Microsoft.Zune.Service.EContentType econtentType = Microsoft.Zune.Service.EContentType.Unknown; + string property = this.m_downloadTask.GetProperty("Type"); + if (property == "type:musictrack") + econtentType = Microsoft.Zune.Service.EContentType.MusicTrack; + else if (property == "type:musicvideo") + econtentType = Microsoft.Zune.Service.EContentType.Video; + else if (property == "type:podcast") + econtentType = Microsoft.Zune.Service.EContentType.PodcastEpisode; + else if (property == "type:app") + econtentType = Microsoft.Zune.Service.EContentType.App; + return econtentType; + } + } + + protected Guid ServiceId + { + get + { + Guid guid = Guid.Empty; + string property = this.m_downloadTask.GetProperty(nameof(ServiceId)); + if (!string.IsNullOrEmpty(property)) + guid = new Guid(property); + return guid; + } + } + + protected int PodcastEpisodeId => this.m_downloadTask.GetPropertyInt("MediaId"); + + protected int CollectionId + { + get + { + int dbMediaId; + if (!Microsoft.Zune.Service.Service.Instance.InCompleteCollection(this.ServiceId, this.ContentType, out dbMediaId, out bool _)) + dbMediaId = -1; + return dbMediaId; + } + } + + protected Microsoft.Zune.Service.EDownloadFlags DownloadFlags => (Microsoft.Zune.Service.EDownloadFlags)this.m_downloadTask.GetPropertyInt(nameof(DownloadFlags)); + + protected int SubscriptionMediaId => this.m_downloadTask.GetPropertyInt(nameof(SubscriptionMediaId)); + + protected int SubscriptionItemMediaId => this.m_downloadTask.GetPropertyInt(nameof(SubscriptionItemMediaId)); + + protected int PlaylistId => this.m_downloadTask.GetPropertyInt(nameof(PlaylistId)); + + public void FindInCollection() + { + Microsoft.Zune.Service.EContentType contentType = this.ContentType; + if (contentType == Microsoft.Zune.Service.EContentType.PodcastEpisode) + PodcastLibraryPage.FindInCollection(-1, this.PodcastEpisodeId); + else if ((this.DownloadFlags & Microsoft.Zune.Service.EDownloadFlags.Channel) != Microsoft.Zune.Service.EDownloadFlags.None) + { + if (this.PlaylistId > 0) + MusicLibraryPage.FindPlaylistInCollection(this.PlaylistId, this.CollectionId, true); + else + ChannelLibraryPage.FindInCollection(this.SubscriptionMediaId, this.SubscriptionItemMediaId); + } + else + { + if (this.CollectionId < 0) + return; + switch (contentType) + { + case Microsoft.Zune.Service.EContentType.MusicTrack: + MusicLibraryPage.FindInCollection(-1, -1, this.CollectionId); + break; + case Microsoft.Zune.Service.EContentType.Video: + VideoLibraryPage.FindInCollection(this.CollectionId); + break; + case Microsoft.Zune.Service.EContentType.App: + ApplicationLibraryPage.FindInCollection(this.CollectionId); + break; + } + } + } + + private void OnProgressChanged(DownloadEventArguments args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.UpdateState), (object)args, DeferredInvokePriority.Normal); + + private void UpdateState(object args) + { + this.Progress = -1f; + float progress; + if (args != null) + { + DownloadEventArguments downloadEventArguments = (DownloadEventArguments)args; + this.m_downloadState = downloadEventArguments.State; + progress = downloadEventArguments.Progress; + } + else + { + this.m_downloadState = this.m_downloadTask.GetState(); + progress = this.m_downloadTask.GetProgress(); + } + switch (this.m_downloadState) + { + case EDownloadTaskState.DLTaskPendingAttach: + case EDownloadTaskState.DLTaskPending: + this.Description = Shell.LoadString(StringId.IDS_PENDING); + this.Available = false; + break; + case EDownloadTaskState.DLTaskDownloading: + this.UpdateProgress(Guid.Empty, progress); + if (this.SecondsToProgressivePlayback == 0) + this.Description = Shell.LoadString(StringId.IDS_PLAY_SONG); + else + this.Description = string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_PROGRESS), (object)(int)progress); + this.Available = true; + break; + case EDownloadTaskState.DLTaskPaused: + this.Description = string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_PROGRESS), (object)(int)progress); + this.Progress = progress / 100f; + this.Available = false; + break; + case EDownloadTaskState.DLTaskCancelled: + this.Description = Shell.LoadString(StringId.IDS_CANCELLED); + this.Available = false; + break; + case EDownloadTaskState.DLTaskFailed: + this.Description = Shell.LoadString(StringId.IDS_FAILED); + this.Available = false; + break; + case EDownloadTaskState.DLTaskComplete: + this.Description = Shell.LoadString(StringId.IDS_INCOLLECTION); + this.Available = true; + break; + default: + this.Description = Shell.LoadString(StringId.IDS_PENDING); + this.Available = false; + break; + } + } + + protected override void OnInvoked() + { + if (!this.Available) + return; + if (this.SecondsToProgressivePlayback == 0) + this.InvokeProgressivePlayback(); + else + this.FindInCollection(); + } + } +} diff --git a/ZuneUI/DownloadsNavigationCommandHandler.cs b/ZuneUI/DownloadsNavigationCommandHandler.cs new file mode 100644 index 0000000..8737027 --- /dev/null +++ b/ZuneUI/DownloadsNavigationCommandHandler.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DownloadsNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class DownloadsNavigationCommandHandler : NavigationCommandHandlerBase + { + public bool _collection; + + public bool Collection + { + get => this._collection; + set => this._collection = value; + } + + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new DownloadsPage(this._collection); + } +} diff --git a/ZuneUI/DownloadsPage.cs b/ZuneUI/DownloadsPage.cs new file mode 100644 index 0000000..5ecb273 --- /dev/null +++ b/ZuneUI/DownloadsPage.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DownloadsPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class DownloadsPage : ZunePage + { + public DownloadsPage(bool collection) + { + this.UI = "res://ZuneMarketplaceResources!DownloadsData.uix#MarketplaceDownloads"; + if (collection || !FeatureEnablement.IsFeatureEnabled(Features.eMarketplace)) + { + this.PivotPreference = Shell.MainFrame.Collection.Downloads; + this.UIPath = "Collection\\Downloads"; + } + else + { + this.PivotPreference = Shell.MainFrame.Marketplace.Downloads; + this.UIPath = "Marketplace\\Downloads\\Home"; + } + this.IsRootPage = true; + } + + public override IPageState SaveAndRelease() => (IPageState)new DownloadsPageState((IPage)this); + } +} diff --git a/ZuneUI/DownloadsPageState.cs b/ZuneUI/DownloadsPageState.cs new file mode 100644 index 0000000..c875d96 --- /dev/null +++ b/ZuneUI/DownloadsPageState.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DownloadsPageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class DownloadsPageState : IPageState + { + private DownloadsPage _page; + + public DownloadsPageState(IPage page) => this._page = (DownloadsPage)page; + + public IPage RestoreAndRelease() + { + if ((double)DownloadManager.Instance.Percentage >= 100.0) + this.Release(); + return (IPage)this._page; + } + + public void Release() + { + this._page.Release(); + this._page = (DownloadsPage)null; + } + + public bool CanBeTrimmed => true; + } +} diff --git a/ZuneUI/DrmHelper.cs b/ZuneUI/DrmHelper.cs new file mode 100644 index 0000000..fc3518d --- /dev/null +++ b/ZuneUI/DrmHelper.cs @@ -0,0 +1,72 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DrmHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; + +namespace ZuneUI +{ + public static class DrmHelper + { + public static bool IsRental(int state, bool fIncludeExpired) + { + DrmState drmState = (DrmState)state; + switch (drmState) + { + case DrmState.DeviceLicense: + case DrmState.Expiring: + return true; + default: + return fIncludeExpired && drmState == DrmState.Expired; + } + } + + public static bool IsRentalExpired(int state, string filename) + { + bool flag = false; + switch ((DrmState)state) + { + case DrmState.Expired: + flag = true; + break; + case DrmState.Expiring: + DRMInfo fileDrmInfo = ZuneApplication.Service.GetFileDRMInfo(filename); + if (fileDrmInfo != null && (fileDrmInfo.NoLicense || fileDrmInfo.LicenseExpired)) + { + flag = true; + break; + } + break; + } + return flag; + } + + public static bool IsRentalExpired(int state, Guid mediaId) + { + bool flag = false; + switch ((DrmState)state) + { + case DrmState.Expired: + flag = true; + break; + case DrmState.Expiring: + DRMInfo mediaDrmInfo = ZuneApplication.Service.GetMediaDRMInfo(mediaId, EContentType.Video); + if (mediaDrmInfo != null && (mediaDrmInfo.NoLicense || mediaDrmInfo.LicenseExpired)) + { + flag = true; + break; + } + break; + } + return flag; + } + + public static void ShowDeviceRentalError() => ZuneUI.Shell.ShowErrorDialog(HRESULT._NS_E_DRM_DEVICE_RENTAL_LICENSE.Int, StringId.IDS_PLAYBACK_ERROR); + + public static void ShowRentalExpiredError() => ZuneUI.Shell.ShowErrorDialog(HRESULT._NS_E_DRM_RENTAL_LICENSE_EXPIRED.Int, StringId.IDS_PLAYBACK_ERROR); + } +} diff --git a/ZuneUI/DrmState.cs b/ZuneUI/DrmState.cs new file mode 100644 index 0000000..2f89203 --- /dev/null +++ b/ZuneUI/DrmState.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DrmState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum DrmState + { + Unknown = 0, + NoLicense = 10, // 0x0000000A + Expired = 20, // 0x00000014 + DeviceLicense = 23, // 0x00000017 + Expiring = 26, // 0x0000001A + Protected = 30, // 0x0000001E + Free = 40, // 0x00000028 + } +} diff --git a/ZuneUI/DrmStateDescriptions.cs b/ZuneUI/DrmStateDescriptions.cs new file mode 100644 index 0000000..1bb8ed7 --- /dev/null +++ b/ZuneUI/DrmStateDescriptions.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DrmStateDescriptions +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public static class DrmStateDescriptions + { + private static string _noLicenseDescription = Shell.LoadString(StringId.IDS_DRM_HEADER_NO_LICENSE); + private static string _personalDescription = Shell.LoadString(StringId.IDS_DRM_HEADER_PERSONAL); + private static string _purchasedDescription = Shell.LoadString(StringId.IDS_DRM_HEADER_PURCHASED); + private static string _rentalDescription = Shell.LoadString(StringId.IDS_DRM_HEADER_RENTAL); + private static string _subscriptionDescription = Shell.LoadString(StringId.IDS_DRM_HEADER_SUBSCRIPTION); + private static string _subscriptionExpiredDescription = Shell.LoadString(StringId.IDS_DRM_HEADER_SUBSCRIPTION_EXPIRED); + private static string _protectedDescription = Shell.LoadString(StringId.IDS_DRM_HEADER_PROTECTED); + private static string _unknownDescription = Shell.LoadString(StringId.IDS_DRM_HEADER_UNKNOWN); + + public static string GetAudioDescription(int stateId) => DrmStateDescriptions.GetDescription(MediaType.Track, (DrmState)stateId); + + public static string GetVideoDescription(int stateId) => DrmStateDescriptions.GetDescription(MediaType.Video, (DrmState)stateId); + + public static string GetDescription(MediaType mediaType, DrmState state) + { + switch (state) + { + case DrmState.Unknown: + return DrmStateDescriptions._unknownDescription; + case DrmState.NoLicense: + return DrmStateDescriptions._noLicenseDescription; + case DrmState.Expired: + return MediaType.Track == mediaType ? DrmStateDescriptions._subscriptionExpiredDescription : DrmStateDescriptions._rentalDescription; + case DrmState.DeviceLicense: + return DrmStateDescriptions._rentalDescription; + case DrmState.Expiring: + return MediaType.Track == mediaType ? DrmStateDescriptions._subscriptionDescription : DrmStateDescriptions._rentalDescription; + case DrmState.Protected: + return MediaType.Track == mediaType ? DrmStateDescriptions._protectedDescription : DrmStateDescriptions._purchasedDescription; + case DrmState.Free: + return DrmStateDescriptions._personalDescription; + default: + return DrmStateDescriptions._unknownDescription; + } + } + } +} diff --git a/ZuneUI/DrmStateMask.cs b/ZuneUI/DrmStateMask.cs new file mode 100644 index 0000000..89168d5 --- /dev/null +++ b/ZuneUI/DrmStateMask.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.DrmStateMask +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public static class DrmStateMask + { + private static readonly long _drmStateMaskAll = 1100653528065; + private static readonly long _drmStateMaskProtected = 1073742848; + private static readonly long _drmStateMaskZunePass = 68157440; + private static readonly long _drmStateMaskPersonal = 1099511627776; + private static readonly long _drmStateMaskUnknown = 1; + + public static bool Match(long drmStateMask1, long drmStateMask2) + { + if (drmStateMask1 == 0L) + drmStateMask1 = DrmStateMask._drmStateMaskUnknown; + if (drmStateMask2 == 0L) + drmStateMask2 = DrmStateMask._drmStateMaskUnknown; + return (drmStateMask1 & drmStateMask2) != 0L; + } + + public static bool IsMixed(long drmStateMask) + { + int num = 0; + if ((drmStateMask & DrmStateMask._drmStateMaskPersonal) != 0L) + ++num; + if ((drmStateMask & DrmStateMask._drmStateMaskProtected) != 0L) + ++num; + if ((drmStateMask & DrmStateMask._drmStateMaskZunePass) != 0L) + ++num; + return num > 1; + } + + public static long Combine(long drmStateMask1, long drmStateMask2) => drmStateMask1 | drmStateMask2; + + public static long Diff(long drmStateMask1, long drmStateMask2) => drmStateMask1 ^ drmStateMask1 & drmStateMask2; + + public static long All() => DrmStateMask._drmStateMaskAll; + + public static long Unknown() => DrmStateMask._drmStateMaskUnknown; + + public static long Personal() => DrmStateMask._drmStateMaskPersonal; + + public static long Protected() => DrmStateMask._drmStateMaskProtected; + + public static long ZunePass() => DrmStateMask._drmStateMaskZunePass; + } +} diff --git a/ZuneUI/EDeviceProcessingStep.cs b/ZuneUI/EDeviceProcessingStep.cs new file mode 100644 index 0000000..1f4bacb --- /dev/null +++ b/ZuneUI/EDeviceProcessingStep.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EDeviceProcessingStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum EDeviceProcessingStep + { + ClientUpdate, + FirmwareUpdate, + SyncSetup, + } +} diff --git a/ZuneUI/EditContactInfoStep.cs b/ZuneUI/EditContactInfoStep.cs new file mode 100644 index 0000000..ca8246d --- /dev/null +++ b/ZuneUI/EditContactInfoStep.cs @@ -0,0 +1,194 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EditContactInfoStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class EditContactInfoStep : RegionInfoStep + { + private AccountUser _accountUser; + private bool _lightWeightOnly; + private Dictionary _errorMappings; + + public EditContactInfoStep(Wizard owner, AccountManagementWizardState state) + : base(owner, state, false) + { + this.LoadStates = true; + this.LoadLanguages = true; + this._lightWeightOnly = false; + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_CONTACT_HEAD); + this.DetailDescription = Shell.LoadString(StringId.IDS_ACCOUNT_EDIT_CONTACT_INFO_DETAIL); + WizardPropertyEditor wizardPropertyEditor = (WizardPropertyEditor)new ContactInfoPropertyEditor(); + this.RequireSignIn = true; + this.Initialize(wizardPropertyEditor); + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#ContactInfoStep"; + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled; + if (flag) + flag = this.LightWeightOnly && SignIn.Instance.IsLightWeight || !this.LightWeightOnly; + return flag; + } + } + + public bool LightWeightOnly + { + get => this._lightWeightOnly; + set + { + if (this._lightWeightOnly == value) + return; + this._lightWeightOnly = value; + this.FirePropertyChanged(nameof(LightWeightOnly)); + this.FirePropertyChanged("Enabled"); + } + } + + internal override Dictionary ErrorPropertyMappings + { + get + { + if (this._errorMappings == null) + { + this._errorMappings = new Dictionary(2); + this._errorMappings.Add(HRESULT._ZEST_E_INVALID_POSTALCODE.Int, ContactInfoPropertyEditor.PostalCode); + this._errorMappings.Add(HRESULT._ZEST_E_LIVEACCOUNT_INVALIDPHONE.Int, BaseContactInfoPropertyEditor.PhoneNumber); + this._errorMappings.Add(HRESULT._ZUNE_E_UPDATE_ACCOUNT_INFO_FAILED.Int, (PropertyDescriptor)null); + this._errorMappings.Add(HRESULT._ZEST_E_LIVEACCOUNT_ADDRESS_INVALID.Int, (PropertyDescriptor)null); + this._errorMappings.Add(HRESULT._ZEST_E_INVALID_ARG_CONTACT_INFO.Int, (PropertyDescriptor)null); + } + return this._errorMappings; + } + } + + protected override PropertyDescriptor CountryDescriptor => ContactInfoPropertyEditor.Country; + + protected override PropertyDescriptor LanguageDescriptor => ContactInfoPropertyEditor.Language; + + protected override PropertyDescriptor StateDescriptor => ContactInfoPropertyEditor.State; + + public AccountUser AccountUser + { + get => this._accountUser; + private set + { + if (this._accountUser == value) + return; + this._accountUser = value; + this.SetCommittedValue(ContactInfoPropertyEditor.City, (object)this.AccountUser.Address.City); + this.SetCommittedValue(ContactInfoPropertyEditor.District, (object)this.AccountUser.Address.District); + this.SetCommittedValue(ContactInfoPropertyEditor.PostalCode, (object)this.AccountUser.Address.PostalCode); + this.SetCommittedValue(ContactInfoPropertyEditor.Street1, (object)this.AccountUser.Address.Street1); + this.SetCommittedValue(ContactInfoPropertyEditor.Street2, (object)this.AccountUser.Address.Street2); + this.SetCommittedValue(BaseContactInfoPropertyEditor.FirstName, (object)this.AccountUser.FirstName); + this.SetCommittedValue(BaseContactInfoPropertyEditor.LastName, (object)this.AccountUser.LastName); + this.SetCommittedValue(BaseContactInfoPropertyEditor.Email, (object)this.AccountUser.Email); + this.SetCommittedValue(BaseContactInfoPropertyEditor.PhoneNumber, (object)this.AccountUser.PhoneNumber); + this.SelectedLocale = this.AccountUser.Locale; + this.SelectedState = this.AccountUser.Address.State; + this.FirePropertyChanged(nameof(AccountUser)); + } + } + + protected override void OnCountryChanged() + { + if (this.WizardPropertyEditor == null) + return; + this.WizardPropertyEditor.SetPropertyState(BaseContactInfoPropertyEditor.FirstName, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(BaseContactInfoPropertyEditor.LastName, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(ContactInfoPropertyEditor.Street1, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(ContactInfoPropertyEditor.Street2, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(ContactInfoPropertyEditor.City, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(ContactInfoPropertyEditor.District, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(ContactInfoPropertyEditor.State, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(ContactInfoPropertyEditor.PostalCode, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(BaseContactInfoPropertyEditor.PhoneNumber, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(BaseContactInfoPropertyEditor.PhoneExtension, (object)this.SelectedCountry); + } + + protected override bool OnCommitChanges() + { + bool flag = true; + if (this.AccountUser != null) + { + ServiceError serviceError = (ServiceError)null; + this.AccountUser.Address.City = this.GetCommittedValue(ContactInfoPropertyEditor.City) as string; + this.AccountUser.Address.District = this.GetCommittedValue(ContactInfoPropertyEditor.District) as string; + this.AccountUser.Address.PostalCode = this.GetCommittedValue(ContactInfoPropertyEditor.PostalCode) as string; + this.AccountUser.Address.Street1 = this.GetCommittedValue(ContactInfoPropertyEditor.Street1) as string; + this.AccountUser.Address.Street2 = this.GetCommittedValue(ContactInfoPropertyEditor.Street2) as string; + this.AccountUser.FirstName = this.GetCommittedValue(BaseContactInfoPropertyEditor.FirstName) as string; + this.AccountUser.LastName = this.GetCommittedValue(BaseContactInfoPropertyEditor.LastName) as string; + this.AccountUser.Email = this.GetCommittedValue(BaseContactInfoPropertyEditor.Email) as string; + this.AccountUser.PhoneNumber = this.GetCommittedValue(BaseContactInfoPropertyEditor.PhoneNumber) as string; + this.AccountUser.Address.State = this.SelectedState; + this.AccountUser.AccountSettings = (AccountSettings)null; + this.AccountUser.ParentPassportIdentity = this.State.PassportPasswordParentStep.PassportIdentity; + HRESULT hr = this.State.AccountManagement.SetAccount((PassportIdentity)null, this.AccountUser, out serviceError); + if (hr.IsSuccess) + { + SignIn.Instance.RefreshAccount(); + } + else + { + flag = false; + this.SetError(hr, serviceError); + } + } + return flag; + } + + protected override void OnActivate() + { + this.ServiceActivationRequestsDone = this.AccountUser != null; + base.OnActivate(); + } + + protected override void OnStartActivationRequests(object state) + { + AccountUser accountUser = this.ObtainAccountUser(); + RegionInfoStep.RegionServiceData regionServiceData = (RegionInfoStep.RegionServiceData)state; + if (accountUser != null && accountUser.Locale != null && regionServiceData.SelectedCountry == null) + { + string[] strArray = accountUser.Locale.Split('-'); + if (strArray.Length >= 2) + regionServiceData.SelectedCountry = strArray[1]; + } + base.OnStartActivationRequests(state); + this.EndActivationRequests((object)accountUser); + } + + protected override void OnEndActivationRequests(object args) + { + if (args == null) + this.NavigateToErrorHandler(); + else if (args is AccountUser) + this.AccountUser = (AccountUser)args; + else + base.OnEndActivationRequests(args); + } + + private AccountUser ObtainAccountUser() + { + AccountUser accountUser = (AccountUser)null; + ServiceError serviceError = (ServiceError)null; + HRESULT account = this.State.AccountManagement.GetAccount((PassportIdentity)null, out accountUser, out serviceError); + if (account.IsError) + { + accountUser = (AccountUser)null; + this.SetError(account, serviceError); + } + return accountUser; + } + } +} diff --git a/ZuneUI/EditPrivacyInfoStep.cs b/ZuneUI/EditPrivacyInfoStep.cs new file mode 100644 index 0000000..9075183 --- /dev/null +++ b/ZuneUI/EditPrivacyInfoStep.cs @@ -0,0 +1,98 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EditPrivacyInfoStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class EditPrivacyInfoStep : PrivacyInfoStep + { + public EditPrivacyInfoStep( + Wizard owner, + AccountManagementWizardState state, + bool parentAccount, + PrivacyInfoSettings showSettings) + : base(owner, state, parentAccount, showSettings) + { + } + + public override bool IsEnabled => this._owner.CurrentPage != this || !this.ServiceRequestWorking; + + public override bool ShowPrivacyStatement => true; + + protected override bool OnCommitChanges() + { + bool flag = true; + if (this.CommittedSettings != null) + { + HRESULT hr = HRESULT._S_OK; + ServiceError serviceError = (ServiceError)null; + if (this.PrivacySettings != null && this.PrivacySettings.Count > 0) + hr = this.State.AccountManagement.SetPrivacySettings(this.CommittedSettings, this.State.PassportPasswordParentStep.PassportIdentity, out serviceError); + if (hr.IsSuccess && this.FamilySettings != null && (this.FamilySettings.Settings != null && this.FamilySettings.Settings.Count > 0)) + this.FamilySettings.CommitSettings(); + if (SignIn.Instance.FamilySettings != null) + SignIn.Instance.FamilySettings.ReloadSettings(); + if (hr.IsSuccess && (this.AllowMicrosoftCommunications != null || this.AllowPartnerCommunications != null)) + hr = this.State.AccountManagement.SetNewsLetterSettings(this.CommittedSettings, out serviceError); + if (!hr.IsSuccess) + { + flag = false; + this.SetError(hr, serviceError); + } + } + return flag; + } + + protected override void OnActivate() + { + this.ServiceActivationRequestsDone = this.CommittedSettings != null; + base.OnActivate(); + } + + protected override void OnStartActivationRequests(object state) + { + this.InitializeHelpersOnWorkerThread(); + this.EndActivationRequests((object)this.ObtainAccountUser()); + } + + protected override void OnEndActivationRequests(object args) + { + if (args == null) + { + this.NavigateToErrorHandler(); + } + else + { + this.InitializeSettings(); + AccountUser accountUser = (AccountUser)args; + this.CommittedSettings = accountUser.AccountSettings; + if (this.ShowSettings != PrivacyInfoSettings.None) + return; + if (accountUser.AccountUserType == AccountUserType.Adult) + this.ShowSettings = PrivacyInfoSettings.SocialSettings; + else if (accountUser.AccountUserType == AccountUserType.ChildWithSocial) + this.ShowSettings = FeatureEnablement.IsFeatureEnabled(Features.eSocial) ? PrivacyInfoSettings.CreateChildAccountWithSocial : PrivacyInfoSettings.CreateChildAccount; + else + this.ShowSettings = PrivacyInfoSettings.CreateChildAccount; + } + } + + private AccountUser ObtainAccountUser() + { + AccountUser accountUser = (AccountUser)null; + ServiceError serviceError = (ServiceError)null; + HRESULT account = this.State.AccountManagement.GetAccount((PassportIdentity)null, out accountUser, out serviceError); + if (account.IsError) + { + accountUser = (AccountUser)null; + this.SetError(account, serviceError); + } + return accountUser; + } + } +} diff --git a/ZuneUI/EmailDomainPropertyDescriptor.cs b/ZuneUI/EmailDomainPropertyDescriptor.cs new file mode 100644 index 0000000..ff9ddd9 --- /dev/null +++ b/ZuneUI/EmailDomainPropertyDescriptor.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EmailDomainPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class EmailDomainPropertyDescriptor : PropertyDescriptor + { + public EmailDomainPropertyDescriptor( + string name, + string multiValueString, + string unknownString) + : base(name, multiValueString, unknownString, true) + { + } + + public override bool IsValidInternal(string value) => EmailHelper.IsValidDomain(value); + } +} diff --git a/ZuneUI/EmailHelper.cs b/ZuneUI/EmailHelper.cs new file mode 100644 index 0000000..551c785 --- /dev/null +++ b/ZuneUI/EmailHelper.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EmailHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text.RegularExpressions; + +namespace ZuneUI +{ + public static class EmailHelper + { + private static Regex s_emailRegex = new Regex("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", RegexOptions.IgnoreCase); + private static Regex s_emailDomainRegex = new Regex("^[A-Z0-9.-]+\\.[A-Z]{2,6}$", RegexOptions.IgnoreCase); + + public static bool IsValid(string email) => !string.IsNullOrEmpty(email) && EmailHelper.s_emailRegex.IsMatch(email); + + public static bool IsValidDomain(string domain) => !string.IsNullOrEmpty(domain) && EmailHelper.s_emailDomainRegex.IsMatch(domain); + } +} diff --git a/ZuneUI/EmailPropertyDescriptor.cs b/ZuneUI/EmailPropertyDescriptor.cs new file mode 100644 index 0000000..c47cf85 --- /dev/null +++ b/ZuneUI/EmailPropertyDescriptor.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EmailPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class EmailPropertyDescriptor : PropertyDescriptor + { + public EmailPropertyDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : base(name, multiValueString, unknownString, required) + { + } + + public override bool IsValidInternal(string value) => string.IsNullOrEmpty(value) && !this.Required || EmailHelper.IsValid(value); + } +} diff --git a/ZuneUI/EmailSelectionPropertyEditor.cs b/ZuneUI/EmailSelectionPropertyEditor.cs new file mode 100644 index 0000000..ebf5dae --- /dev/null +++ b/ZuneUI/EmailSelectionPropertyEditor.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EmailSelectionPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class EmailSelectionPropertyEditor : WizardPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static PropertyDescriptor s_Email = (PropertyDescriptor)new EmailPropertyDescriptor(nameof(Email), string.Empty, string.Empty, true); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (EmailSelectionPropertyEditor.s_dataProviderProperties == null) + EmailSelectionPropertyEditor.s_dataProviderProperties = new PropertyDescriptor[1] + { + EmailSelectionPropertyEditor.s_Email + }; + return EmailSelectionPropertyEditor.s_dataProviderProperties; + } + } + + public static PropertyDescriptor Email => EmailSelectionPropertyEditor.s_Email; + } +} diff --git a/ZuneUI/EmailSelectionStep.cs b/ZuneUI/EmailSelectionStep.cs new file mode 100644 index 0000000..724363b --- /dev/null +++ b/ZuneUI/EmailSelectionStep.cs @@ -0,0 +1,196 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EmailSelectionStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.ErrorMapperApi; +using Microsoft.Zune.Service; +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class EmailSelectionStep : AccountManagementStep + { + private bool _hasEmail; + private bool _isEmailPassportId; + private bool _pageLocked; + private bool _skipOnce; + private Dictionary _errorMappings; + + public EmailSelectionStep(Wizard owner, AccountManagementWizardState state, bool parentAccount) + : base(owner, state, parentAccount) + { + if (parentAccount) + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_PARENTAL_INPUT_HEAD); + else + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_EMAIL_STEP); + this.Initialize((WizardPropertyEditor)new EmailSelectionPropertyEditor()); + } + + public override string UI => "res://ZuneShellResources!CreatePassport.uix#EmailSelectionStep"; + + public bool HasEmail + { + get => this._hasEmail; + set + { + if (this._hasEmail == value) + return; + this._hasEmail = value; + this.FirePropertyChanged(nameof(HasEmail)); + this.FirePropertyChanged("NeedsPassportId"); + } + } + + public string Email + { + get => this.GetUncommittedValue(EmailSelectionPropertyEditor.Email) as string; + internal set + { + this.SetCommittedValue(EmailSelectionPropertyEditor.Email, (object)value); + this.FirePropertyChanged(nameof(Email)); + } + } + + private bool CheckedEmail => this.ServiceDeactivationRequestsDone; + + internal bool PageLocked + { + get => this._pageLocked; + set + { + if (this._pageLocked == value) + return; + this._pageLocked = value; + this.FirePropertyChanged(nameof(PageLocked)); + } + } + + internal bool SkipOnce + { + get => this._skipOnce; + set + { + if (this._skipOnce == value) + return; + this._skipOnce = value; + this.FirePropertyChanged(nameof(SkipOnce)); + } + } + + public bool IsEmailPassportId + { + get => this._isEmailPassportId; + private set + { + if (this._isEmailPassportId == value) + return; + this._isEmailPassportId = value; + this.FirePropertyChanged(nameof(IsEmailPassportId)); + this.FirePropertyChanged("NeedsPassportId"); + } + } + + public bool NeedsPassportId => !this.HasEmail || !this.IsEmailPassportId; + + public override bool IsValid + { + get + { + MetadataEditProperty property = this.WizardPropertyEditor.GetProperty(EmailSelectionPropertyEditor.Email); + HRESULT hresult = HRESULT._S_OK; + if (this.HasEmail) + { + string email = this.Email; + if (this.HasEmail && this.ParentAccount && (email.Equals(this.State.EmailSelectionStep.Email, StringComparison.InvariantCultureIgnoreCase) || email.Equals(this.State.CreatePassportStep.Email, StringComparison.InvariantCultureIgnoreCase))) + hresult = HRESULT._ZUNE_E_SIGNUP_INVALID_PARENT_EMAIL; + } + if (hresult.IsError || property.ExternalError == HRESULT._ZUNE_E_SIGNUP_INVALID_PARENT_EMAIL) + property.ExternalError = hresult; + return !this.HasEmail || base.IsValid; + } + } + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled && !this.CreatePassportStep.CreatedPassport; + if (flag) + flag = !this.ParentAccount || this.State.BasicAccountInfoStep.IsParentAccountNeeded; + if (flag) + flag = !this.CheckedEmail || !this.PageLocked; + return flag; + } + } + + internal override Dictionary ErrorPropertyMappings + { + get + { + if (this._errorMappings == null) + { + this._errorMappings = new Dictionary(1); + this._errorMappings.Add(HRESULT._ZUNE_E_WINLIVE_UNAUTHORIZED_DOMAIN.Int, EmailSelectionPropertyEditor.Email); + } + return this._errorMappings; + } + } + + internal override ErrorMapperResult GetMappedErrorDescriptionAndUrl(HRESULT hr) => Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int, eErrorCondition.eEC_WinLive); + + private CreatePassportStep CreatePassportStep => !this.ParentAccount ? this.State.CreatePassportStep : this.State.CreatePassportParentStep; + + protected override void OnActivate() + { + if (this.SkipOnce || this.PageLocked) + { + this.SkipOnce = false; + this._owner.MoveNext(); + } + else + { + this.ServiceDeactivationRequestsDone = false; + if (string.IsNullOrEmpty(this.Email) && !this.ParentAccount) + { + UIDevice appDevice = ApplicationMarketplaceHelper.FindAppDevice(); + if (appDevice != UIDeviceList.NullDevice) + { + this.Email = appDevice.LiveId; + this.HasEmail = !string.IsNullOrEmpty(this.Email); + } + } + base.OnActivate(); + } + } + + internal override bool OnMovingNext() + { + if (!this.HasEmail) + this.ServiceDeactivationRequestsDone = true; + if (this.ServiceDeactivationRequestsDone) + return base.OnMovingNext(); + this.StartDeactivationRequests((object)this.Email); + return false; + } + + protected override void OnStartDeactivationRequests(object state) => this.EndDeactivationRequests((object)this.ValidatePassportId(state as string)); + + protected override void OnEndDeactivationRequests(object args) => this.IsEmailPassportId = (bool)args; + + private bool ValidatePassportId(string email) + { + bool flag = false; + ServiceError serviceError = (ServiceError)null; + WinLiveAvailableInformation information; + HRESULT hr = this.State.WinLiveSignup.CheckAvailableSigninName(email, false, (string)null, (string)null, out information, out serviceError); + if (hr.IsError) + this.SetError(hr, serviceError); + else + flag = !information.Available; + return flag; + } + } +} diff --git a/ZuneUI/Enum.cs b/ZuneUI/Enum.cs new file mode 100644 index 0000000..694bb9a --- /dev/null +++ b/ZuneUI/Enum.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Enum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public static class Enum + { + public static string GetDescription(System.Enum value) + { + object[] customAttributes = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false); + return customAttributes == null || customAttributes.Length <= 0 ? value.ToString() : Shell.LoadString((StringId)((DescriptionAttribute)customAttributes[0]).StringId); + } + } +} diff --git a/ZuneUI/EpisodeAttachment.cs b/ZuneUI/EpisodeAttachment.cs new file mode 100644 index 0000000..9707c38 --- /dev/null +++ b/ZuneUI/EpisodeAttachment.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EpisodeAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class EpisodeAttachment : VideoAttachment + { + public const string RequestTypeString = "video"; + + public EpisodeAttachment(Guid id, string title, string subtitle, string imageUri) + : base(id, title, subtitle, imageUri) + { + this.AttachmentUI = "res://ZuneShellResources!SocialComposer.uix#EpisodeAttachmentUI"; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_VIDEO_ATTACHMENT); + } + + public override string RequestType => "video"; + } +} diff --git a/ZuneUI/EpisodeDownloadCommand.cs b/ZuneUI/EpisodeDownloadCommand.cs new file mode 100644 index 0000000..49dd9ee --- /dev/null +++ b/ZuneUI/EpisodeDownloadCommand.cs @@ -0,0 +1,109 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.EpisodeDownloadCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Subscription; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class EpisodeDownloadCommand : DownloadCommand + { + private DataProviderObject m_episode; + private EItemDownloadType m_downloadType; + private bool m_requireSignIn; + private bool m_explicit; + + public EpisodeDownloadCommand(IModelItem owner, DataProviderObject episode) + : base(owner) + { + this.m_episode = episode; + this.m_downloadType = (EItemDownloadType)this.m_episode.GetProperty("DownloadType"); + this.TaskId = (string)this.m_episode.GetProperty("EnclosureUrl"); + } + + public static void DownloadEpisode(DataProviderObject episode) + { + if (episode is SubscriptionDataProviderItem) + ((SubscriptionDataProviderItem)episode).SaveToLibrary(); + EpisodeDownloadCommand.DownloadEpisode((int)episode.GetProperty("SeriesId"), (int)episode.GetProperty("LibraryId")); + } + + public static void DownloadEpisode(int seriesId, int episodeId) + { + try + { + SubscriptionManager.Instance.DownloadEpisode(seriesId, episodeId); + } + catch (ApplicationException ex) + { + } + } + + protected override void OnInvoked() + { + switch (this.GetDownloadState()) + { + case EDownloadTaskState.DLTaskPendingAttach: + case EDownloadTaskState.DLTaskPending: + case EDownloadTaskState.DLTaskDownloading: + case EDownloadTaskState.DLTaskPaused: + ZuneShell.DefaultInstance.Execute("Marketplace\\Downloads\\Home", (IDictionary)null); + break; + case EDownloadTaskState.DLTaskComplete: + PodcastLibraryPage.FindInCollection((int)this.m_episode.GetProperty("SeriesId"), (int)this.m_episode.GetProperty("LibraryId")); + break; + default: + if (this.m_requireSignIn && !SignIn.Instance.SignedIn || this.m_explicit && ZuneApplication.Service.BlockExplicitContent()) + break; + EpisodeDownloadCommand.DownloadEpisode(this.m_episode); + this.Refresh(); + break; + } + } + + public bool RequireSignIn + { + get => this.m_requireSignIn; + set => this.m_requireSignIn = value; + } + + public bool Explicit + { + get => this.m_explicit; + set => this.m_explicit = value; + } + + protected override EDownloadTaskState GetDownloadState() + { + this.m_downloadType = (EItemDownloadType)this.m_episode.GetProperty("DownloadType"); + switch ((EItemDownloadState)this.m_episode.GetProperty("DownloadState")) + { + case EItemDownloadState.eDownloadStateNone: + return EDownloadTaskState.DLTaskNone; + case EItemDownloadState.eDownloadStateDownloading: + return EDownloadTaskState.DLTaskDownloading; + case EItemDownloadState.eDownloadStateDownloaded: + return EDownloadTaskState.DLTaskComplete; + default: + return EDownloadTaskState.DLTaskNone; + } + } + + protected override string GetDownloadString(EDownloadTaskState downloadState) + { + if (downloadState != EDownloadTaskState.DLTaskComplete) + return base.GetDownloadString(downloadState); + return this.m_downloadType == EItemDownloadType.eDownloadTypeAutomatic ? ZuneUI.Shell.LoadString(StringId.IDS_AUTOMATIC) : ZuneUI.Shell.LoadString(StringId.IDS_INCOLLECTION); + } + + public static int ConvertDownloadStatusToInt(EItemDownloadState type) => (int)type; + + public static int ConvertDownloadTypeToInt(EItemDownloadType type) => (int)type; + } +} diff --git a/ZuneUI/ErrorDialogInfo.cs b/ZuneUI/ErrorDialogInfo.cs new file mode 100644 index 0000000..3a2a0de --- /dev/null +++ b/ZuneUI/ErrorDialogInfo.cs @@ -0,0 +1,53 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ErrorDialogInfo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.ErrorMapperApi; +using UIXControls; + +namespace ZuneUI +{ + public class ErrorDialogInfo : DialogHelper + { + private int _hr; + private int _hrOriginal; + private string _title; + private string _description; + private string _webHelpUrl; + private eErrorCondition _condition; + + internal static void Show(int hr, string title) => ErrorDialogInfo.Show(hr, eErrorCondition.eEC_None, title, (string)null); + + internal static void Show(int hr, eErrorCondition condition, string title) => ErrorDialogInfo.Show(hr, condition, title, (string)null); + + internal static void Show(int hr, string title, string description) => ErrorDialogInfo.Show(hr, eErrorCondition.eEC_None, title, description); + + internal static void Show(int hr, eErrorCondition condition, string title, string description) => new ErrorDialogInfo(hr, condition, title, description).Show(); + + private ErrorDialogInfo(int hr, eErrorCondition condition, string title, string description) + : base("res://ZuneShellResources!ErrorDialog.uix#ErrorDialogContentUI") + { + this._title = title; + this._hrOriginal = hr; + this._condition = condition; + ErrorMapperResult descriptionAndUrl = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(this._hrOriginal, this._condition); + this._hr = descriptionAndUrl.Hr; + this._description = description ?? descriptionAndUrl.Description; + this._webHelpUrl = descriptionAndUrl.WebHelpUrl; + } + + public int HR => this._hr; + + public int OriginalHR => this._hrOriginal; + + public eErrorCondition ErrorCondition => this._condition; + + public string Title => this._title; + + public new string Description => this._description; + + public string WebHelpUrl => this._webHelpUrl; + } +} diff --git a/ZuneUI/ExistingSyncGroup.cs b/ZuneUI/ExistingSyncGroup.cs new file mode 100644 index 0000000..9601f69 --- /dev/null +++ b/ZuneUI/ExistingSyncGroup.cs @@ -0,0 +1,230 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ExistingSyncGroup +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Playlist; +using MicrosoftZuneLibrary; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class ExistingSyncGroup : SyncGroup + { + private SyncRuleDetails _details; + private SyncRulesView _view; + private int _index; + private bool _isExpanded; + private string _title; + private AutoPlaylistBuilder _originalComplexRuleSetup; + private string _originalComplexRuleName; + private SyncCategory _complexType; + private bool _isEdited; + + public ExistingSyncGroup(SyncGroupList parentList, SyncRulesView view, int index) + : this(parentList, view, index, false) + { + } + + public ExistingSyncGroup( + SyncGroupList parentList, + SyncRulesView view, + int index, + bool isExpandedEntry) + : base(parentList) + { + this._details = view.GetItem(index); + this._view = view; + this._index = index; + this._isExpanded = isExpandedEntry; + this.UpdateTitle(); + if (!this.IsComplex) + return; + this.UpdateComplexType(); + this._originalComplexRuleName = this.Title; + this._originalComplexRuleSetup = new AutoPlaylistBuilder(this.ID); + } + + protected override void OnDispose(bool disposing) + { + if (disposing && this._originalComplexRuleSetup != null) + this._originalComplexRuleSetup.Dispose(); + base.OnDispose(disposing); + } + + public override string Title => this._title; + + public override int ID => this._details.mediaId; + + public override SyncCategory Type => this.IsComplex ? this._complexType : (SyncCategory)this._details.syncCategory; + + public override long Size => !this._details.calculated || this._isEdited ? -1L : this._details.totalSize; + + public override int Count => !this._details.calculated || this._isEdited ? -1 : (int)this._details.totalItems; + + public override SyncGroupState State + { + get + { + if (this._isEdited) + return SyncGroupState.Pending; + return !this._details.calculated ? SyncGroupState.Uncalculated : SyncGroupState.Calculated; + } + } + + public override bool IsActive + { + get => this._details.included; + set + { + this._view.UpdateItem(this._index, value); + this.DataUpdated(); + } + } + + public override bool IsVisible => !this._details.ignore; + + public override bool IsComplex => this._details.complex; + + public override void CommitChanges() + { + if (!this.IsVisible || this.IsActive) + return; + MediaIdAndType[] mediaIdAndTypeArray = new MediaIdAndType[1] + { + new MediaIdAndType(this.ID, (MediaType) this._details.mediaType) + }; + if (this._isExpanded) + { + this.ParentList.Device.DeleteAndExclude((IList)mediaIdAndTypeArray); + } + else + { + this.ParentList.Device.RemoveSyncRule((IList)mediaIdAndTypeArray); + if (!this.IsComplex) + return; + Shell.DeleteMedia((IList)new List(1) + { + new MediaIdAndType(this.ID, MediaType.Playlist) + }, false); + } + } + + public override void CancelChanges() + { + if (!this.IsComplex || !this._isEdited) + return; + if (this.Title != this._originalComplexRuleName) + PlaylistManager.Instance.RenamePlaylist(this.ID, this._originalComplexRuleName); + this._originalComplexRuleSetup.SetRules(this.ID); + } + + public override void DataUpdated() + { + this._details = this._view.GetItem(this._index); + this.UpdateTitle(); + this.FirePropertyChanged("Size"); + this.FirePropertyChanged("Count"); + this.FirePropertyChanged("State"); + this.FirePropertyChanged("IsActive"); + this.FirePropertyChanged("IsVisible"); + if (!(this.ParentList.GetGroupForSchema(this.Type) is DetailsBackedSchemaSyncGroup groupForSchema)) + return; + groupForSchema.UpdateActiveState(); + } + + public override void DataEdited() + { + this._isEdited = true; + this.UpdateComplexType(); + this.DataUpdated(); + } + + private void UpdateTitle() + { + if (this.IsComplex) + { + this._title = PlaylistManager.GetPlaylistName(this.ID); + } + else + { + EListType listType = EListType.eDeviceContentList; + SchemaMap schemaMap = SchemaMap.kiIndex_Title; + string format = "{0}"; + switch ((MediaType)this._details.mediaType) + { + case MediaType.Track: + listType = EListType.eTrackList; + format = Shell.LoadString(StringId.IDS_TRACK_RULE_BASE); + break; + case MediaType.Video: + listType = EListType.eVideoList; + format = Shell.LoadString(StringId.IDS_VIDEO_RULE_BASE); + break; + case MediaType.Photo: + listType = EListType.ePhotoList; + format = Shell.LoadString(StringId.IDS_PHOTO_RULE_BASE); + break; + case MediaType.Playlist: + listType = EListType.ePlaylistList; + format = Shell.LoadString(StringId.IDS_PLAYLIST_RULE_BASE); + break; + case MediaType.Album: + listType = EListType.eAlbumList; + schemaMap = SchemaMap.kiIndex_WMAlbumTitle; + format = Shell.LoadString(StringId.IDS_ALBUM_RULE_BASE); + break; + case MediaType.PodcastEpisode: + listType = EListType.ePodcastEpisodeList; + format = Shell.LoadString(StringId.IDS_PODCAST_EPISODE_RULE_BASE); + break; + case MediaType.Podcast: + listType = EListType.ePodcastList; + format = Shell.LoadString(StringId.IDS_PODCAST_SERIES_RULE_BASE); + break; + case MediaType.MediaFolder: + listType = EListType.eFolderList; + schemaMap = SchemaMap.kiIndex_SourceURL; + format = Shell.LoadString(StringId.IDS_FOLDER_RULE_BASE); + break; + case MediaType.Genre: + listType = EListType.eGenreList; + schemaMap = SchemaMap.kiIndex_WMGenre; + format = Shell.LoadString(StringId.IDS_GENRE_RULE_BASE); + break; + case MediaType.PlaylistChannel: + listType = EListType.ePlaylistList; + format = "{0}"; + break; + case MediaType.Artist: + listType = EListType.eArtistList; + schemaMap = SchemaMap.kiIndex_WMAlbumArtist; + format = Shell.LoadString(StringId.IDS_ARTIST_RULE_BASE); + break; + case MediaType.UserCard: + listType = EListType.eUserCardList; + format = Shell.LoadString(StringId.IDS_FRIEND_RULE_BASE); + break; + case MediaType.Application: + listType = EListType.eAppList; + format = Shell.LoadString(StringId.IDS_APPLICATION_RULE_BASE); + break; + default: + this._title = Shell.LoadString(StringId.IDS_GENERIC_ERROR); + break; + } + if (listType != EListType.eDeviceContentList) + this._title = string.Format(format, (object)PlaylistManager.GetFieldValue(this.ID, listType, (int)schemaMap, Shell.LoadString(StringId.IDS_GENERIC_ERROR))); + } + this.FirePropertyChanged("Title"); + } + + private void UpdateComplexType() + { + this._complexType = UIDeviceList.MapMediaTypeToSyncCategory(PlaylistManager.GetAutoPlaylistSchema(this.ID)); + this.FirePropertyChanged("Type"); + } + } +} diff --git a/ZuneUI/Experience.cs b/ZuneUI/Experience.cs new file mode 100644 index 0000000..2f5fb5a --- /dev/null +++ b/ZuneUI/Experience.cs @@ -0,0 +1,95 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Experience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public abstract class Experience : Command + { + private bool _isCurrent; + private Choice _nodes; + private SQMDataId _sqmClickId; + + public Experience(Frame frameOwner) + : base((IModelItemOwner)frameOwner, "", (EventHandler)null) + => this._sqmClickId = SQMDataId.Invalid; + + public Experience(Frame frameOwner, StringId nameId, SQMDataId SQMClickId) + : base((IModelItemOwner)frameOwner, Shell.LoadString(nameId), (EventHandler)null) + => this._sqmClickId = SQMClickId; + + public Choice Nodes + { + get + { + if (this._nodes == null) + { + this._nodes = new Choice((IModelItemOwner)this); + this._nodes.Options = this.NodesList; + } + return this._nodes; + } + set + { + if (this._nodes == value) + return; + this._nodes = value; + this.FirePropertyChanged(nameof(Nodes)); + } + } + + public abstract IList NodesList { get; } + + public Frame Frame => (Frame)this.Owner; + + public bool IsCurrent + { + get => this._isCurrent; + set + { + if (this._isCurrent == value) + return; + this._isCurrent = value; + this.OnIsCurrentChanged(); + this.FirePropertyChanged(nameof(IsCurrent)); + } + } + + public virtual string DefaultUIPath => ""; + + protected int GetNodeIndex(Node node) + { + for (int index = 0; index < this.NodesList.Count; ++index) + { + if (this.NodesList[index] == node) + return index; + } + return -1; + } + + protected virtual void OnIsCurrentChanged() + { + } + + protected override void OnInvoked() + { + if (this.IsCurrent) + return; + ((Frame)this.Owner).Experiences.ChosenValue = (object)this; + Node node = (Node)this.Nodes.ChosenValue; + if (node == null && this.NodesList != null && this.NodesList.Count > 0) + node = (Node)this.NodesList[0]; + node?.Invoke(InvokePolicy.Synchronous); + if (this._sqmClickId != SQMDataId.Invalid) + SQMLog.Log(this._sqmClickId, 1); + base.OnInvoked(); + } + } +} diff --git a/ZuneUI/FallibleEventArgs.cs b/ZuneUI/FallibleEventArgs.cs new file mode 100644 index 0000000..b89c648 --- /dev/null +++ b/ZuneUI/FallibleEventArgs.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FallibleEventArgs +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public struct FallibleEventArgs + { + public readonly HRESULT HR; + + public FallibleEventArgs(HRESULT hr) => this.HR = hr; + } +} diff --git a/ZuneUI/FallibleEventHandler.cs b/ZuneUI/FallibleEventHandler.cs new file mode 100644 index 0000000..fdd254a --- /dev/null +++ b/ZuneUI/FallibleEventHandler.cs @@ -0,0 +1,10 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FallibleEventHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public delegate void FallibleEventHandler(object sender, FallibleEventArgs args); +} diff --git a/ZuneUI/FamilySetting.cs b/ZuneUI/FamilySetting.cs new file mode 100644 index 0000000..357c637 --- /dev/null +++ b/ZuneUI/FamilySetting.cs @@ -0,0 +1,73 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FamilySetting +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FamilySetting + { + private int _ratingId; + private string _ratingSystem; + private int _ratingLevel; + private bool _blockUnrated; + private bool _changed; + + public FamilySetting(int ratingId, string ratingSystem, int ratingLevel, bool blockUnrated) + { + this._ratingId = ratingId; + this._ratingSystem = ratingSystem; + this._ratingLevel = ratingLevel; + this._blockUnrated = blockUnrated; + this._changed = false; + } + + public FamilySetting(string ratingSystem, int ratingLevel, bool blockUnrated) + { + this._ratingId = -1; + this._ratingSystem = ratingSystem; + this._ratingLevel = ratingLevel; + this._blockUnrated = blockUnrated; + this._changed = true; + } + + public int RatingId + { + get => this._ratingId; + set => this._ratingId = value; + } + + public string RatingSystem + { + get => this._ratingSystem; + set + { + this._ratingSystem = value; + this._changed = true; + } + } + + public int RatingLevel + { + get => this._ratingLevel; + set + { + this._ratingLevel = value; + this._changed = true; + } + } + + public bool BlockUnrated + { + get => this._blockUnrated; + set + { + this._blockUnrated = value; + this._changed = true; + } + } + + public bool HasChanged => this._changed; + } +} diff --git a/ZuneUI/FamilySettingChoice.cs b/ZuneUI/FamilySettingChoice.cs new file mode 100644 index 0000000..a85ca7a --- /dev/null +++ b/ZuneUI/FamilySettingChoice.cs @@ -0,0 +1,69 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FamilySettingChoice +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class FamilySettingChoice : Choice + { + private string _title; + private string _settingId; + private bool _showBlockUnrated; + private BooleanChoice _blockUnrated; + private IList _choices; + + public FamilySettingChoice( + IModelItemOwner owner, + string title, + string description, + string blockText, + string settingId, + bool showBlockUnrated, + IList choices) + : base(owner, description, choices) + { + this._title = title; + this._settingId = settingId; + this._showBlockUnrated = showBlockUnrated; + this._blockUnrated = new BooleanChoice(owner, blockText); + this._choices = choices; + this.Clear(); + } + + public string Title => this._title; + + public string SettingId => this._settingId; + + public bool ShowBlockUnrated => this._showBlockUnrated; + + public BooleanChoice BlockUnrated => this._blockUnrated; + + public IList Choices => this._choices; + + public FamilySettingValue GetSettingValueById(int value) + { + foreach (FamilySettingValue choice in (IEnumerable)this.Choices) + { + if (choice.Value == value) + return choice; + } + return (FamilySettingValue)null; + } + + public FamilySettingValue SettingValue + { + get => (FamilySettingValue)this.ChosenValue; + set + { + if (!this.Options.Contains((object)value)) + return; + this.ChosenValue = (object)value; + } + } + } +} diff --git a/ZuneUI/FamilySettingValue.cs b/ZuneUI/FamilySettingValue.cs new file mode 100644 index 0000000..2f0bded --- /dev/null +++ b/ZuneUI/FamilySettingValue.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FamilySettingValue +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FamilySettingValue + { + private string _text; + private int _value; + + public FamilySettingValue(string text, int value) + { + this._text = text; + this._value = value; + } + + public int Value => this._value; + + public string Text => this._text; + } +} diff --git a/ZuneUI/FamilySettings.cs b/ZuneUI/FamilySettings.cs new file mode 100644 index 0000000..a876047 --- /dev/null +++ b/ZuneUI/FamilySettings.cs @@ -0,0 +1,89 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FamilySettings +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class FamilySettings + { + private Dictionary _settings; + private int _userId; + + public FamilySettings(int userId) + { + this._userId = userId; + this._settings = (Dictionary)null; + this.ReloadSettings(); + } + + public FamilySettings() + { + this._userId = -1; + this._settings = new Dictionary(); + } + + public void ReloadSettings() + { + this.Settings = new Dictionary(); + int[] rgSettingIds; + FamilySettingsManager.Instance.GetSettingIdsForUser(this.UserId, out rgSettingIds); + if (rgSettingIds == null || rgSettingIds.Length <= 0) + return; + for (int index = 0; index < rgSettingIds.Length; ++index) + { + string szRatingSystem; + int nRatingLevel; + bool fBlockUnrated; + FamilySettingsManager.Instance.GetSetting(rgSettingIds[index], out szRatingSystem, out nRatingLevel, out fBlockUnrated); + this.Settings[szRatingSystem] = new FamilySetting(rgSettingIds[index], szRatingSystem, nRatingLevel, fBlockUnrated); + } + } + + public int UserId + { + get => this._userId; + set => this._userId = value; + } + + public Dictionary Settings + { + get => this._settings; + set => this._settings = value; + } + + public void CommitSettings() + { + if (this.UserId == -1) + return; + foreach (FamilySetting familySetting in this.Settings.Values) + { + if (familySetting.HasChanged) + { + int settingId; + FamilySettingsManager.Instance.AddSetting(familySetting.RatingId, this.UserId, familySetting.RatingSystem, familySetting.RatingLevel, familySetting.BlockUnrated, out settingId); + if (familySetting.RatingId == -1) + familySetting.RatingId = settingId; + } + } + } + + public void SetSetting(string ratingSystem, int ratingLevel, bool blockUnrated) + { + if (string.IsNullOrEmpty(ratingSystem)) + return; + if (this.Settings.ContainsKey(ratingSystem)) + { + FamilySetting setting = this.Settings[ratingSystem]; + setting.RatingLevel = ratingLevel; + setting.BlockUnrated = blockUnrated; + } + else + this.Settings.Add(ratingSystem, new FamilySetting(ratingSystem, ratingLevel, blockUnrated)); + } + } +} diff --git a/ZuneUI/FeatureMenuItemCommand.cs b/ZuneUI/FeatureMenuItemCommand.cs new file mode 100644 index 0000000..23cb1a0 --- /dev/null +++ b/ZuneUI/FeatureMenuItemCommand.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FeatureMenuItemCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class FeatureMenuItemCommand : MenuItemCommand + { + private Features _feature; + private int _hidden = -1; + + public Features Features + { + get => this._feature; + set + { + if (this._feature != value) + this._hidden = -1; + this._feature = value; + } + } + + public override bool ShouldHide() + { + if (this._hidden == -1) + this._hidden = !FeatureEnablement.IsFeatureEnabled(this._feature) ? 1 : 0; + return this._hidden == 1 || base.ShouldHide(); + } + } +} diff --git a/ZuneUI/FeaturesChanged.cs b/ZuneUI/FeaturesChanged.cs new file mode 100644 index 0000000..23bc557 --- /dev/null +++ b/ZuneUI/FeaturesChanged.cs @@ -0,0 +1,56 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FeaturesChanged +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; +using UIXControls; + +namespace ZuneUI +{ + public class FeaturesChanged : IDisposable + { + private bool m_featuresHaveChanged; + private static FeaturesChanged m_instance; + + public static FeaturesChanged Instance + { + get + { + if (FeaturesChanged.m_instance == null) + FeaturesChanged.m_instance = new FeaturesChanged(); + return FeaturesChanged.m_instance; + } + } + + public void StartUp() + { + this.m_featuresHaveChanged = false; + FeaturesChangedApi.Instance.OnFeaturesChangedEvent += new FeaturesChangedHandler(this.OnFeaturesChangedCallback); + } + + private void OnFeaturesChangedCallback(bool featuresHaveChanged) + { + this.FeaturesHaveChanged = featuresHaveChanged; + if (!Shell.MainFrame.Marketplace.IsCurrent) + return; + CultureHelper.CheckMarketplaceCulture(); + } + + public bool FeaturesHaveChanged + { + get => this.m_featuresHaveChanged; + private set + { + if (this.m_featuresHaveChanged || !value) + return; + MessageBox.Show(Shell.LoadString(StringId.IDS_FEATURESCHANGED_TITLE), Shell.LoadString(StringId.IDS_FEATURESCHANGED_CONTENT), (EventHandler)null); + this.m_featuresHaveChanged = value; + } + } + + public void Dispose() => FeaturesChangedApi.Instance.OnFeaturesChangedEvent -= new FeaturesChangedHandler(this.OnFeaturesChangedCallback); + } +} diff --git a/ZuneUI/FileOpenDialog.cs b/ZuneUI/FileOpenDialog.cs new file mode 100644 index 0000000..69de0c7 --- /dev/null +++ b/ZuneUI/FileOpenDialog.cs @@ -0,0 +1,168 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FileOpenDialog +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Runtime.InteropServices; +using System.Threading; + +namespace ZuneUI +{ + public class FileOpenDialog + { + private string m_filePath; + + private FileOpenDialog() + { + } + + public string FilePath + { + get => this.m_filePath; + private set => this.m_filePath = value; + } + + public static FileOpenDialog Show( + string title, + string initialPath, + Command doneCommand) + { + return FileOpenDialog.Show(title, initialPath, (string[])null, doneCommand); + } + + public static FileOpenDialog Show( + string title, + string initialPath, + string[] fileFilters, + Command doneCommand) + { + FileOpenDialog dialog = new FileOpenDialog(); + FileOpenDialog.Show(title, initialPath, fileFilters, (DeferredInvokeHandler)(args => + { + dialog.FilePath = (string)args; + doneCommand?.Invoke(); + })); + return dialog; + } + + public static void Show(string title, string initialPath, DeferredInvokeHandler callback) => FileOpenDialog.Show(title, initialPath, (string[])null, callback); + + public static void Show( + string title, + string initialPath, + string[] fileFilters, + DeferredInvokeHandler callback) + { + IntPtr winHandle = Application.Window.Handle; + Thread thread = new Thread((ParameterizedThreadStart)(args => + { + FileOpenDialog.OpenFileName ofn = new FileOpenDialog.OpenFileName(winHandle); + try + { + if (!string.IsNullOrEmpty(title)) + ofn.lpstrTitle = title; + if (!string.IsNullOrEmpty(initialPath)) + ofn.lpstrInitialDir = initialPath; + if (fileFilters != null) + ofn.lpstrFilter = string.Join("\0", fileFilters) + "\0"; + string str = (string)null; + if (FileOpenDialog.GetOpenFileName(ofn)) + str = Marshal.PtrToStringUni(ofn.lpstrFile); + Application.DeferredInvoke(callback, (object)str); + } + finally + { + ofn?.Dispose(); + } + })); + thread.TrySetApartmentState(ApartmentState.STA); + thread.Start(); + } + + public static string MyPicturesPath => Environment.GetFolderPath(Environment.SpecialFolder.MyPictures); + + [DllImport("comdlg32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern bool GetOpenFileName([In, Out] FileOpenDialog.OpenFileName ofn); + + private delegate IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + private class OpenFileName : IDisposable + { + public int lStructSize; + public IntPtr hwndOwner; + public IntPtr hInstance; + [MarshalAs(UnmanagedType.LPWStr)] + public string lpstrFilter; + public IntPtr lpstrCustomFilter; + public int nMaxCustFilter; + public int nFilterIndex; + public IntPtr lpstrFile; + public int nMaxFile; + public IntPtr lpstrFileTitle; + public int nMaxFileTitle; + public string lpstrInitialDir; + public string lpstrTitle; + public int Flags; + public short nFileOffset; + public short nFileExtension; + public string lpstrDefExt; + public IntPtr lCustData; + public FileOpenDialog.WndProc lpfnHook; + public string lpTemplateName; + public IntPtr pvReserved; + public int dwReserved; + public int FlagsEx; + + public OpenFileName(IntPtr handle) + { + IntPtr ptr = Marshal.AllocHGlobal(520); + Marshal.WriteInt32(ptr, 0); + this.lpstrCustomFilter = IntPtr.Zero; + this.nMaxFile = 260; + this.lpstrFile = ptr; + this.lpstrFileTitle = IntPtr.Zero; + this.nMaxFileTitle = 260; + this.lCustData = IntPtr.Zero; + this.pvReserved = IntPtr.Zero; + this.hwndOwner = handle; + this.lStructSize = Marshal.SizeOf(typeof(FileOpenDialog.OpenFileName)); + } + + public void Dispose() => Marshal.FreeHGlobal(this.lpstrFile); + } + + private enum OpenFileNameFlags + { + OFN_READONLY = 1, + OFN_OVERWRITEPROMPT = 2, + OFN_HIDEREADONLY = 4, + OFN_NOCHANGEDIR = 8, + OFN_SHOWHELP = 16, // 0x00000010 + OFN_ENABLEHOOK = 32, // 0x00000020 + OFN_ENABLETEMPLATE = 64, // 0x00000040 + OFN_ENABLETEMPLATEHANDLE = 128, // 0x00000080 + OFN_NOVALIDATE = 256, // 0x00000100 + OFN_ALLOWMULTISELECT = 512, // 0x00000200 + OFN_EXTENSIONDIFFERENT = 1024, // 0x00000400 + OFN_PATHMUSTEXIST = 2048, // 0x00000800 + OFN_FILEMUSTEXIST = 4096, // 0x00001000 + OFN_CREATEPROMPT = 8192, // 0x00002000 + OFN_SHAREAWARE = 16384, // 0x00004000 + OFN_NOREADONLYRETURN = 32768, // 0x00008000 + OFN_NOTESTFILECREATE = 65536, // 0x00010000 + OFN_NONETWORKBUTTON = 131072, // 0x00020000 + OFN_NOLONGNAMES = 262144, // 0x00040000 + OFN_EXPLORER = 524288, // 0x00080000 + OFN_NODEREFERENCELINKS = 1048576, // 0x00100000 + OFN_LONGNAMES = 2097152, // 0x00200000 + OFN_ENABLEINCLUDENOTIFY = 4194304, // 0x00400000 + OFN_ENABLESIZING = 8388608, // 0x00800000 + OFN_DONTADDTORECENT = 33554432, // 0x02000000 + OFN_FORCESHOWHIDDEN = 268435456, // 0x10000000 + } + } +} diff --git a/ZuneUI/FilterList.cs b/ZuneUI/FilterList.cs new file mode 100644 index 0000000..87a3b78 --- /dev/null +++ b/ZuneUI/FilterList.cs @@ -0,0 +1,61 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FilterList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public abstract class FilterList : ModelItem + { + private IList _source; + private IList _filteredList; + + public IList Source + { + get => this._source; + set + { + if (this._source == value) + return; + this._source = value; + this.FirePropertyChanged(nameof(Source)); + this.ProduceFilteredList(); + } + } + + public IList FilteredList + { + get => this._filteredList; + private set + { + if (this._filteredList == value) + return; + this._filteredList = value; + this.FirePropertyChanged(nameof(FilteredList)); + } + } + + protected void ProduceFilteredList() + { + IList list = (IList)null; + if (this._source != null) + { + list = (IList)new ArrayListDataSet(); + for (int index = 0; index < this._source.Count; ++index) + { + object obj = this._source[index]; + int count = list.Count; + if (this.ShouldIncludeItem(index, count, obj)) + list.Insert(count, obj); + } + } + this.FilteredList = list; + } + + protected abstract bool ShouldIncludeItem(int sourceIndex, int targetIndex, object item); + } +} diff --git a/ZuneUI/FindAlbumInfoHelper.cs b/ZuneUI/FindAlbumInfoHelper.cs new file mode 100644 index 0000000..c7746c9 --- /dev/null +++ b/ZuneUI/FindAlbumInfoHelper.cs @@ -0,0 +1,88 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FindAlbumInfoHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using MicrosoftZuneLibrary; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class FindAlbumInfoHelper + { + public static AlbumMetadata GetAlbumMetadata(int libraryId) => ZuneApplication.ZuneLibrary.GetAlbumMetadata(libraryId); + + public static List GetSongMatchDataList( + AlbumMetadata localAlbum, + AlbumMetadata mergedAlbum, + uint wmisAlbumTrackCount) + { + List songMatchDataList = new List((int)localAlbum.TrackCount); + for (uint index = 0; index < localAlbum.TrackCount; ++index) + { + TrackMetadata track = localAlbum.GetTrack(index); + GroupedList optionsForTrack = FindAlbumInfoHelper.GetOptionsForTrack(track, mergedAlbum, wmisAlbumTrackCount); + int fromAlbumMetadata = FindAlbumInfoHelper.GetTrackIndexFromAlbumMetadata(mergedAlbum, track.MediaId); + int selectedMatchIndex = (long)fromAlbumMetadata < (long)wmisAlbumTrackCount ? fromAlbumMetadata + 1 : -1; + SongMatchData songMatchData = new SongMatchData(mergedAlbum, track, optionsForTrack, fromAlbumMetadata, selectedMatchIndex); + songMatchDataList.Add(songMatchData); + } + return songMatchDataList; + } + + private static int GetTrackIndexFromAlbumMetadata(AlbumMetadata albumMetadata, int mediaId) + { + for (uint index = 0; index < albumMetadata.TrackCount; ++index) + { + if (albumMetadata.GetTrack(index).MediaId == mediaId) + return (int)index; + } + return -1; + } + + public static void SetAlbumTrackMediaId( + AlbumMetadata albumMetadata, + int trackIndex, + int mediaId) + { + for (uint index = 0; index < albumMetadata.TrackCount; ++index) + { + TrackMetadata track = albumMetadata.GetTrack(index); + if (track.MediaId == mediaId) + { + track.MediaId = -1; + break; + } + } + albumMetadata.GetTrack((uint)trackIndex).MediaId = mediaId; + } + + private static GroupedList GetOptionsForTrack( + TrackMetadata track, + AlbumMetadata mergedAlbum, + uint wmisAlbumTrackCount) + { + List trackOptionGroupItemList = new List((int)wmisAlbumTrackCount + 1); + trackOptionGroupItemList.Add(new TrackOptionGroupItem() + { + TrackMetadata = track, + Original = true + }); + for (int index = 0; (long)index < (long)wmisAlbumTrackCount; ++index) + trackOptionGroupItemList.Add(new TrackOptionGroupItem() + { + TrackMetadata = mergedAlbum.GetTrack((uint)index), + Original = false + }); + return new GroupedList() + { + Comparer = (IComparer)new TrackOptionsComparer(), + Source = (IList)trackOptionGroupItemList + }; + } + } +} diff --git a/ZuneUI/FindAlbumInfoWMISWorker.cs b/ZuneUI/FindAlbumInfoWMISWorker.cs new file mode 100644 index 0000000..c43b88b --- /dev/null +++ b/ZuneUI/FindAlbumInfoWMISWorker.cs @@ -0,0 +1,65 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FindAlbumInfoWMISWorker +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class FindAlbumInfoWMISWorker : ModelItem + { + private AlbumMetadata _metadata; + private DataProviderQueryStatus _status; + + public void BeginGetAlbumFromWMIS( + long wmisAlbumId, + int wmisVolume, + AlbumMetadata albumMetadata) + { + this.Status = DataProviderQueryStatus.RequestingData; + ZuneApplication.ZuneLibrary.GetAlbumMetadataForAlbumId(wmisAlbumId, wmisVolume, albumMetadata, new GetAlbumForAlbumIdCompleteHandler(this.OnCompleteGetAlbumFromWMIS)); + } + + public void OnCompleteGetAlbumFromWMIS( + long wmisAlbumId, + int wmisVolume, + int hr, + AlbumMetadata albumMetadata) + { + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (hr == 0) + { + this.Metadata = albumMetadata; + this.Status = DataProviderQueryStatus.Complete; + } + else + this.Status = DataProviderQueryStatus.Error; + }, (object)null); + } + + public AlbumMetadata Metadata + { + get => this._metadata; + private set + { + this._metadata = value; + this.FirePropertyChanged(nameof(Metadata)); + } + } + + public DataProviderQueryStatus Status + { + get => this._status; + internal set + { + this._status = value; + this.FirePropertyChanged(nameof(Status)); + } + } + } +} diff --git a/ZuneUI/FirstConnectDeviceCustomPrivacyPage.cs b/ZuneUI/FirstConnectDeviceCustomPrivacyPage.cs new file mode 100644 index 0000000..8a250be --- /dev/null +++ b/ZuneUI/FirstConnectDeviceCustomPrivacyPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstConnectDeviceCustomPrivacyPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FirstConnectDeviceCustomPrivacyPage : FirstConnectPage + { + internal FirstConnectDeviceCustomPrivacyPage(Wizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_SELECT_YOUR_PRIVACY_OPTIONS_HEADER); + + public override string UI => "res://ZuneShellResources!FirstConnect.uix#FirstConnectDeviceCustomPrivacyPage"; + } +} diff --git a/ZuneUI/FirstConnectDeviceMarketplacePage.cs b/ZuneUI/FirstConnectDeviceMarketplacePage.cs new file mode 100644 index 0000000..aaec192 --- /dev/null +++ b/ZuneUI/FirstConnectDeviceMarketplacePage.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstConnectDeviceMarketplacePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FirstConnectDeviceMarketplacePage : FirstConnectPage + { + internal FirstConnectDeviceMarketplacePage(Wizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_ENABLE_ZUNE_MARKETPLACE_HEADER); + + public override string UI => "res://ZuneShellResources!FirstConnect.uix#FirstConnectDeviceMarketplacePage"; + + internal override bool OnMovingNext() + { + DeviceManagement deviceManagement = ZuneShell.DefaultInstance.Management.DeviceManagement; + if (deviceManagement.EnableMarketplaceChoice.ChosenIndex == 0 || (HRESULT)deviceManagement.MarketplaceCredentials.hr == HRESULT._S_OK) + return base.OnMovingNext(); + deviceManagement.CredentialValidationRequested = true; + return false; + } + } +} diff --git a/ZuneUI/FirstConnectDeviceNamePage.cs b/ZuneUI/FirstConnectDeviceNamePage.cs new file mode 100644 index 0000000..10c2321 --- /dev/null +++ b/ZuneUI/FirstConnectDeviceNamePage.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstConnectDeviceNamePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FirstConnectDeviceNamePage : FirstConnectPage + { + internal FirstConnectDeviceNamePage(Wizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_NAME_ZUNE_HEADER); + + internal override bool OnMovingNext() + { + bool flag = base.OnMovingNext(); + if (this._owner is FirstConnectForPhoneWizard || this._owner is FirstLaunchForPhoneWizard) + this._owner.CommitChanges(); + return flag; + } + + public override string UI => "res://ZuneShellResources!FirstConnect.uix#FirstConnectDeviceNamePage"; + } +} diff --git a/ZuneUI/FirstConnectDeviceSyncOptionsPage.cs b/ZuneUI/FirstConnectDeviceSyncOptionsPage.cs new file mode 100644 index 0000000..9ac7549 --- /dev/null +++ b/ZuneUI/FirstConnectDeviceSyncOptionsPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstConnectDeviceSyncOptionsPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FirstConnectDeviceSyncOptionsPage : FirstConnectPage + { + internal FirstConnectDeviceSyncOptionsPage(Wizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_CHOOSE_MEDIA_TYPES_TO_SYNC); + + public override string UI => "res://ZuneShellResources!FirstConnect.uix#FirstConnectDeviceSyncOptionsPage"; + } +} diff --git a/ZuneUI/FirstConnectForPhoneWizard.cs b/ZuneUI/FirstConnectForPhoneWizard.cs new file mode 100644 index 0000000..235cd81 --- /dev/null +++ b/ZuneUI/FirstConnectForPhoneWizard.cs @@ -0,0 +1,71 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstConnectForPhoneWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FirstConnectForPhoneWizard : DeviceUpdateWizard + { + private bool _wasPreviouslyNotPaired; + + public FirstConnectForPhoneWizard() + { + this._wasPreviouslyNotPaired = ZuneShell.DefaultInstance.Management.DeviceManagement.DevicePartnership == DeviceRelationship.None; + ZuneShell.DefaultInstance.Management.DeviceManagement.DevicePartnership = DeviceRelationship.Permanent; + } + + protected override void AddPages() + { + this.AddPage((WizardPage)new FirstConnectPhoneIntroPage((Wizard)this), Shell.LoadString(StringId.IDS_BREADCRUMB_INTRODUCTION)); + this.AddPage((WizardPage)new FirstConnectDeviceNamePage((Wizard)this), Shell.LoadString(StringId.IDS_BREADCRUMB_PHONE_NAME)); + this.AddPage((WizardPage)new DeviceUpdateCheckingPage((DeviceUpdateWizard)this), Shell.LoadString(StringId.IDS_BREADCRUMB_PHONE_UPDATE)); + this.AddPage((WizardPage)new DeviceUpdateEULAPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateBatteryPowerPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateGuestWarningPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateSyncingPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateDiskSpaceErrorPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateProgressPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateSummaryPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateErrorPage((DeviceUpdateWizard)this)); + } + + public override void Cancel() + { + if (this.CurrentPage is DeviceUpdateProgressPage) + { + if (this.UIFirmwareUpdater == null || !this.UIFirmwareUpdater.UpdateInProgress) + return; + this.UIFirmwareUpdater.CancelFirmwareUpdate(); + } + else + { + if (this.RequiredStepsComplete) + return; + base.Cancel(); + } + } + + public override bool MoveBack() + { + if (!base.MoveBack()) + return false; + if (this.CurrentPage is FirstConnectPage) + ((FirstConnectPage)this.CurrentPage).IsPageComplete = false; + return true; + } + + public bool RequiredStepsComplete => !(this.CurrentPage is FirstConnectPhoneIntroPage) && !(this.CurrentPage is FirstConnectDeviceNamePage) || ((FirstConnectPage)this.CurrentPage).IsPageComplete; + + public override bool CanCommitChanges => this.IsValid && this.RequiredStepsComplete; + + protected override bool OnCommitChanges() + { + bool navigateToLandingPage = this._wasPreviouslyNotPaired && !(this.CurrentPage is FirstConnectDeviceNamePage); + ZuneShell.DefaultInstance.Management.CommitListSave(); + ZuneShell.DefaultInstance.Management.DeviceManagement.SetupComplete(navigateToLandingPage); + return base.OnCommitChanges(); + } + } +} diff --git a/ZuneUI/FirstConnectLandPage.cs b/ZuneUI/FirstConnectLandPage.cs new file mode 100644 index 0000000..173181d --- /dev/null +++ b/ZuneUI/FirstConnectLandPage.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstConnectLandPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class FirstConnectLandPage : SetupLandPage + { + public FirstConnectLandPage() => this.UI = "res://ZuneShellResources!SetupLand.uix#FirstConnect"; + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (UIDeviceList.IsSuitableForConnection(SyncControls.Instance.CurrentDeviceOverride)) + SyncControls.Instance.CurrentDeviceOverride.Enumerate(); + DeviceManagement.HandleSetupQueue(); + }, DeferredInvokePriority.Low); + } + } +} diff --git a/ZuneUI/FirstConnectPage.cs b/ZuneUI/FirstConnectPage.cs new file mode 100644 index 0000000..3598f22 --- /dev/null +++ b/ZuneUI/FirstConnectPage.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstConnectPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class FirstConnectPage : WizardPage + { + private bool _isEnabled = true; + private bool _isPageComplete; + + internal FirstConnectPage(Wizard wizard) + : base(wizard) + { + } + + public virtual bool IsPageComplete + { + get => this._isPageComplete; + set + { + if (this._isPageComplete == value) + return; + this._isPageComplete = value; + this.FirePropertyChanged(nameof(IsPageComplete)); + } + } + + public override bool IsEnabled => this._isEnabled; + + internal override bool OnMovingNext() + { + this.IsPageComplete = true; + return base.OnMovingNext(); + } + + internal override bool OnMovingBack() + { + this.IsPageComplete = false; + return base.OnMovingBack(); + } + } +} diff --git a/ZuneUI/FirstConnectPhoneIntroPage.cs b/ZuneUI/FirstConnectPhoneIntroPage.cs new file mode 100644 index 0000000..c6b2c23 --- /dev/null +++ b/ZuneUI/FirstConnectPhoneIntroPage.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstConnectPhoneIntroPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FirstConnectPhoneIntroPage : FirstConnectPage + { + internal FirstConnectPhoneIntroPage(Wizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_PHONE_INTRO_TITLE); + + public override bool IsEnabled => this._owner is FirstLaunchForPhoneWizard || this._owner is FirstConnectForPhoneWizard; + + public override string UI => "res://ZuneShellResources!FirstConnect.uix#FirstConnectPhoneIntroPage"; + } +} diff --git a/ZuneUI/FirstConnectWizard.cs b/ZuneUI/FirstConnectWizard.cs new file mode 100644 index 0000000..5aa2560 --- /dev/null +++ b/ZuneUI/FirstConnectWizard.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstConnectWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class FirstConnectWizard : DeviceWizard + { + public FirstConnectWizard() + { + this.AddPage((WizardPage)new FirstConnectDeviceNamePage((Wizard)this)); + if (FeatureEnablement.IsFeatureEnabled(Features.eSocial) || FeatureEnablement.IsFeatureEnabled(Features.eMarketplace)) + this.AddPage((WizardPage)new FirstConnectDeviceMarketplacePage((Wizard)this)); + this.AddPage((WizardPage)new FirstConnectDeviceSyncOptionsPage((Wizard)this)); + if (this.ActiveDevice.SupportsUsageData) + this.AddPage((WizardPage)new FirstConnectDeviceCustomPrivacyPage((Wizard)this)); + else + ZuneShell.DefaultInstance.Management.DeviceManagement.PrivacyChoice.Value = false; + ZuneShell.DefaultInstance.Management.DeviceManagement.DevicePartnership = DeviceRelationship.Permanent; + } + + protected override bool OnCommitChanges() + { + ZuneShell.DefaultInstance.Management.CommitListSave(); + ZuneShell.DefaultInstance.Management.DeviceManagement.SetupComplete(this.ActiveDevice.SupportsBrandingType(DeviceBranding.Kin)); + return base.OnCommitChanges(); + } + } +} diff --git a/ZuneUI/FirstLaunchDownloadFoldersPage.cs b/ZuneUI/FirstLaunchDownloadFoldersPage.cs new file mode 100644 index 0000000..7bef7e2 --- /dev/null +++ b/ZuneUI/FirstLaunchDownloadFoldersPage.cs @@ -0,0 +1,30 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchDownloadFoldersPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FirstLaunchDownloadFoldersPage : FirstLaunchSoftwareSettingBase + { + internal FirstLaunchDownloadFoldersPage(Wizard wizard) + : base(wizard) + { + this.Description = Shell.LoadString(StringId.IDS_CHANGE_WHERE_ZUNE_STORES_MEDIA); + this.EnableVerticalScrolling = true; + } + + public override bool IsEnabled + { + get + { + if (ZuneShell.DefaultInstance.Management.UsingWin7Libraries) + return false; + return !(this._owner is FirstLaunchForPhoneWizard) || ((FirstLaunchForPhoneWizard)this._owner).IsSoftwareSettingsEnabled; + } + } + + public override string UI => "res://ZuneShellResources!FirstLaunch.uix#FirstLaunchDownloadFoldersPage"; + } +} diff --git a/ZuneUI/FirstLaunchFileTypesPage.cs b/ZuneUI/FirstLaunchFileTypesPage.cs new file mode 100644 index 0000000..f4aa8dc --- /dev/null +++ b/ZuneUI/FirstLaunchFileTypesPage.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchFileTypesPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FirstLaunchFileTypesPage : FirstLaunchSoftwareSettingBase + { + internal FirstLaunchFileTypesPage(Wizard wizard) + : base(wizard) + { + this.Description = Shell.LoadString(StringId.IDS_ASSOCIATE_FILE_TYPES); + this.EnableVerticalScrolling = true; + } + + public override string UI => "res://ZuneShellResources!FirstLaunch.uix#FirstLaunchFileTypesPage"; + } +} diff --git a/ZuneUI/FirstLaunchForPhoneWelcomePage.cs b/ZuneUI/FirstLaunchForPhoneWelcomePage.cs new file mode 100644 index 0000000..9464252 --- /dev/null +++ b/ZuneUI/FirstLaunchForPhoneWelcomePage.cs @@ -0,0 +1,53 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchForPhoneWelcomePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class FirstLaunchForPhoneWelcomePage : WizardPage + { + private Choice _welcomeOptionsChoice; + + internal FirstLaunchForPhoneWelcomePage(Wizard wizard) + : base(wizard) + { + this.Description = Shell.LoadString(StringId.IDS_PHONE_WELCOME_TITLE); + this.EnableVerticalScrolling = true; + this.CanNavigateInto = false; + } + + public override string UI => "res://ZuneShellResources!FirstLaunch.uix#FirstLaunchForPhoneWelcomePage"; + + public Choice WelcomeOptionsChoice + { + get + { + if (this._welcomeOptionsChoice == null) + { + this._welcomeOptionsChoice = new Choice((IModelItemOwner)this); + this._welcomeOptionsChoice.Options = (IList)new Command[2] + { + (Command) new RadioOptionWithSecondaryText((IModelItemOwner) this, Shell.LoadString(StringId.IDS_PHONE_WELCOME_DEFAULT_HEADER), Shell.LoadString(StringId.IDS_PHONE_WELCOME_DEFAULT_TEXT)), + (Command) new RadioOptionWithSecondaryText((IModelItemOwner) this, Shell.LoadString(StringId.IDS_PHONE_WELCOME_CONFIG_HEADER), Shell.LoadString(StringId.IDS_PHONE_WELCOME_CONFIG_TEXT)) + }; + this._welcomeOptionsChoice.Clear(); + this._welcomeOptionsChoice.ChosenChanged += (EventHandler)((sender, args) => ((FirstLaunchForPhoneWizard)this._owner).IsSoftwareSettingsEnabled = this._welcomeOptionsChoice.ChosenIndex == 1); + } + return this._welcomeOptionsChoice; + } + } + + internal override bool OnMovingNext() + { + if (this._welcomeOptionsChoice.ChosenIndex == 1) + Fue.Instance.ProxyDefaultPaths(); + return base.OnMovingNext(); + } + } +} diff --git a/ZuneUI/FirstLaunchForPhoneWizard.cs b/ZuneUI/FirstLaunchForPhoneWizard.cs new file mode 100644 index 0000000..78653ef --- /dev/null +++ b/ZuneUI/FirstLaunchForPhoneWizard.cs @@ -0,0 +1,82 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchForPhoneWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Configuration; + +namespace ZuneUI +{ + public class FirstLaunchForPhoneWizard : DeviceUpdateWizard + { + private bool _isSoftwareSettingsEnabled = true; + private bool _wasPreviouslyNotPaired; + + public FirstLaunchForPhoneWizard() + { + this._wasPreviouslyNotPaired = ZuneShell.DefaultInstance.Management.DeviceManagement.DevicePartnership == DeviceRelationship.None; + ZuneShell.DefaultInstance.Management.DeviceManagement.DevicePartnership = DeviceRelationship.Permanent; + } + + protected override void AddPages() + { + this.AddPage((WizardPage)new FirstConnectPhoneIntroPage((Wizard)this), Shell.LoadString(StringId.IDS_BREADCRUMB_INTRODUCTION)); + this.AddPage((WizardPage)new FirstLaunchForPhoneWelcomePage((Wizard)this), Shell.LoadString(StringId.IDS_BREADCRUMB_SOFTWARE_SETTINGS)); + this.AddPage((WizardPage)new FirstLaunchMonitoredFoldersPage((Wizard)this)); + this.AddPage((WizardPage)new FirstLaunchDownloadFoldersPage((Wizard)this)); + this.AddPage((WizardPage)new FirstLaunchFileTypesPage((Wizard)this)); + this.AddPage((WizardPage)new FirstLaunchPrivacyPage((Wizard)this)); + this.AddPage((WizardPage)new FirstConnectDeviceNamePage((Wizard)this), Shell.LoadString(StringId.IDS_BREADCRUMB_PHONE_NAME)); + this.AddPage((WizardPage)new DeviceUpdateCheckingPage((DeviceUpdateWizard)this), Shell.LoadString(StringId.IDS_BREADCRUMB_PHONE_UPDATE)); + this.AddPage((WizardPage)new DeviceUpdateEULAPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateBatteryPowerPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateGuestWarningPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateSyncingPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateDiskSpaceErrorPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateProgressPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateSummaryPage((DeviceUpdateWizard)this)); + this.AddPage((WizardPage)new DeviceUpdateErrorPage((DeviceUpdateWizard)this)); + } + + public bool IsSoftwareSettingsEnabled + { + get => this._isSoftwareSettingsEnabled; + set + { + if (this._isSoftwareSettingsEnabled == value) + return; + this._isSoftwareSettingsEnabled = value; + this.FirePropertyChanged(nameof(IsSoftwareSettingsEnabled)); + } + } + + public override bool CanCommitChanges => this.IsValid && (this.CurrentPage is DeviceUpdateCheckingPage && this.ActiveDevice.UIFirmwareUpdater != null && !this.ActiveDevice.UIFirmwareUpdater.IsUpdateAvailable || (!this.CanAdvancePageIndex || this.CurrentPage is FirstLaunchWelcomePage || this.CurrentPage is FirstConnectDeviceNamePage)); + + protected override bool OnCommitChanges() + { + bool navigateToLandingPage = this._wasPreviouslyNotPaired && !(this.CurrentPage is FirstConnectDeviceNamePage); + if (!this.IsSoftwareSettingsEnabled) + ClientConfiguration.FUE.AcceptedPrivacyStatement = true; + ZuneShell.DefaultInstance.Management.CommitListSave(); + ZuneShell.DefaultInstance.Management.DeviceManagement.SetupComplete(navigateToLandingPage); + if (navigateToLandingPage || this.CurrentPage is DeviceUpdatePage || this.CurrentPage is DeviceUpdateErrorPage) + { + Fue.Instance.MigrateLegacyConfiguration(); + Fue.Instance.CompleteFUE(); + if (!this.ActiveDevice.AllowChainedUpdates) + { + Shell.MainFrame.Device.Invoke(); + } + else + { + this.ActiveDevice.NavigateToDeviceSummaryAfterUpdate = true; + this.ActiveDevice.UIFirmwareUpdater.StartCheckForUpdates(false, true); + } + } + return base.OnCommitChanges(); + } + + public bool RequiredStepsComplete => this.CurrentPage is DeviceUpdatePage || this.CurrentPage is DeviceUpdateErrorPage; + } +} diff --git a/ZuneUI/FirstLaunchLandPage.cs b/ZuneUI/FirstLaunchLandPage.cs new file mode 100644 index 0000000..533fb79 --- /dev/null +++ b/ZuneUI/FirstLaunchLandPage.cs @@ -0,0 +1,188 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchLandPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.IO; +using ZuneXml; + +namespace ZuneUI +{ + public class FirstLaunchLandPage : SetupLandPage + { + private Timer _deviceArrivalTimer; + private int _deviceArrivalTimerInterval = 10000; + private bool _phoneDisconnected; + private static string _commonAppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), ZuneUI.Shell.LoadString(StringId.IDS_APPDATAFOLDERNAME).TrimStart('\\')); + private static string _customFirstLaunchMovieUri = ClientConfiguration.FUE.FirstLaunchVideo; + private bool _playbackFailed; + private FirstLaunchWizardType _wizardType = FirstLaunchWizardType.Undefined; + + public FirstLaunchLandPage() + { + this.UI = "res://ZuneShellResources!SetupLand.uix#FirstLaunch"; + if (Fue.Instance.AutoFUE) + this.BackgroundUI = "res://ZuneShellResources!SetupLand.uix#SetupLandBackground"; + else if (FeatureEnablement.IsFeatureEnabled(Features.eFirstLaunchIntroVideo)) + this.BackgroundUI = "res://ZuneShellResources!SetupLand.uix#FirstLaunchBackground"; + else + this.BackgroundUI = "res://ZuneShellResources!SetupLand.uix#FirstLaunchNoVideoBackground"; + } + + protected override void SetConnectionRule() => SingletonModelItem.Instance.AllowDeviceConnections = true; + + protected override void OnDispose(bool disposing) + { + SingletonModelItem.Instance.DeviceDisconnectedEvent -= new DeviceListEventHandler(this.OnDeviceDisconnected); + base.OnDispose(disposing); + } + + public void WaitForPhoneArrival() + { + UIDevice connectedPhone = this.FindConnectedPhone(); + if (connectedPhone == UIDeviceList.NullDevice) + { + if (this._deviceArrivalTimer == null) + { + this._deviceArrivalTimer = new Timer(); + this._deviceArrivalTimer.Enabled = true; + this._deviceArrivalTimer.Tick += new EventHandler(this.OnDeviceConnectedTimeout); + this._deviceArrivalTimer.Interval = this._deviceArrivalTimerInterval; + } + SingletonModelItem.Instance.DeviceConnectedEvent += new DeviceListEventHandler(this.OnDeviceConnected); + } + else + this.ProcessPhoneForWizard(connectedPhone); + } + + private UIDevice FindConnectedPhone() + { + UIDevice uiDevice1 = UIDeviceList.NullDevice; + foreach (UIDevice uiDevice2 in SingletonModelItem.Instance) + { + if (uiDevice2.IsConnectedToClientPhysically && uiDevice2.Class == DeviceClass.WindowsPhone) + { + uiDevice1 = uiDevice2; + break; + } + } + return uiDevice1; + } + + private void OnDeviceConnected(object sender, DeviceListEventArgs args) + { + if (args.Device.Class != DeviceClass.WindowsPhone) + return; + this.ProcessPhoneForWizard(args.Device); + } + + private void OnDeviceDisconnected(object sender, DeviceListEventArgs args) + { + if (SyncControls.Instance.CurrentDeviceOverride != args.Device) + return; + this.PhoneDisconnected = true; + } + + private void OnDeviceConnectedTimeout(object sender, EventArgs args) => this.ProcessPhoneForWizard(UIDeviceList.NullDevice); + + private void ProcessPhoneForWizard(UIDevice device) + { + if (this._deviceArrivalTimer != null) + this._deviceArrivalTimer.Stop(); + SingletonModelItem.Instance.DeviceConnectedEvent -= new DeviceListEventHandler(this.OnDeviceConnected); + SingletonModelItem.Instance.AllowDeviceConnections = false; + if (device.Class == DeviceClass.WindowsPhone && device.Relationship == DeviceRelationship.None && !device.RequiresAutoRestore) + { + if (device.SupportsOOBECompleted && !device.OOBECompleted) + { + SingletonModelItem.Instance.HideDevice(device); + DeviceManagement.ShowDeviceOOBEIncompleteDialog(); + this.WizardType = FirstLaunchWizardType.Standard; + } + else + { + SingletonModelItem.Instance.DeviceDisconnectedEvent += new DeviceListEventHandler(this.OnDeviceDisconnected); + this.WizardType = FirstLaunchWizardType.PhoneFirstConnect; + } + } + else + this.WizardType = FirstLaunchWizardType.Standard; + } + + public FirstLaunchWizardType WizardType + { + get => this._wizardType; + set + { + if (this._wizardType == value) + return; + this._wizardType = value; + this.FirePropertyChanged(nameof(WizardType)); + } + } + + public bool PhoneDisconnected + { + get => this._phoneDisconnected; + set + { + if (this._phoneDisconnected == value) + return; + this._phoneDisconnected = value; + this.FirePropertyChanged(nameof(PhoneDisconnected)); + } + } + + public void InvokePlayback() + { + string str = string.Empty; + if (!string.IsNullOrEmpty(FirstLaunchLandPage._customFirstLaunchMovieUri)) + str = FirstLaunchLandPage._customFirstLaunchMovieUri; + else + this.PlaybackFailed = true; + if (!string.IsNullOrEmpty(str)) + { + Uri uri = new Uri(str); + PlaybackTrack playbackTrack = (PlaybackTrack)null; + if (uri.IsLoopback) + { + if (this.VideoExists(str)) + { + int mediaId = ZuneApplication.ZuneLibrary.AddMedia(str); + if (mediaId != -1) + playbackTrack = (PlaybackTrack)new LibraryPlaybackTrack(mediaId, MediaType.Video, (ContainerPlayMarker)null); + } + else + this.PlaybackFailed = true; + } + else + playbackTrack = (PlaybackTrack)new VideoPlaybackTrack(Guid.Empty, "", (string)null, str, false, true, false, false, false, VideoDefinitionEnum.HD); + if (playbackTrack == null) + return; + SingletonModelItem.Instance.PlayItem((object)playbackTrack, PlayNavigationOptions.None); + } + else + this.PlaybackFailed = true; + } + + public bool PlaybackFailed + { + get => this._playbackFailed; + set + { + if (this._playbackFailed == value) + return; + this._playbackFailed = value; + this.FirePropertyChanged(nameof(PlaybackFailed)); + } + } + + private bool VideoExists(string uri) => !string.IsNullOrEmpty(uri) && File.Exists(uri); + } +} diff --git a/ZuneUI/FirstLaunchMonitoredFoldersPage.cs b/ZuneUI/FirstLaunchMonitoredFoldersPage.cs new file mode 100644 index 0000000..f0592e7 --- /dev/null +++ b/ZuneUI/FirstLaunchMonitoredFoldersPage.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchMonitoredFoldersPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class FirstLaunchMonitoredFoldersPage : FirstLaunchSoftwareSettingBase + { + private bool _activated; + + internal FirstLaunchMonitoredFoldersPage(Wizard wizard) + : base(wizard) + { + this.Description = Shell.LoadString(StringId.IDS_CHOOSE_MEDIA_LOCATIONS); + this.EnableVerticalScrolling = true; + } + + public override string UI => "res://ZuneShellResources!FirstLaunch.uix#FirstLaunchMonitoredFoldersPage"; + + internal override void Activate() + { + if (!this._activated) + { + this._activated = true; + ZuneShell.DefaultInstance.Management.MediaInfoChoice.Value = FeatureEnablement.IsFeatureEnabled(Features.eOptIn); + } + base.Activate(); + } + } +} diff --git a/ZuneUI/FirstLaunchPrivacyPage.cs b/ZuneUI/FirstLaunchPrivacyPage.cs new file mode 100644 index 0000000..1b5f1ed --- /dev/null +++ b/ZuneUI/FirstLaunchPrivacyPage.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchPrivacyPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class FirstLaunchPrivacyPage : FirstLaunchSoftwareSettingBase + { + private bool _activated; + + internal FirstLaunchPrivacyPage(Wizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_CHANGE_PRIVACY_SETTINGS); + + public override string UI => "res://ZuneShellResources!FirstLaunch.uix#FirstLaunchPrivacyPage"; + + internal override void Activate() + { + if (!this._activated) + { + this._activated = true; + ZuneShell.DefaultInstance.Management.SqmChoice.Value = FeatureEnablement.IsFeatureEnabled(Features.eOptIn); + } + base.Activate(); + } + } +} diff --git a/ZuneUI/FirstLaunchSoftwareSettingBase.cs b/ZuneUI/FirstLaunchSoftwareSettingBase.cs new file mode 100644 index 0000000..3396e10 --- /dev/null +++ b/ZuneUI/FirstLaunchSoftwareSettingBase.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchSoftwareSettingBase +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class FirstLaunchSoftwareSettingBase : WizardPage + { + internal FirstLaunchSoftwareSettingBase(Wizard wizard) + : base(wizard) + { + } + + public override bool IsEnabled => !(this._owner is FirstLaunchForPhoneWizard) || ((FirstLaunchForPhoneWizard)this._owner).IsSoftwareSettingsEnabled; + } +} diff --git a/ZuneUI/FirstLaunchWelcomePage.cs b/ZuneUI/FirstLaunchWelcomePage.cs new file mode 100644 index 0000000..f33ef3e --- /dev/null +++ b/ZuneUI/FirstLaunchWelcomePage.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchWelcomePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FirstLaunchWelcomePage : WizardPage + { + internal FirstLaunchWelcomePage(Wizard wizard) + : base(wizard) + { + this.Description = Shell.LoadString(StringId.IDS_FIRSTRUN_GREETING); + this.EnableVerticalScrolling = true; + } + + public override bool ShowNavigation => false; + + public override bool CanCancel => false; + + public override string UI => "res://ZuneShellResources!FirstLaunch.uix#FirstLaunchWelcomePage"; + } +} diff --git a/ZuneUI/FirstLaunchWizard.cs b/ZuneUI/FirstLaunchWizard.cs new file mode 100644 index 0000000..6e46d0d --- /dev/null +++ b/ZuneUI/FirstLaunchWizard.cs @@ -0,0 +1,48 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class FirstLaunchWizard : Wizard + { + public FirstLaunchWizard() + { + this.AddPage((WizardPage)new FirstLaunchWelcomePage((Wizard)this)); + this.AddPage((WizardPage)new FirstLaunchMonitoredFoldersPage((Wizard)this)); + this.AddPage((WizardPage)new FirstLaunchDownloadFoldersPage((Wizard)this)); + this.AddPage((WizardPage)new FirstLaunchFileTypesPage((Wizard)this)); + this.AddPage((WizardPage)new FirstLaunchPrivacyPage((Wizard)this)); + } + + public override bool CanCommitChanges + { + get + { + if (!this.IsValid) + return false; + return !this.CanAdvancePageIndex || this.CurrentPage is FirstLaunchWelcomePage; + } + } + + protected override bool OnCommitChanges() + { + if (this.CurrentPage is FirstLaunchWelcomePage) + { + ZuneShell.DefaultInstance.Management.MediaInfoChoice.Value = true; + ZuneShell.DefaultInstance.Management.SqmChoice.Value = true; + SQMLog.Log(SQMDataId.UserConfiguredSettingsFUE, 0); + } + else + SQMLog.Log(SQMDataId.UserConfiguredSettingsFUE, 1); + ZuneShell.DefaultInstance.Management.CommitListSave(); + Fue.Instance.MigrateLegacyConfiguration(); + Fue.Instance.CompleteFUE(); + return base.OnCommitChanges(); + } + } +} diff --git a/ZuneUI/FirstLaunchWizardSettings.cs b/ZuneUI/FirstLaunchWizardSettings.cs new file mode 100644 index 0000000..611fff1 --- /dev/null +++ b/ZuneUI/FirstLaunchWizardSettings.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchWizardSettings +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum FirstLaunchWizardSettings + { + Default, + Config, + } +} diff --git a/ZuneUI/FirstLaunchWizardType.cs b/ZuneUI/FirstLaunchWizardType.cs new file mode 100644 index 0000000..2fd3de1 --- /dev/null +++ b/ZuneUI/FirstLaunchWizardType.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FirstLaunchWizardType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum FirstLaunchWizardType + { + Undefined = -1, // 0xFFFFFFFF + Standard = 0, + PhoneFirstConnect = 1, + } +} diff --git a/ZuneUI/FloatHelper.cs b/ZuneUI/FloatHelper.cs new file mode 100644 index 0000000..c55008b --- /dev/null +++ b/ZuneUI/FloatHelper.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FloatHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class FloatHelper + { + public static int Round(float val) => (int)Math.Round((double)val); + } +} diff --git a/ZuneUI/FolderBrowseDialog.cs b/ZuneUI/FolderBrowseDialog.cs new file mode 100644 index 0000000..0aaa3a9 --- /dev/null +++ b/ZuneUI/FolderBrowseDialog.cs @@ -0,0 +1,141 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FolderBrowseDialog +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; + +namespace ZuneUI +{ + public static class FolderBrowseDialog + { + private const int BIF_RETURNONLYFSDIRS = 1; + private const int BIF_EDITBOX = 16; + private const int BIF_NEWDIALOGSTYLE = 64; + private const int BIF_VALIDATE = 32; + private const int BFFM_INITIALIZED = 1; + private const int BFFM_SELCHANGED = 2; + private const int BFFM_VALIDATEFAILED = 4; + private const int BFFM_ENABLEOK = 1125; + private const int MAX_PATH = 260; + private static readonly IntPtr NoValidation = IntPtr.Zero; + private static readonly IntPtr ValidateWritable = new IntPtr(1); + + public static void Show(string title, DeferredInvokeHandler callback) => FolderBrowseDialog.Show(title, callback, false); + + public static void Show(string title, DeferredInvokeHandler callback, bool validate) + { + IntPtr winHandle = Application.Window.Handle; + Thread thread = new Thread((ParameterizedThreadStart)(args => + { + FolderBrowseDialog.BROWSEINFO bi = new FolderBrowseDialog.BROWSEINFO(); + bi.hwndOwner = winHandle; + bi.pidlRoot = IntPtr.Zero; + bi.pszDisplayName = new string(' ', 261); + if (!string.IsNullOrEmpty(title)) + bi.pszTitle = title; + bi.ulFlags = 112U; + bi.lpfn = new FolderBrowseDialog.BFFCALLBACK(FolderBrowseDialog.Validate); + bi.lParam = validate ? FolderBrowseDialog.ValidateWritable : FolderBrowseDialog.NoValidation; + bi.iImage = 0; + IntPtr num = FolderBrowseDialog.SHBrowseForFolder(ref bi); + string str = (string)null; + if (num != IntPtr.Zero) + { + StringBuilder Path = new StringBuilder(261); + if (FolderBrowseDialog.SHGetPathFromIDList(num, Path) != 0) + str = Path.ToString(); + } + Marshal.FreeCoTaskMem(num); + Application.DeferredInvoke(callback, (object)str); + })); + thread.TrySetApartmentState(ApartmentState.STA); + thread.Start(); + } + + private static int Validate(IntPtr hwnd, uint uMsg, IntPtr lParam, IntPtr lpData) + { + switch (uMsg) + { + case 2: + if (lpData == FolderBrowseDialog.ValidateWritable) + { + bool lParam1 = false; + StringBuilder Path = new StringBuilder(260); + if (FolderBrowseDialog.SHGetPathFromIDList(lParam, Path) != 0) + lParam1 = FolderBrowseDialog.CanWriteToFolder(Path.ToString()); + FolderBrowseDialog.SendMessage(hwnd, 1125, 0, lParam1); + break; + } + break; + case 4: + return 1; + } + return 0; + } + + public static bool CanWriteToFolder(string folder) + { + try + { + string pathRoot = Path.GetPathRoot(folder); + if (pathRoot.Length == 1 || pathRoot.Length >= 2 && (int)pathRoot[1] == (int)Path.VolumeSeparatorChar) + { + DriveInfo driveInfo = new DriveInfo(pathRoot); + if (driveInfo.DriveType == DriveType.CDRom || driveInfo.DriveType == DriveType.Removable) + return false; + } + StringBuilder tmpFileName = new StringBuilder(260); + if (FolderBrowseDialog.GetTempFileName(folder, "tmp", 0U, tmpFileName) == 0U) + return false; + using (FileStream fileStream = File.Create(tmpFileName.ToString(), 2, FileOptions.DeleteOnClose)) + fileStream.WriteByte((byte)65); + return true; + } + catch (Exception ex) + { + return false; + } + } + + [DllImport("Shell32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr SHBrowseForFolder(ref FolderBrowseDialog.BROWSEINFO bi); + + [DllImport("Shell32.dll", CharSet = CharSet.Auto)] + private static extern int SHGetPathFromIDList(IntPtr pidl, [Out] StringBuilder Path); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, bool lParam); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto)] + internal static extern uint GetTempFileName( + string tmpPath, + string prefix, + uint uniqueIdOrZero, + StringBuilder tmpFileName); + + private delegate int BFFCALLBACK(IntPtr hwnd, uint uMsg, IntPtr lParam, IntPtr lpData); + + [StructLayout(LayoutKind.Sequential, Pack = 8)] + private struct BROWSEINFO + { + public IntPtr hwndOwner; + public IntPtr pidlRoot; + [MarshalAs(UnmanagedType.LPTStr)] + public string pszDisplayName; + [MarshalAs(UnmanagedType.LPTStr)] + public string pszTitle; + public uint ulFlags; + [MarshalAs(UnmanagedType.FunctionPtr)] + public FolderBrowseDialog.BFFCALLBACK lpfn; + public IntPtr lParam; + public int iImage; + } + } +} diff --git a/ZuneUI/FontLoader.cs b/ZuneUI/FontLoader.cs new file mode 100644 index 0000000..8864777 --- /dev/null +++ b/ZuneUI/FontLoader.cs @@ -0,0 +1,62 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FontLoader +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune; +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class FontLoader + { + private List _fonts; + private string _resourceDll; + private bool _loaded; + private bool _loadQueued; + + public List Fonts + { + get => this._fonts; + set + { + this._fonts = value; + this.QueueFontLoading(); + } + } + + public string Resource + { + set + { + this._resourceDll = value; + this.QueueFontLoading(); + } + } + + private void QueueFontLoading() + { + if (this._loaded) + throw new InvalidOperationException("This is a one trick pony, sorry."); + if (this._loadQueued) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.LoadFonts), (object)null); + this._loadQueued = true; + } + + private void LoadFonts(object args) + { + this._loadQueued = false; + if (this._fonts == null || this._fonts.Count == 0) + return; + if (this._resourceDll == null) + throw new InvalidOperationException("Must specify a Resource to retrieve the fonts from."); + foreach (string font in this._fonts) + MemoryFonts.TryLoadFromResource(this._resourceDll, font); + this._loaded = true; + } + } +} diff --git a/ZuneUI/FormatCompletionListener.cs b/ZuneUI/FormatCompletionListener.cs new file mode 100644 index 0000000..8ce5109 --- /dev/null +++ b/ZuneUI/FormatCompletionListener.cs @@ -0,0 +1,74 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FormatCompletionListener +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.ComponentModel; + +namespace ZuneUI +{ + public class FormatCompletionListener : ModelItem + { + private Command _completed; + private UIDevice _device; + + public FormatCompletionListener() + { + this._completed = new Command((IModelItemOwner)this); + SyncControls.Instance.PropertyChanged += new PropertyChangedEventHandler(this.OnDeviceChanged); + this._device = SyncControls.Instance.CurrentDevice; + this.SetCurrentDevice(); + } + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing || !this._device.IsValid) + return; + this._device.FormatCompletedEvent -= new FallibleEventHandler(this.FormatCompleted); + } + + private void SetCurrentDevice() + { + if (this._device.IsValid) + this._device.FormatCompletedEvent -= new FallibleEventHandler(this.FormatCompleted); + this._device = SyncControls.Instance.CurrentDevice; + if (!this._device.IsValid) + return; + this._device.FormatCompletedEvent += new FallibleEventHandler(this.FormatCompleted); + } + + private void FormatCompleted(object sender, FallibleEventArgs args) + { + if (this._device.IsConnectedToClient) + { + this._device.EnumeratedEvent -= new FallibleEventHandler(this.EnumerationCompleted); + this._device.EnumeratedEvent += new FallibleEventHandler(this.EnumerationCompleted); + this._device.Enumerate(); + } + else + this.FinishFormat(HRESULT._S_OK); + } + + private void EnumerationCompleted(object sender, FallibleEventArgs args) => this.FinishFormat(args.HR); + + private void FinishFormat(HRESULT hResult) + { + this._device.EnumeratedEvent -= new FallibleEventHandler(this.EnumerationCompleted); + this.Completed.Invoke(); + } + + private void OnDeviceChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "CurrentDevice")) + return; + this.SetCurrentDevice(); + } + + public bool IsFormatting => this._device.IsFormatting; + + public Command Completed => this._completed; + } +} diff --git a/ZuneUI/Frame.cs b/ZuneUI/Frame.cs new file mode 100644 index 0000000..9c40d23 --- /dev/null +++ b/ZuneUI/Frame.cs @@ -0,0 +1,61 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Frame +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public abstract class Frame : ModelItem + { + private bool _isCurrent; + private Choice _experiences; + + public Frame(IModelItemOwner owner) + : base(owner) + { + } + + public Choice Experiences + { + get + { + if (this._experiences == null) + { + this._experiences = new Choice((IModelItemOwner)this); + this._experiences.Options = this.ExperiencesList; + } + return this._experiences; + } + set + { + if (this._experiences == value) + return; + this._experiences = value; + this.FirePropertyChanged(nameof(Experiences)); + } + } + + public abstract IList ExperiencesList { get; } + + public bool IsCurrent + { + get => this._isCurrent; + set + { + if (this._isCurrent == value) + return; + this._isCurrent = value; + this.OnIsCurrentChanged(); + this.FirePropertyChanged(nameof(IsCurrent)); + } + } + + protected virtual void OnIsCurrentChanged() + { + } + } +} diff --git a/ZuneUI/FriendRequestAttachment.cs b/ZuneUI/FriendRequestAttachment.cs new file mode 100644 index 0000000..0f8c84c --- /dev/null +++ b/ZuneUI/FriendRequestAttachment.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FriendRequestAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class FriendRequestAttachment : Attachment + { + public const string RequestTypeString = "friendrequest"; + + public FriendRequestAttachment() + : base(Guid.Empty, (string)null, (string)null, (string)null) + { + this.AttachmentUI = (string)null; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_FRIENDREQUEST_ATTACHMENT); + } + + public override MediaType MediaType => MediaType.Undefined; + + public override string RequestType => "friendrequest"; + } +} diff --git a/ZuneUI/FriendsHelper.cs b/ZuneUI/FriendsHelper.cs new file mode 100644 index 0000000..3c46dd9 --- /dev/null +++ b/ZuneUI/FriendsHelper.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FriendsHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Subscription; +using System; + +namespace ZuneUI +{ + public class FriendsHelper : ModelItem + { + private bool m_refreshCompleted; + + public FriendsHelper() => this.StartListening(); + + protected override void OnDispose(bool disposing) + { + if (disposing) + this.StopListening(); + base.OnDispose(disposing); + } + + public bool RefreshCompleted + { + get => this.m_refreshCompleted; + private set + { + if (this.m_refreshCompleted == value) + return; + this.m_refreshCompleted = value; + this.FirePropertyChanged(nameof(RefreshCompleted)); + } + } + + public void Refresh(Guid userGuid, string feedUri) + { + if (userGuid != Guid.Empty && SignIn.Instance.LastSignedInUserGuid == userGuid) + this.RefreshCompleted = new HRESULT(SubscriptionManager.Instance.Refresh(SignIn.Instance.LastSignedInUserId, EMediaTypes.eMediaTypeUser, false)).IsError; + else + this.RefreshCompleted = true; + } + + private void StartListening() => SubscriptionManager.Instance.OnForegroundSubscriptionChanged += new SubscriptionEventHandler(this.OnForegroundSubscriptionChanged); + + private void StopListening() => SubscriptionManager.Instance.OnForegroundSubscriptionChanged -= new SubscriptionEventHandler(this.OnForegroundSubscriptionChanged); + + private void OnForegroundSubscriptionChanged(SubscriptonEventArguments args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredOnForegroundSubscriptionChanged), (object)args, DeferredInvokePriority.Normal); + + private void DeferredOnForegroundSubscriptionChanged(object args) + { + SubscriptonEventArguments subscriptonEventArguments = (SubscriptonEventArguments)args; + if (subscriptonEventArguments.Action != SubscriptionAction.RefreshFinished || subscriptonEventArguments.MediaType != EMediaTypes.eMediaTypeUser || subscriptonEventArguments.UserInitiated) + return; + this.RefreshCompleted = true; + } + } +} diff --git a/ZuneUI/FriendsNavigationCommandHandler.cs b/ZuneUI/FriendsNavigationCommandHandler.cs new file mode 100644 index 0000000..98bdc63 --- /dev/null +++ b/ZuneUI/FriendsNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FriendsNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class FriendsNavigationCommandHandler : DeviceAwareNavigationHandler + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)FriendsPage.CreateInstance(this.ShowDeviceContents); + } +} diff --git a/ZuneUI/FriendsPage.cs b/ZuneUI/FriendsPage.cs new file mode 100644 index 0000000..dacb9ef --- /dev/null +++ b/ZuneUI/FriendsPage.cs @@ -0,0 +1,79 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FriendsPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class FriendsPage : LibraryPage + { + public static readonly string FriendsPageTemplate = "res://ZuneShellResources!Friends.uix#FriendLibrary"; + private FriendsPanel _friendsPanel; + private string _selectedZuneTag; + + public static FriendsPage CreateInstance() => new FriendsPage(false); + + public static FriendsPage CreateInstance(bool showDevice) => new FriendsPage(showDevice); + + public FriendsPage(bool showDevice) + : base(showDevice, MediaType.UserCard) + { + if (showDevice) + { + Deviceland.InitDevicePage((ZunePage)this); + this.PivotPreference = Shell.MainFrame.Device.Friends; + this.ShowComputerIcon = ComputerIconState.Show; + } + else + this.PivotPreference = Shell.MainFrame.Social.Friends; + this.TransportControlStyle = TransportControlStyle.Music; + this.PlaybackContext = PlaybackContext.Music; + this.IsRootPage = true; + this.UI = FriendsPage.FriendsPageTemplate; + this.UIPath = "Social\\Friends"; + this._friendsPanel = new FriendsPanel(this); + } + + public override void InvokeSettings() + { + if (Shell.MainFrame.Device.IsCurrent) + Shell.SettingsFrame.Settings.Device.Invoke(); + else + Shell.SettingsFrame.Settings.Account.Invoke(); + } + + public FriendsPanel FriendsPanel => this._friendsPanel; + + public string SelectedZuneTag + { + get => this._selectedZuneTag; + set + { + if (!(this._selectedZuneTag != value)) + return; + this._selectedZuneTag = value; + this.FirePropertyChanged(nameof(SelectedZuneTag)); + } + } + + public string ZuneTag + { + get + { + string str = (string)null; + if (!this.ShowDeviceContents) + str = SignIn.Instance.ZuneTag; + else if (SyncControls.Instance.CurrentDevice.IsValid) + str = SyncControls.Instance.CurrentDevice.ZuneTag; + return str; + } + } + + public override IPageState SaveAndRelease() + { + this._friendsPanel.Release(); + return base.SaveAndRelease(); + } + } +} diff --git a/ZuneUI/FriendsPanel.cs b/ZuneUI/FriendsPanel.cs new file mode 100644 index 0000000..1427b64 --- /dev/null +++ b/ZuneUI/FriendsPanel.cs @@ -0,0 +1,38 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FriendsPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class FriendsPanel : ListPanel + { + internal FriendsPanel(FriendsPage page) + : base((IModelItemOwner)page) + { + } + + public int GetIndexFromZuneTag(string tagToFind) + { + int num1 = -1; + int num2 = 0; + if (this.Content != null && !string.IsNullOrEmpty(tagToFind)) + { + foreach (object data in (IEnumerable)this.Content) + { + if (ProfileCardData.GetDataProviderObject(data) is DataProviderObject dataProviderObject && SignIn.TagsMatch(dataProviderObject.GetProperty("ZuneTag") as string, tagToFind)) + { + num1 = num2; + break; + } + ++num2; + } + } + return num1; + } + } +} diff --git a/ZuneUI/Fue.cs b/ZuneUI/Fue.cs new file mode 100644 index 0000000..6319ff2 --- /dev/null +++ b/ZuneUI/Fue.cs @@ -0,0 +1,246 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Fue +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class Fue : ModelItem + { + private const int RenderPromptIntervalInitValue = 120000; + private const int RenderPromptIntervalPostValue = 120000; + private bool _proxyDefaultPathsComplete; + private bool _autoFUE; + private string errorMessage; + private static Fue singletonInstance; + private bool fileTypeAssociationsAreSet; + private int _renderPromptInterval = 120000; + private Timer _renderPromptTimer; + + public static Fue Instance + { + get + { + if (Fue.singletonInstance == null) + Fue.singletonInstance = new Fue(); + return Fue.singletonInstance; + } + } + + public bool IsFirstLaunch + { + get + { + bool flag = ClientConfiguration.FUE.ShowFirstLaunchVideo && FeatureEnablement.IsFeatureEnabled(Features.eFirstLaunchIntroVideo); + return ClientConfiguration.FUE.ShowFUE || flag; + } + } + + public string ErrorMessage + { + get => this.errorMessage; + set + { + this.errorMessage = value; + ZuneUI.Shell.ShowErrorDialog(0, this.errorMessage); + } + } + + public static event EventHandler FUECompleted; + + private Fue() + { + } + + public void StartJobs() + { + this.InitializeDefaultPaths(); + this.UpdateNSS(); + } + + public bool AutoFUE + { + get => this._autoFUE; + set => this._autoFUE = value; + } + + public void MigrateLegacyConfiguration() => ClientConfiguration.FUE.SettingsVersion = ZuneApplication.ZuneCurrentSettingsVersion; + + public void SetFileTypeAssociationsAreSet() => this.fileTypeAssociationsAreSet = true; + + public void InitializeQuickplayConfig() + { + if (!FeatureEnablement.IsFeatureEnabled(Features.eQuickplay)) + return; + ClientConfiguration.Shell.StartupPage = ZuneUI.Shell.MainFrame.Quickplay.DefaultUIPath; + ClientConfiguration.Quickplay.ShowFUE = true; + ClientConfiguration.Quickplay.CheckUseCount = true; + ClientConfiguration.Quickplay.UnusedCount = 0; + ClientConfiguration.Quickplay.FavoredExperience = ""; + } + + public void CompleteFUE() + { + ClientConfiguration.FUE.ShowFUE = false; + ClientConfiguration.FUE.ShowArtistChooser = FeatureEnablement.IsFeatureEnabled(Features.eQuickMixLocal) && (FeatureEnablement.IsFeatureEnabled(Features.eQuickplay) || FeatureEnablement.IsFeatureEnabled(Features.ePicks)); + this.InitializeQuickplayConfig(); + if (!this.fileTypeAssociationsAreSet) + ZuneShell.DefaultInstance.Management.SaveFileTypesAsDefault(); + ZuneShell.DefaultInstance.NavigateBack(); + SQMLog.LogToStream(SQMDataId.LanguageLocale, ZuneUI.Shell.LoadString(StringId.IDS_ZUNECLIENT_LOCALE)); + SQMLog.Log(SQMDataId.DXModeEnabled, Application.RenderingType == RenderingType.DX9 ? 1 : 0); + ClientConfiguration.SQM.SQMLaunchIndex = 0; + this.StartJobs(); + if (Fue.FUECompleted == null) + return; + Fue.FUECompleted((object)Fue.Instance, EventArgs.Empty); + } + + public void CompleteMigration() + { + this.InitializeQuickplayConfig(); + ZuneShell.DefaultInstance.NavigateBack(); + if (Fue.FUECompleted == null) + return; + Fue.FUECompleted((object)Fue.Instance, EventArgs.Empty); + } + + public void ProxyDefaultPaths() + { + if (this._proxyDefaultPathsComplete) + return; + Management management = ZuneShell.DefaultInstance.Management; + string[] music; + string[] videos; + string[] pictures; + string[] podcasts; + string ripFolder; + string videoMediaFolder; + string photoMediaFolder; + string podcastMediaFolder; + HRESULT knownFolders = (HRESULT)ZuneApplication.ZuneLibrary.GetKnownFolders(out music, out videos, out pictures, out podcasts, out string[] _, out ripFolder, out videoMediaFolder, out photoMediaFolder, out podcastMediaFolder, out string _); + if (ClientConfiguration.Groveler.MonitoredAudioFolders == null) + { + for (int index = 0; index < music.Length; ++index) + management.MonitoredAudioFolders.Add((object)music[index]); + } + if (ClientConfiguration.Groveler.MonitoredPhotoFolders == null) + { + for (int index = 0; index < pictures.Length; ++index) + management.MonitoredPhotoFolders.Add((object)pictures[index]); + } + if (ClientConfiguration.Groveler.MonitoredVideoFolders == null) + { + for (int index = 0; index < videos.Length; ++index) + management.MonitoredVideoFolders.Add((object)videos[index]); + } + if (ClientConfiguration.Groveler.MonitoredPodcastFolders == null) + { + for (int index = 0; index < podcasts.Length; ++index) + management.MonitoredPodcastFolders.Add((object)podcasts[index]); + } + management.MediaFolder = string.IsNullOrEmpty(ClientConfiguration.Groveler.RipDirectory) ? ripFolder : ClientConfiguration.Groveler.RipDirectory; + management.VideoMediaFolder = string.IsNullOrEmpty(ClientConfiguration.Groveler.VideoMediaFolder) ? videoMediaFolder : ClientConfiguration.Groveler.VideoMediaFolder; + management.PhotoMediaFolder = string.IsNullOrEmpty(ClientConfiguration.Groveler.PhotoMediaFolder) ? photoMediaFolder : ClientConfiguration.Groveler.PhotoMediaFolder; + management.PodcastMediaFolder = string.IsNullOrEmpty(ClientConfiguration.Groveler.PodcastMediaFolder) ? podcastMediaFolder : ClientConfiguration.Groveler.PodcastMediaFolder; + management.SaveMonitoredFolders(false); + this._proxyDefaultPathsComplete = true; + } + + public void InitializeDefaultPaths() + { + string[] music; + string[] videos; + string[] pictures; + string[] podcasts; + string ripFolder; + string videoMediaFolder; + string photoMediaFolder; + string podcastMediaFolder; + HRESULT knownFolders = (HRESULT)ZuneApplication.ZuneLibrary.GetKnownFolders(out music, out videos, out pictures, out podcasts, out string[] _, out ripFolder, out videoMediaFolder, out photoMediaFolder, out podcastMediaFolder, out string _); + if (ClientConfiguration.Groveler.MonitoredAudioFolders == null) + ClientConfiguration.Groveler.MonitoredAudioFolders = (IList)music; + if (ClientConfiguration.Groveler.MonitoredPhotoFolders == null) + ClientConfiguration.Groveler.MonitoredPhotoFolders = (IList)pictures; + if (ClientConfiguration.Groveler.MonitoredVideoFolders == null) + ClientConfiguration.Groveler.MonitoredVideoFolders = (IList)videos; + if (ClientConfiguration.Groveler.MonitoredPodcastFolders == null) + ClientConfiguration.Groveler.MonitoredPodcastFolders = (IList)podcasts; + if (string.IsNullOrEmpty(ClientConfiguration.Groveler.RipDirectory) && !string.IsNullOrEmpty(ripFolder)) + ClientConfiguration.Groveler.RipDirectory = ripFolder; + if (string.IsNullOrEmpty(ClientConfiguration.Groveler.VideoMediaFolder) && !string.IsNullOrEmpty(videoMediaFolder)) + ClientConfiguration.Groveler.VideoMediaFolder = videoMediaFolder; + if (string.IsNullOrEmpty(ClientConfiguration.Groveler.PhotoMediaFolder) && !string.IsNullOrEmpty(photoMediaFolder)) + ClientConfiguration.Groveler.PhotoMediaFolder = photoMediaFolder; + if (!string.IsNullOrEmpty(ClientConfiguration.Groveler.PodcastMediaFolder) || string.IsNullOrEmpty(podcastMediaFolder)) + return; + ClientConfiguration.Groveler.PodcastMediaFolder = podcastMediaFolder; + } + + public void UpdateNSS() + { + HMESettings hmeSettings = new HMESettings(); + if (((HRESULT)hmeSettings.Init()).IsError || !hmeSettings.VelaSharingEnabled) + return; + hmeSettings.EnableSharingForUser(); + hmeSettings.SetSharingEnabledForMediaType(EMediaTypes.eMediaTypeAudio, true); + hmeSettings.SetSharingEnabledForMediaType(EMediaTypes.eMediaTypeImage, false); + hmeSettings.SetSharingEnabledForMediaType(EMediaTypes.eMediaTypeVideo, false); + } + + public int RenderPromptInterval + { + get => this._renderPromptInterval; + set + { + if (this._renderPromptInterval == value) + return; + this._renderPromptInterval = value; + this.FirePropertyChanged(nameof(RenderPromptInterval)); + } + } + + public Timer RenderPromptTimer + { + get + { + if (this._renderPromptTimer == null) + { + this._renderPromptTimer = new Timer((IModelItemOwner)this); + this._renderPromptTimer.Interval = this.RenderPromptInterval; + this._renderPromptTimer.AutoRepeat = false; + this._renderPromptTimer.Tick += new EventHandler(this.RenderPromptTimeout); + } + return this._renderPromptTimer; + } + } + + private void RenderPromptTimeout(object sender, EventArgs e) + { + if (Application.RenderingType == RenderingType.GDI) + return; + Win32MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_RENDER_PROMPT), ZuneUI.Shell.LoadString(StringId.IDS_RENDER_PROMPT_CAPTION), Win32MessageBoxType.MB_YESNO | Win32MessageBoxType.MB_ICONQUESTION, (DeferredInvokeHandler)(args => + { + switch ((int)args) + { + case 6: + this.RenderPromptInterval = 120000; + break; + case 7: + ClientConfiguration.GeneralSettings.RenderingType = 0; + Win32MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_RENDER_PROMPT_RESTART), ZuneUI.Shell.LoadString(StringId.IDS_RENDER_PROMPT_CAPTION), Win32MessageBoxType.MB_ICONASTERISK, (DeferredInvokeHandler)(args2 => Application.Window.Close())); + break; + } + })); + } + } +} diff --git a/ZuneUI/FutureBase`1.cs b/ZuneUI/FutureBase`1.cs new file mode 100644 index 0000000..6e0b2ac --- /dev/null +++ b/ZuneUI/FutureBase`1.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.FutureBase`1 +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class FutureBase + { + private T _value; + private bool _calculationPerformed; + + public T Value + { + get + { + if (!this._calculationPerformed) + { + this._value = this.CalculateValue(); + this._calculationPerformed = true; + } + return this._value; + } + } + + protected abstract T CalculateValue(); + } +} diff --git a/ZuneUI/GDILandPage.cs b/ZuneUI/GDILandPage.cs new file mode 100644 index 0000000..e9dd786 --- /dev/null +++ b/ZuneUI/GDILandPage.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.GDILandPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class GDILandPage : SetupLandPage + { + public GDILandPage() + { + this.UI = "res://ZuneShellResources!SetupLand.uix#GDIWarning"; + this.BackgroundUI = "res://ZuneShellResources!SetupLand.uix#SetupLandBackground"; + } + + protected override void SetConnectionRule() => SingletonModelItem.Instance.AllowDeviceConnections = true; + } +} diff --git a/ZuneUI/GenreMetadataHelper.cs b/ZuneUI/GenreMetadataHelper.cs new file mode 100644 index 0000000..65257de --- /dev/null +++ b/ZuneUI/GenreMetadataHelper.cs @@ -0,0 +1,73 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.GenreMetadataHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public static class GenreMetadataHelper + { + private static StringId[] s_movieGenreIds = new StringId[11] + { + StringId.IDS_VIDEO_GENRE_ACTION_ADVENTURE, + StringId.IDS_VIDEO_GENRE_COMEDY, + StringId.IDS_VIDEO_GENRE_DOCUMENTARY, + StringId.IDS_VIDEO_GENRE_DRAMA, + StringId.IDS_VIDEO_GENRE_FAMILY, + StringId.IDS_VIDEO_GENRE_FOREIGN_INDEPENDENT, + StringId.IDS_VIDEO_GENRE_HORROR, + StringId.IDS_VIDEO_GENRE_OTHER, + StringId.IDS_VIDEO_GENRE_ROMANCE, + StringId.IDS_VIDEO_GENRE_SCIFI_FANTASY, + StringId.IDS_VIDEO_GENRE_THRILLER_MYSTERY + }; + private static StringId[] s_tvGenreIds = new StringId[15] + { + StringId.IDS_VIDEO_GENRE_ACTION_ADVENTURE, + StringId.IDS_VIDEO_GENRE_ANIMATION, + StringId.IDS_VIDEO_GENRE_COMEDY, + StringId.IDS_VIDEO_GENRE_DOCUMENTARY_BIO, + StringId.IDS_VIDEO_GENRE_DRAMA, + StringId.IDS_VIDEO_GENRE_EDUCATIONAL, + StringId.IDS_VIDEO_GENRE_FAMILY_CHILDREN, + StringId.IDS_VIDEO_GENRE_MOVIES, + StringId.IDS_VIDEO_GENRE_MUSIC, + StringId.IDS_VIDEO_GENRE_NEWS, + StringId.IDS_VIDEO_GENRE_OTHER, + StringId.IDS_VIDEO_GENRE_REALITY_TV, + StringId.IDS_VIDEO_GENRE_SCIFI_FANTASY, + StringId.IDS_VIDEO_GENRE_SOAP, + StringId.IDS_VIDEO_GENRE_SPORTS + }; + private static StringId[] s_otherGenreIds = new StringId[3] + { + StringId.IDS_VIDEO_GENRE_CREATIONS, + StringId.IDS_VIDEO_GENRE_FAMILY_FRIENDS, + StringId.IDS_VIDEO_GENRE_OTHER + }; + private static List s_movieGenres; + private static List s_tvGenres; + private static List s_otherGenres; + + public static IList CannedTVGenres => (IList)GenreMetadataHelper.EnsureGenres(ref GenreMetadataHelper.s_tvGenres, GenreMetadataHelper.s_tvGenreIds); + + public static IList CannedMovieGenres => (IList)GenreMetadataHelper.EnsureGenres(ref GenreMetadataHelper.s_movieGenres, GenreMetadataHelper.s_movieGenreIds); + + public static IList CannedOtherGenres => (IList)GenreMetadataHelper.EnsureGenres(ref GenreMetadataHelper.s_otherGenres, GenreMetadataHelper.s_otherGenreIds); + + private static List EnsureGenres(ref List genres, StringId[] genreIds) + { + if (genres == null) + { + genres = new List(genreIds.Length); + foreach (StringId genreId in genreIds) + genres.Add(Shell.LoadString(genreId)); + } + return genres; + } + } +} diff --git a/ZuneUI/GenresPanel.cs b/ZuneUI/GenresPanel.cs new file mode 100644 index 0000000..5abc44f --- /dev/null +++ b/ZuneUI/GenresPanel.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.GenresPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class GenresPanel : MusicLibraryListPanelBase + { + internal GenresPanel(MusicLibraryPage libraryPage) + : base(libraryPage) + { + } + + public override MediaType MediaType => MediaType.Genre; + + public override IList SelectedLibraryIds + { + get => this.LibraryPage.SelectedGenreIds; + set => this.LibraryPage.SelectedGenreIds = value; + } + } +} diff --git a/ZuneUI/GetCartItemPropertyDelegate.cs b/ZuneUI/GetCartItemPropertyDelegate.cs new file mode 100644 index 0000000..65708d8 --- /dev/null +++ b/ZuneUI/GetCartItemPropertyDelegate.cs @@ -0,0 +1,10 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.GetCartItemPropertyDelegate +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal delegate string GetCartItemPropertyDelegate(CartItem item); +} diff --git a/ZuneUI/GetPageCallback.cs b/ZuneUI/GetPageCallback.cs new file mode 100644 index 0000000..8c7133b --- /dev/null +++ b/ZuneUI/GetPageCallback.cs @@ -0,0 +1,10 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.GetPageCallback +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public delegate ZunePage GetPageCallback(); +} diff --git a/ZuneUI/GuestSchemaSyncGroup.cs b/ZuneUI/GuestSchemaSyncGroup.cs new file mode 100644 index 0000000..2e439ef --- /dev/null +++ b/ZuneUI/GuestSchemaSyncGroup.cs @@ -0,0 +1,57 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.GuestSchemaSyncGroup +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class GuestSchemaSyncGroup : SchemaSyncGroup + { + private long _size; + private bool _active; + + public GuestSchemaSyncGroup(SyncGroupList list, long size) + : base(list, SyncCategory.Guest) + { + this._size = size; + this._active = true; + } + + public override long Size => this._size; + + public override int Count => 0; + + public override SyncGroupState State => SyncGroupState.Calculated; + + public override bool IsActive + { + get => this._active; + set + { + if (this._active == value) + return; + this._active = value; + this.FirePropertyChanged(nameof(IsActive)); + this.ParentList.GasGauge.HideGuestSpace = !this._active; + } + } + + public override bool IsVisible => true; + + public override void CommitChanges() + { + if (this._active) + return; + this.ParentList.Device.DeleteAllGuestContent(); + } + + public override void CancelChanges() + { + } + + public override void DataUpdated() + { + } + } +} diff --git a/ZuneUI/GuidHelper.cs b/ZuneUI/GuidHelper.cs new file mode 100644 index 0000000..8ba7022 --- /dev/null +++ b/ZuneUI/GuidHelper.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.GuidHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public static class GuidHelper + { + public static Guid CreateFromString(string value) + { + if (string.IsNullOrEmpty(value)) + return Guid.Empty; + Guid guid = Guid.Empty; + try + { + guid = new Guid(value); + } + catch (Exception ex) + { + } + return guid; + } + + public static bool IsEmpty(Guid guid) => guid == Guid.Empty; + + public static Guid Empty => Guid.Empty; + } +} diff --git a/ZuneUI/HelpCommandHandler.cs b/ZuneUI/HelpCommandHandler.cs new file mode 100644 index 0000000..20e7393 --- /dev/null +++ b/ZuneUI/HelpCommandHandler.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.HelpCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Win32; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System.Collections; + +namespace ZuneUI +{ + public class HelpCommandHandler : ICommandHandler + { + public void Execute(string command, IDictionary commandArgs) => ZuneApplication.Service.LaunchBrowserForExternalUrl((string)Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Zune").GetValue("Installation Directory") + command, EPassportPolicyId.None); + } +} diff --git a/ZuneUI/HipPassportStep.cs b/ZuneUI/HipPassportStep.cs new file mode 100644 index 0000000..42a89c5 --- /dev/null +++ b/ZuneUI/HipPassportStep.cs @@ -0,0 +1,116 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.HipPassportStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.ErrorMapperApi; +using Microsoft.Zune.Service; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class HipPassportStep : AccountManagementStep + { + private bool _firstView; + private WinLiveInformation _winLiveHip; + private Dictionary _errorMappings; + + public HipPassportStep(Wizard owner, AccountManagementWizardState state, bool parentAccount) + : base(owner, state, parentAccount) + { + this._firstView = true; + if (parentAccount) + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_PARENTAL_INPUT_HEAD); + else + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_PASSPORT_STEP); + this.Initialize((WizardPropertyEditor)new HipPropertyEditor()); + } + + public WinLiveInformation WinLiveHip + { + get => this._winLiveHip; + private set + { + if (this._winLiveHip == value) + return; + this._winLiveHip = value; + this.FirePropertyChanged(nameof(WinLiveHip)); + this.FirePropertyChanged("IsEnabled"); + } + } + + public override string UI => "res://ZuneShellResources!CreatePassport.uix#HipPassportStep"; + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled && !this.CreatePassportStep.CreatedPassport; + if (flag) + flag = this.CreatePassportStep.IsEnabled && (this._owner.CurrentPage != this || this.WinLiveHip != null); + return flag; + } + } + + internal override Dictionary ErrorPropertyMappings + { + get + { + if (this._errorMappings == null) + { + this._errorMappings = new Dictionary(1); + this._errorMappings.Add(HRESULT._NS_E_WINLIVE_HIP_SOLUTION_INVALID.Int, (PropertyDescriptor)null); + } + return this._errorMappings; + } + } + + private CreatePassportStep CreatePassportStep => !this.ParentAccount ? this.State.CreatePassportStep : this.State.CreatePassportParentStep; + + public void Refresh() + { + if (!this.IsEnabled) + return; + this.OnActivate(); + } + + protected override void OnActivate() + { + this.SetCommittedValue(HipPropertyEditor.HipCharacters, (object)""); + if (this._firstView) + { + this._firstView = false; + this.WinLiveHip = this.CreatePassportStep.WinLiveInformation; + } + else + this.WinLiveHip = (WinLiveInformation)null; + this.ServiceActivationRequestsDone = this.WinLiveHip != null; + if (this.ServiceActivationRequestsDone) + return; + this.StartActivationRequests((object)this.State.BasicAccountInfoStep.SelectedLocale); + } + + internal override ErrorMapperResult GetMappedErrorDescriptionAndUrl(HRESULT hr) => Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int, eErrorCondition.eEC_WinLive); + + protected override void OnStartActivationRequests(object state) => this.EndActivationRequests((object)this.ObtainWinLiveHip(state as string)); + + protected override void OnEndActivationRequests(object args) + { + if (args == null) + this.NavigateToErrorHandler(); + else + this.WinLiveHip = args as WinLiveInformation; + } + + private WinLiveInformation ObtainWinLiveHip(string local) + { + WinLiveInformation information1 = (WinLiveInformation)null; + ServiceError serviceError = (ServiceError)null; + HRESULT information2 = this.State.WinLiveSignup.GetInformation(local, Microsoft.Zune.Service.EHipType.Image, out information1, out serviceError); + if (information2.IsError) + this.SetError(information2, serviceError); + return information1; + } + } +} diff --git a/ZuneUI/HipPropertyEditor.cs b/ZuneUI/HipPropertyEditor.cs new file mode 100644 index 0000000..5ec398e --- /dev/null +++ b/ZuneUI/HipPropertyEditor.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.HipPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class HipPropertyEditor : WizardPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static PropertyDescriptor s_HipCharacters = new PropertyDescriptor("HIPSolution", string.Empty, string.Empty, true); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (HipPropertyEditor.s_dataProviderProperties == null) + HipPropertyEditor.s_dataProviderProperties = new PropertyDescriptor[1] + { + HipPropertyEditor.s_HipCharacters + }; + return HipPropertyEditor.s_dataProviderProperties; + } + } + + public static PropertyDescriptor HipCharacters => HipPropertyEditor.s_HipCharacters; + } +} diff --git a/ZuneUI/IBackgroundAwareDeviceIconSet.cs b/ZuneUI/IBackgroundAwareDeviceIconSet.cs new file mode 100644 index 0000000..d987303 --- /dev/null +++ b/ZuneUI/IBackgroundAwareDeviceIconSet.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IBackgroundAwareDeviceIconSet +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public interface IBackgroundAwareDeviceIconSet + { + ISimpleDeviceIconSet ForLightBackground { get; } + + ISimpleDeviceIconSet ForDarkBackground { get; } + + ISimpleDeviceIconSet GetSetForBackground(bool backgroundIsDark); + } +} diff --git a/ZuneUI/IColorSet.cs b/ZuneUI/IColorSet.cs new file mode 100644 index 0000000..4268027 --- /dev/null +++ b/ZuneUI/IColorSet.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IColorSet +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public interface IColorSet + { + IDeviceColor Light { get; } + + IDeviceColor Dark { get; } + + IDeviceColor Text { get; } + + IDeviceColor HoverText { get; } + } +} diff --git a/ZuneUI/ICommandHandler.cs b/ZuneUI/ICommandHandler.cs new file mode 100644 index 0000000..cf292ca --- /dev/null +++ b/ZuneUI/ICommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ICommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public interface ICommandHandler + { + void Execute(string command, IDictionary commandArgs); + } +} diff --git a/ZuneUI/IDeviceColor.cs b/ZuneUI/IDeviceColor.cs new file mode 100644 index 0000000..5f24ac5 --- /dev/null +++ b/ZuneUI/IDeviceColor.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IDeviceColor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public interface IDeviceColor + { + float R { get; } + + float G { get; } + + float B { get; } + } +} diff --git a/ZuneUI/IDeviceContentsPage.cs b/ZuneUI/IDeviceContentsPage.cs new file mode 100644 index 0000000..2e3e872 --- /dev/null +++ b/ZuneUI/IDeviceContentsPage.cs @@ -0,0 +1,13 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IDeviceContentsPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public interface IDeviceContentsPage : IPage + { + bool ShowDeviceContents { get; } + } +} diff --git a/ZuneUI/IDeviceIconSet.cs b/ZuneUI/IDeviceIconSet.cs new file mode 100644 index 0000000..777928d --- /dev/null +++ b/ZuneUI/IDeviceIconSet.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IDeviceIconSet +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public interface IDeviceIconSet + { + ISimpleDeviceIconSet Large { get; } + + ISimpleDeviceIconSet Medium { get; } + + IInteractiveDeviceIconSet Small { get; } + + Image Background { get; } + + IColorSet Colors { get; } + } +} diff --git a/ZuneUI/IInteractiveDeviceIconSet.cs b/ZuneUI/IInteractiveDeviceIconSet.cs new file mode 100644 index 0000000..f33d62b --- /dev/null +++ b/ZuneUI/IInteractiveDeviceIconSet.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IInteractiveDeviceIconSet +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public interface IInteractiveDeviceIconSet + { + IBackgroundAwareDeviceIconSet Default { get; } + + IBackgroundAwareDeviceIconSet Hover { get; } + + IBackgroundAwareDeviceIconSet Drag { get; } + + IBackgroundAwareDeviceIconSet Click { get; } + + IBackgroundAwareDeviceIconSet Syncing { get; } + } +} diff --git a/ZuneUI/INotifyPropertyChangedImpl.cs b/ZuneUI/INotifyPropertyChangedImpl.cs new file mode 100644 index 0000000..517d591 --- /dev/null +++ b/ZuneUI/INotifyPropertyChangedImpl.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.INotifyPropertyChangedImpl +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.ComponentModel; + +namespace ZuneUI +{ + public class INotifyPropertyChangedImpl : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + protected void NotifyPropertyChanged(string propertyName, bool propogate) + { + if (this.PropertyChanged == null) + return; + this.PropertyChanged((object)this, (PropertyChangedEventArgs)new MetadataPropertyChangedEventArgs(propertyName, propogate)); + } + } +} diff --git a/ZuneUI/IPage.cs b/ZuneUI/IPage.cs new file mode 100644 index 0000000..800e9a9 --- /dev/null +++ b/ZuneUI/IPage.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public interface IPage + { + IPageState SaveAndRelease(); + + void Release(); + + void OnNavigatedTo(); + + void OnNavigatedAway(IPage destination); + } +} diff --git a/ZuneUI/IPageState.cs b/ZuneUI/IPageState.cs new file mode 100644 index 0000000..5f1dd8a --- /dev/null +++ b/ZuneUI/IPageState.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IPageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public interface IPageState + { + IPage RestoreAndRelease(); + + void Release(); + + bool CanBeTrimmed { get; } + } +} diff --git a/ZuneUI/ISimpleDeviceIconSet.cs b/ZuneUI/ISimpleDeviceIconSet.cs new file mode 100644 index 0000000..3c484d9 --- /dev/null +++ b/ZuneUI/ISimpleDeviceIconSet.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ISimpleDeviceIconSet +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public interface ISimpleDeviceIconSet + { + Image Connected { get; } + + Image Disconnected { get; } + + Image GetImageForConnectedness(bool isConnected); + } +} diff --git a/ZuneUI/ISlideShowStateOwner.cs b/ZuneUI/ISlideShowStateOwner.cs new file mode 100644 index 0000000..e3b739a --- /dev/null +++ b/ZuneUI/ISlideShowStateOwner.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ISlideShowStateOwner +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.ComponentModel; + +namespace ZuneUI +{ + public interface ISlideShowStateOwner : INotifyPropertyChanged + { + SlideShowState SlideShowState { get; } + } +} diff --git a/ZuneUI/IThumbnailCommand.cs b/ZuneUI/IThumbnailCommand.cs new file mode 100644 index 0000000..1dfb604 --- /dev/null +++ b/ZuneUI/IThumbnailCommand.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IThumbnailCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public interface IThumbnailCommand : ICommand, INotifyPropertyChanged + { + Image Image { get; } + + IDictionary Data { get; } + + string Description { get; } + + bool Selected { get; } + } +} diff --git a/ZuneUI/IWizardNavigation.cs b/ZuneUI/IWizardNavigation.cs new file mode 100644 index 0000000..26fddd4 --- /dev/null +++ b/ZuneUI/IWizardNavigation.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IWizardNavigation +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public interface IWizardNavigation + { + Command Back { get; } + + Command Next { get; } + + Command Finish { get; } + + Command Cancel { get; } + } +} diff --git a/ZuneUI/IZunePage.cs b/ZuneUI/IZunePage.cs new file mode 100644 index 0000000..eaa7926 --- /dev/null +++ b/ZuneUI/IZunePage.cs @@ -0,0 +1,64 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IZunePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public interface IZunePage : IPage, INotifyPropertyChanged + { + string UI { get; set; } + + string BackgroundUI { get; set; } + + string BottomBarUI { get; } + + string OverlayUI { get; set; } + + IDictionary NavigationArguments { get; set; } + + ICommandHandler CommandHandler { get; } + + bool ShowBackArrow { get; } + + bool ShowDeviceIcon { get; } + + bool ShowPlaylistIcon { get; } + + bool ShowCDIcon { get; } + + bool ShowNowPlayingX { get; } + + bool ShowNowPlayingBackgroundOnIdle { get; } + + bool NotificationAreaVisible { get; } + + bool AutoHideToolbars { get; } + + bool ShowAppBackground { get; } + + ComputerIconState ShowComputerIcon { get; } + + bool ShowLogo { get; } + + bool ShowPivots { get; } + + bool ShowSearch { get; } + + bool ShowSettings { get; } + + TransportControlStyle TransportControlStyle { get; } + + PlaybackContext PlaybackContext { get; } + + bool HandleBack(); + + bool HandleEscape(); + + bool CanNavigateForwardTo(IZunePage destination); + } +} diff --git a/ZuneUI/ImageConstants.cs b/ZuneUI/ImageConstants.cs new file mode 100644 index 0000000..ad50f7b --- /dev/null +++ b/ZuneUI/ImageConstants.cs @@ -0,0 +1,65 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ImageConstants +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public static class ImageConstants + { + private static Size _nowPlayingSize = new Size(1012, 693); + private static Size _smallArtistTileSize = new Size(160, 120); + private static Size _largeArtistTileSize = new Size(420, 320); + private static Size _channelTileSize = new Size(160, 120); + private static Size _smallMusicVideoTileSize = new Size(160, 120); + private static Size _largeMusicVideoTileSize = new Size(420, 320); + private static Size _smallAlbumSize = new Size(86, 86); + private static Size _mediumAlbumSize = new Size(100, 100); + private static Size _largeAlbumSize = new Size(320, 320); + private static Size _mediumAppsTileSize = new Size(100, 100); + private static Size _largeAppsTileSize = new Size(160, 160); + private static Size _playlistTileSize = new Size(160, 120); + private static Size _feature1x1Size = new Size(240, 240); + private static Size _feature4x3SmallSize = new Size(258, 194); + private static Size _feature4x3Size = new Size(420, 320); + private static Size _feature16x9Size = new Size(853, 480); + private static Size _defaultSize = new Size(320, 320); + + public static Size Default => ImageConstants._defaultSize; + + public static Size NowPlaying => ImageConstants._nowPlayingSize; + + public static Size SmallAlbum => ImageConstants._smallAlbumSize; + + public static Size MediumAlbum => ImageConstants._mediumAlbumSize; + + public static Size LargeAlbum => ImageConstants._largeAlbumSize; + + public static Size ChannelTile => ImageConstants._channelTileSize; + + public static Size SmallMusicVideoTile => ImageConstants._smallMusicVideoTileSize; + + public static Size LargeMusicVideoTile => ImageConstants._largeMusicVideoTileSize; + + public static Size SmallArtistTile => ImageConstants._smallArtistTileSize; + + public static Size LargeArtistTile => ImageConstants._largeArtistTileSize; + + public static Size MediumAppsTile => ImageConstants._mediumAppsTileSize; + + public static Size LargeAppsTile => ImageConstants._largeAppsTileSize; + + public static Size PlaylistTile => ImageConstants._playlistTileSize; + + public static Size Feature1x1 => ImageConstants._feature1x1Size; + + public static Size Feature4x3Small => ImageConstants._feature4x3SmallSize; + + public static Size Feature4x3 => ImageConstants._feature4x3Size; + + public static Size Feature16x9 => ImageConstants._feature16x9Size; + } +} diff --git a/ZuneUI/ImageIdType.cs b/ZuneUI/ImageIdType.cs new file mode 100644 index 0000000..c159c3e --- /dev/null +++ b/ZuneUI/ImageIdType.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ImageIdType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum ImageIdType + { + ImageId, + MovieId, + ArtistId, + MovieTrailerId, + ParentalRatingId, + } +} diff --git a/ZuneUI/ImageRequested.cs b/ZuneUI/ImageRequested.cs new file mode 100644 index 0000000..0c60cc0 --- /dev/null +++ b/ZuneUI/ImageRequested.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ImageRequested +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum ImageRequested + { + PrimaryImage, + BackgroundImage, + XboxBackgroundImage, + } +} diff --git a/ZuneUI/InboxNavigationCommandHandler.cs b/ZuneUI/InboxNavigationCommandHandler.cs new file mode 100644 index 0000000..6989e50 --- /dev/null +++ b/ZuneUI/InboxNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.InboxNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class InboxNavigationCommandHandler : NavigationCommandHandlerBase + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new InboxPage(); + } +} diff --git a/ZuneUI/InboxPage.cs b/ZuneUI/InboxPage.cs new file mode 100644 index 0000000..3462812 --- /dev/null +++ b/ZuneUI/InboxPage.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.InboxPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; +using ZuneXml; + +namespace ZuneUI +{ + public class InboxPage : LibraryPage + { + private InboxPanel _inboxPanel; + private MessageDetailsPanel _messageDetailsPanel; + private Command _refreshPageCommand; + public static readonly string InboxPageTemplate = "res://ZuneShellResources!InboxMainPanel.uix#InboxLibrary"; + + public InboxPage() + { + this.PivotPreference = Shell.MainFrame.Social.Inbox; + this.IsRootPage = true; + this.UI = InboxPage.InboxPageTemplate; + this.UIPath = "Social\\Inbox"; + this._refreshPageCommand = new Command((IModelItemOwner)this); + this._inboxPanel = new InboxPanel(this); + this._messageDetailsPanel = new MessageDetailsPanel((LibraryPage)this, true); + } + + public override void InvokeSettings() => Shell.SettingsFrame.Settings.Account.Invoke(); + + public override IPageState SaveAndRelease() + { + if (this.NavigationArguments == null) + this.NavigationArguments = (IDictionary)new Hashtable(1); + if (this.Details.SelectedItem != null) + { + this.NavigationArguments[(object)"MessageId"] = (object)((MessageRoot)this.Details.SelectedItem).MessagingId; + this.Details.SelectedItem = (DataProviderObject)null; + } + else + this.NavigationArguments.Remove((object)"MessageId"); + this._inboxPanel.Release(); + this._messageDetailsPanel.Release(); + return base.SaveAndRelease(); + } + + public InboxPanel MainPanel => this._inboxPanel; + + public MessageDetailsPanel Details => this._messageDetailsPanel; + + public Command RefreshPageCommand => this._refreshPageCommand; + } +} diff --git a/ZuneUI/InboxPanel.cs b/ZuneUI/InboxPanel.cs new file mode 100644 index 0000000..c5ae276 --- /dev/null +++ b/ZuneUI/InboxPanel.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.InboxPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class InboxPanel : ListPanel + { + internal InboxPanel(InboxPage page) + : base((IModelItemOwner)page) + { + } + } +} diff --git a/ZuneUI/InstalledProductChecker.cs b/ZuneUI/InstalledProductChecker.cs new file mode 100644 index 0000000..4856365 --- /dev/null +++ b/ZuneUI/InstalledProductChecker.cs @@ -0,0 +1,84 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.InstalledProductChecker +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace ZuneUI +{ + public static class InstalledProductChecker + { + public static bool IsInstalled(string upgradeCode, int minVersionMajor, int minVersionMinor) + { + Guid empty1 = Guid.Empty; + Guid guid; + try + { + guid = new Guid(upgradeCode); + } + catch + { + return false; + } + string empty2 = string.Empty; + int index = 0; + string productCode; + do + { + productCode = InstalledProductChecker.EnumRelatedProducts(guid.ToString("B"), index); + if (!string.IsNullOrEmpty(productCode) && InstalledProductChecker.GetProductVersionMajor(productCode) >= minVersionMajor && InstalledProductChecker.GetProductVersionMinor(productCode) >= minVersionMinor) + return true; + ++index; + } + while (!string.IsNullOrEmpty(productCode)); + return false; + } + + public static string GetProductName(string productCode) => InstalledProductChecker.GetProductInfo(productCode, "ProductName"); + + public static int GetProductVersionMajor(string productCode) + { + int result; + int.TryParse(InstalledProductChecker.GetProductInfo(productCode, "VersionMajor"), out result); + return result; + } + + public static int GetProductVersionMinor(string productCode) + { + int result; + int.TryParse(InstalledProductChecker.GetProductInfo(productCode, "VersionMinor"), out result); + return result; + } + + public static string GetProductInfo(string productCode, string property) + { + int size = 512; + StringBuilder valueBuffer = new StringBuilder(size); + return (HRESULT)InstalledProductChecker.MsiGetProductInfo(productCode, property, valueBuffer, ref size) != HRESULT._S_OK ? string.Empty : valueBuffer.ToString(); + } + + public static string EnumRelatedProducts(string upgradeCode, int index) + { + StringBuilder productCodeBuffer = new StringBuilder(39); + return (HRESULT)InstalledProductChecker.MsiEnumRelatedProducts(upgradeCode, 0, index, productCodeBuffer) != HRESULT._S_OK ? string.Empty : productCodeBuffer.ToString(); + } + + [DllImport("msi.dll")] + private static extern int MsiGetProductInfo( + string productCode, + string property, + [Out] StringBuilder valueBuffer, + ref int size); + + [DllImport("msi.dll")] + private static extern int MsiEnumRelatedProducts( + string upgradeCode, + int reserved, + int index, + [Out] StringBuilder productCodeBuffer); + } +} diff --git a/ZuneUI/InstancePageState.cs b/ZuneUI/InstancePageState.cs new file mode 100644 index 0000000..0485236 --- /dev/null +++ b/ZuneUI/InstancePageState.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.InstancePageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class InstancePageState : IPageState + { + private IPage _page; + + public InstancePageState(IPage page) => this._page = page; + + public IPage RestoreAndRelease() => this._page; + + public void Release() => this._page.Release(); + + public bool CanBeTrimmed => true; + } +} diff --git a/ZuneUI/IntHelper.cs b/ZuneUI/IntHelper.cs new file mode 100644 index 0000000..d238f71 --- /dev/null +++ b/ZuneUI/IntHelper.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IntHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class IntHelper + { + public static int MinValue => int.MinValue; + + public static int MaxValue => int.MaxValue; + } +} diff --git a/ZuneUI/IntPropertyDescriptor.cs b/ZuneUI/IntPropertyDescriptor.cs new file mode 100644 index 0000000..c188ea1 --- /dev/null +++ b/ZuneUI/IntPropertyDescriptor.cs @@ -0,0 +1,46 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IntPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class IntPropertyDescriptor : PropertyDescriptor + { + public IntPropertyDescriptor( + string name, + string multiValueString, + string unknownString, + int maxTextLength) + : base(name, multiValueString, unknownString, maxTextLength) + { + } + + public IntPropertyDescriptor(string name, string multiValueString, string unknownString) + : base(name, multiValueString, unknownString) + { + } + + public IntPropertyDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : base(name, multiValueString, unknownString, required) + { + } + + public override object ConvertFromString(string value) + { + int result; + return int.TryParse(value, out result) ? (object)result : (object)0; + } + + public override bool IsValidInternal(string value) + { + int result; + return string.IsNullOrEmpty(value) || int.TryParse(value, out result) && result >= 0; + } + } +} diff --git a/ZuneUI/IntYearPropertyDescriptor.cs b/ZuneUI/IntYearPropertyDescriptor.cs new file mode 100644 index 0000000..aa01a3f --- /dev/null +++ b/ZuneUI/IntYearPropertyDescriptor.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.IntYearPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class IntYearPropertyDescriptor : YearPropertyDescriptor + { + public IntYearPropertyDescriptor( + string name, + string multiValueString, + string unknownString, + int maxTextLength) + : base(name, multiValueString, unknownString, maxTextLength) + { + } + + public override string ConvertToString(object value) + { + if (value == null) + return (string)null; + int num = (int)value; + return num < 0 ? (string)null : num.ToString(); + } + + public override object ConvertFromString(string value) + { + int result; + return int.TryParse(value, out result) ? (object)result : (object)0; + } + } +} diff --git a/ZuneUI/InternetConnection.cs b/ZuneUI/InternetConnection.cs new file mode 100644 index 0000000..1dff95e --- /dev/null +++ b/ZuneUI/InternetConnection.cs @@ -0,0 +1,63 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.InternetConnection +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Net.NetworkInformation; + +namespace ZuneUI +{ + public class InternetConnection : NotifyPropertyChangedImpl + { + private static InternetConnection _instance; + private bool _isConnected; + private bool _initializationSucceeded; + + private InternetConnection() => this.Initialize(); + + public static InternetConnection Instance + { + get + { + if (InternetConnection._instance == null) + InternetConnection._instance = new InternetConnection(); + return InternetConnection._instance; + } + } + + public bool IsConnected + { + get + { + if (!this._initializationSucceeded) + this.IsConnected = Win32InternetConnection.IsConnected; + return this._isConnected; + } + private set + { + if (this._isConnected == value) + return; + this._isConnected = value; + this.FirePropertyChanged(nameof(IsConnected)); + } + } + + private void Initialize() + { + try + { + this._isConnected = NetworkInterface.GetIsNetworkAvailable(); + NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(this.OnNetworkAvailabilityChanged); + this._initializationSucceeded = true; + } + catch (Exception ex) + { + this._initializationSucceeded = false; + } + } + + private void OnNetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) => this.IsConnected = e.IsAvailable; + } +} diff --git a/ZuneUI/JumpListManager.cs b/ZuneUI/JumpListManager.cs new file mode 100644 index 0000000..764da52 --- /dev/null +++ b/ZuneUI/JumpListManager.cs @@ -0,0 +1,210 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.JumpListManager +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Threading; + +namespace ZuneUI +{ + public class JumpListManager : SingletonModelItem + { + private const int _maxPins = 6; + private const int _maxQuickMixes = 5; + private const int _normalIconIndex = -12; + private const int _quickMixIconIndex = -13; + private Command _updatePins; + private IList _pinList; + private IList _quickMixList; + private bool _pinListsHaveBeenSetAtLeastOnce; + private bool _finalCommitHasBeenCompleted; + private bool _showResumeNowPlaying; + private bool _currentPlaylistWillBeSaved; + private bool _transportControlsHavePlaylist; + private string _resumeNowPlayingName; + private string _shuffleAllName; + private string _pinCategoryName; + private string _quickMixCategoryName; + private static int _lastUpdateJobCookie = 0; + private static object _updateJobLock = new object(); + + public JumpListManager() + : base((IModelItemOwner)SingletonModelItem.Instance) + { + this._updatePins = new Command((IModelItemOwner)this); + this._pinListsHaveBeenSetAtLeastOnce = false; + this._finalCommitHasBeenCompleted = false; + this._showResumeNowPlaying = false; + this._resumeNowPlayingName = ZuneUI.Shell.LoadString(StringId.IDS_JUMP_LIST_RESUME_NOWPLAYING); + this._shuffleAllName = ZuneUI.Shell.LoadString(StringId.IDS_JUMP_LIST_SHUFFLE_ALL); + this._pinCategoryName = ZuneUI.Shell.LoadString(StringId.IDS_JUMP_LIST_QUICKPLAY_CATEGORY); + this._quickMixCategoryName = ZuneUI.Shell.LoadString(StringId.IDS_JUMP_LIST_QUICKMIX_CATEGORY); + SingletonModelItem.Instance.PropertyChanged += new PropertyChangedEventHandler(this.OnTransportControlsPropertyChanged); + ZuneApplication.Closing += new EventHandler(this.OnApplicationClosing); + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + ZuneApplication.Closing -= new EventHandler(this.OnApplicationClosing); + SingletonModelItem.Instance.PropertyChanged -= new PropertyChangedEventHandler(this.OnTransportControlsPropertyChanged); + } + base.OnDispose(disposing); + } + + public Command JumpListPinUpdateRequested => this._updatePins; + + public void SetPins(IList pinList, IList quickMixList) + { + this._pinList = pinList; + this._quickMixList = quickMixList; + this._pinListsHaveBeenSetAtLeastOnce = true; + this.UpdateJumpList(); + } + + public static void PlayPin(JumpListPin pin) + { + if (pin == null) + return; + SingletonModelItem.Instance.RequestedJumpListPin = pin; + } + + private void OnTransportControlsPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (args.PropertyName == "HasPlaylist" || args.PropertyName == "Playing") + { + TransportControls instance = SingletonModelItem.Instance; + bool flag = instance.HasPlaylist && !instance.Playing; + if (this._showResumeNowPlaying != flag) + { + this._showResumeNowPlaying = flag; + this.UpdateJumpList(); + } + this._transportControlsHavePlaylist = instance.HasPlaylist; + } + else + { + if (!(args.PropertyName == "CurrentPlaylist")) + return; + this._currentPlaylistWillBeSaved = SingletonModelItem.Instance.WillSaveCurrentPlaylistOnShutdown(); + } + } + + private void OnApplicationClosing(object sender, EventArgs args) + { + if (!this._currentPlaylistWillBeSaved) + this._showResumeNowPlaying = false; + else if (this._transportControlsHavePlaylist) + this._showResumeNowPlaying = true; + this.UpdateJumpList(); + this._finalCommitHasBeenCompleted = true; + } + + private void UpdateJumpList() + { + if (!OSVersion.IsWin7() || !this._pinListsHaveBeenSetAtLeastOnce || this._finalCommitHasBeenCompleted) + return; + JumpListManager.UpdateJumpListJob updateJumpListJob = new JumpListManager.UpdateJumpListJob(); + updateJumpListJob.Cookie = Interlocked.Increment(ref JumpListManager._lastUpdateJobCookie); + updateJumpListJob.ShowResumeNowPlaying = this._showResumeNowPlaying; + updateJumpListJob.ResumeNowPlayingName = this._resumeNowPlayingName; + updateJumpListJob.ShuffleAllName = this._shuffleAllName; + updateJumpListJob.PinCategoryName = this._pinCategoryName; + updateJumpListJob.QuickMixCategoryName = this._quickMixCategoryName; + updateJumpListJob.PinList = new JumpListPin[this._pinList.Count]; + for (int index = 0; index < this._pinList.Count; ++index) + updateJumpListJob.PinList[index] = new JumpListPin((JumpListPin)this._pinList[index]); + updateJumpListJob.QuickMixList = new JumpListPin[this._quickMixList.Count]; + for (int index = 0; index < this._quickMixList.Count; ++index) + updateJumpListJob.QuickMixList[index] = new JumpListPin((JumpListPin)this._quickMixList[index]); + ThreadPool.QueueUserWorkItem(new WaitCallback(JumpListManager.UpdateJumpListWorker), (object)updateJumpListJob); + } + + private static void UpdateJumpListWorker(object data) + { + if (!(data is JumpListManager.UpdateJumpListJob updateJumpListJob)) + return; + lock (JumpListManager._updateJobLock) + { + if (JumpListManager._lastUpdateJobCookie != updateJumpListJob.Cookie) + return; + List disallowedDestinationList = (List)null; + JumpListSession session; + HRESULT hresult = (HRESULT)Win7ShellManager.Instance.BeginJumpListSession(out session); + if (hresult.IsSuccess) + hresult = (HRESULT)session.GetDisallowedDestinations(out disallowedDestinationList); + if (hresult.IsSuccess) + { + List disallowedCommandLineArguments = disallowedDestinationList.ConvertAll((Converter)(rawEntry => rawEntry.CommandLineArguments)); + JumpListEntry task; + if (updateJumpListJob.ShowResumeNowPlaying) + { + session.CreateTask(out task); + task.Name = updateJumpListJob.ResumeNowPlayingName; + task.CommandLineArguments = "/resumenowplaying"; + task.IconIndex = -12; + } + session.CreateTask(out task); + task.Name = updateJumpListJob.ShuffleAllName; + task.CommandLineArguments = "/shuffleall"; + task.IconIndex = -12; + JumpListCategory category; + if (updateJumpListJob.PinList != null && updateJumpListJob.PinList.Length > 0) + { + session.CreateCategory(out category); + category.Name = updateJumpListJob.PinCategoryName; + for (int index = 0; index < 6 && index < updateJumpListJob.PinList.Length; ++index) + JumpListManager.PopulateJumpListIfPossible(category, updateJumpListJob.PinList[index], -12, disallowedCommandLineArguments); + } + if (updateJumpListJob.QuickMixList != null && updateJumpListJob.QuickMixList.Length > 0) + { + session.CreateCategory(out category); + category.Name = updateJumpListJob.QuickMixCategoryName; + for (int index = 0; index < 5 && index < updateJumpListJob.QuickMixList.Length; ++index) + JumpListManager.PopulateJumpListIfPossible(category, updateJumpListJob.QuickMixList[index], -13, disallowedCommandLineArguments); + } + session.Commit(); + } + else + session?.Cancel(); + } + } + + private static void PopulateJumpListIfPossible( + JumpListCategory category, + JumpListPin pin, + int iconIndex, + List disallowedCommandLineArguments) + { + string str = string.Format("/playpin:{0}", (object)pin.ToString()); + if (disallowedCommandLineArguments.Contains(str)) + return; + JumpListEntry destination; + category.CreateDestination(out destination); + destination.Name = pin.Name; + destination.CommandLineArguments = str; + destination.IconIndex = iconIndex; + } + + private class UpdateJumpListJob + { + public int Cookie; + public bool ShowResumeNowPlaying; + public string ResumeNowPlayingName; + public string ShuffleAllName; + public string PinCategoryName; + public string QuickMixCategoryName; + public JumpListPin[] PinList; + public JumpListPin[] QuickMixList; + } + } +} diff --git a/ZuneUI/JumpListPin.cs b/ZuneUI/JumpListPin.cs new file mode 100644 index 0000000..ce5cf0c --- /dev/null +++ b/ZuneUI/JumpListPin.cs @@ -0,0 +1,92 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.JumpListPin +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class JumpListPin + { + private const string _formatString = "{0}~{1}~{2}~{3}~{4}"; + private const int _numberOfFormatStringParameters = 5; + private string _name; + private bool _isQuickMix; + private bool _isMarketplace; + private MediaType _type; + private string _id; + private int _userId; + + public JumpListPin() + { + } + + public JumpListPin(JumpListPin source) + { + this._name = source._name; + this._isQuickMix = source._isQuickMix; + this._isMarketplace = source._isMarketplace; + this._type = source._type; + this._id = source._id; + this._userId = source._userId; + } + + public string Name + { + get => this._name; + set => this._name = value; + } + + public bool IsQuickMix + { + get => this._isQuickMix; + set => this._isQuickMix = value; + } + + public bool IsMarketplace + { + get => this._isMarketplace; + set => this._isMarketplace = value; + } + + public MediaType Type + { + get => this._type; + set => this._type = value; + } + + public string ID + { + get => this._id; + set => this._id = value; + } + + public int UserID + { + get => this._userId; + set => this._userId = value; + } + + public override string ToString() => string.Format("{0}~{1}~{2}~{3}~{4}", (object)this.IsQuickMix, (object)this.IsMarketplace, (object)(int)this.Type, (object)this.UserID, (object)this.ID); + + public static JumpListPin Parse(string pinString) + { + JumpListPin jumpListPin = (JumpListPin)null; + string[] strArray = pinString.Split('~'); + bool result1; + bool result2; + int result3; + int result4; + if (strArray.Length == 5 && bool.TryParse(strArray[0], out result1) && (bool.TryParse(strArray[1], out result2) && int.TryParse(strArray[2], out result3)) && int.TryParse(strArray[3], out result4)) + { + jumpListPin = new JumpListPin(); + jumpListPin.IsQuickMix = result1; + jumpListPin.IsMarketplace = result2; + jumpListPin.Type = (MediaType)result3; + jumpListPin.UserID = result4; + jumpListPin.ID = strArray[4]; + } + return jumpListPin; + } + } +} diff --git a/ZuneUI/KinBrandingStringMap.cs b/ZuneUI/KinBrandingStringMap.cs new file mode 100644 index 0000000..42c6861 --- /dev/null +++ b/ZuneUI/KinBrandingStringMap.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.KinBrandingStringMap +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal class KinBrandingStringMap : PhoneBrandingStringMap + { + private static readonly KinBrandingStringMap _instance = new KinBrandingStringMap(); + + private KinBrandingStringMap() + { + } + + static KinBrandingStringMap() => KinBrandingStringMap._instance.Initialize(); + + public static KinBrandingStringMap Instance => KinBrandingStringMap._instance; + + public override void Initialize() + { + base.Initialize(); + if (!this._stringMap.ContainsKey(StringId.IDS_EULA_DIALOG_TEXTAREA_TITLE)) + return; + this._stringMap.Remove(StringId.IDS_EULA_DIALOG_TEXTAREA_TITLE); + } + } +} diff --git a/ZuneUI/LanguageHelper.cs b/ZuneUI/LanguageHelper.cs new file mode 100644 index 0000000..f17629c --- /dev/null +++ b/ZuneUI/LanguageHelper.cs @@ -0,0 +1,66 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LanguageHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Globalization; + +namespace ZuneUI +{ + internal class LanguageHelper + { + internal static string GetDisplayLanguageName(string languageCode) + { + string str = (string)null; + try + { + if (!string.IsNullOrEmpty(languageCode)) + { + CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(languageCode); + while (!cultureInfo.IsNeutralCulture) + cultureInfo = cultureInfo.Parent; + str = LanguageHelper.GetDisplayName(cultureInfo.ToString()); + } + } + catch (ArgumentException ex) + { + } + return str; + } + + internal static string GetDisplayName(string languageCode) + { + string str = string.Empty; + if (!string.IsNullOrEmpty(languageCode)) + { + try + { + str = new CultureInfo(languageCode).DisplayName; + } + catch (ArgumentException ex) + { + } + } + return str; + } + + internal static string GetAbbreviation(string languageName) + { + string str = string.Empty; + if (!string.IsNullOrEmpty(languageName)) + { + foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.AllCultures)) + { + if (culture.DisplayName.Equals(languageName, StringComparison.CurrentCultureIgnoreCase)) + { + str = culture.TwoLetterISOLanguageName; + break; + } + } + } + return str; + } + } +} diff --git a/ZuneUI/LanguageNameComparer.cs b/ZuneUI/LanguageNameComparer.cs new file mode 100644 index 0000000..8b83450 --- /dev/null +++ b/ZuneUI/LanguageNameComparer.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LanguageNameComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + internal class LanguageNameComparer : IComparer + { + private static LanguageNameComparer s_instance; + + public static IComparer Instance + { + get + { + if (LanguageNameComparer.s_instance == null) + LanguageNameComparer.s_instance = new LanguageNameComparer(); + return (IComparer)LanguageNameComparer.s_instance; + } + } + + private LanguageNameComparer() + { + } + + int IComparer.Compare(string x, string y) => string.Compare(LanguageHelper.GetDisplayName(x), LanguageHelper.GetDisplayName(y), StringComparison.CurrentCultureIgnoreCase); + } +} diff --git a/ZuneUI/LanguagePropertyDescriptor.cs b/ZuneUI/LanguagePropertyDescriptor.cs new file mode 100644 index 0000000..e738056 --- /dev/null +++ b/ZuneUI/LanguagePropertyDescriptor.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LanguagePropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Globalization; + +namespace ZuneUI +{ + public class LanguagePropertyDescriptor : PropertyDescriptor + { + public LanguagePropertyDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : base(name, multiValueString, unknownString, 1000, required, (object)CultureInfo.CurrentCulture.TwoLetterISOLanguageName) + { + this.DefaultValue = (object)CultureHelper.GetDefaultLanguage(); + } + + public override object ConvertFromString(string value) => (object)LanguageHelper.GetAbbreviation(value); + + public override string ConvertToString(object value) => LanguageHelper.GetDisplayName(value as string); + } +} diff --git a/ZuneUI/LibraryAlbumInfo.cs b/ZuneUI/LibraryAlbumInfo.cs new file mode 100644 index 0000000..6f77cd5 --- /dev/null +++ b/ZuneUI/LibraryAlbumInfo.cs @@ -0,0 +1,150 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LibraryAlbumInfo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; +using System.Threading; + +namespace ZuneUI +{ + public class LibraryAlbumInfo : ModelItem + { + private int _trackId; + private string _trackTitle; + private string _albumTitle; + private string _artistName; + private string _albumArtUrl; + private Image _thumbnailImage; + private Guid _zuneMediaId; + private ICommand _onAsyncUpdateAlbumArtUrlCompleted; + + public LibraryAlbumInfo( + LibraryPlaybackTrack track, + int thumbnailMaxWidth, + int thumbnailMaxHeight) + : this(track, thumbnailMaxWidth, thumbnailMaxHeight, (ICommand)null) + { + } + + public LibraryAlbumInfo( + LibraryPlaybackTrack track, + int thumbnailMaxWidth, + int thumbnailMaxHeight, + ICommand onAsyncUpdateAlbumArtUrlCompleted) + { + this._onAsyncUpdateAlbumArtUrlCompleted = onAsyncUpdateAlbumArtUrlCompleted == null ? (ICommand)new Command((IModelItemOwner)this) : onAsyncUpdateAlbumArtUrlCompleted; + if (track.MediaType == MediaType.Track) + { + this._trackId = track.MediaId; + this._trackTitle = track.Title; + int[] columnIndexes1 = new int[2] { 11, 78 }; + object[] fieldValues1 = new object[2] + { + (object) -1, + (object) -1 + }; + ZuneLibrary.GetFieldValues(this._trackId, EListType.eTrackList, columnIndexes1.Length, columnIndexes1, fieldValues1, PlaylistManager.Instance.QueryContext); + int albumId = (int)fieldValues1[0]; + int iMediaId = (int)fieldValues1[1]; + if (albumId >= 0) + { + int[] columnIndexes2 = new int[2] { 382, 451 }; + object[] fieldValues2 = new object[2]; + ZuneLibrary.GetFieldValues(albumId, EListType.eAlbumList, columnIndexes2.Length, columnIndexes2, fieldValues2, PlaylistManager.Instance.QueryContext); + this._albumTitle = (string)fieldValues2[0]; + this._zuneMediaId = GuidHelper.CreateFromString((string)fieldValues2[1]); + ThreadPool.QueueUserWorkItem((WaitCallback)(args => + { + string str = LibraryDataProviderItemBase.GetArtUrl(albumId, "Album", false); + if (!string.IsNullOrEmpty(str)) + str = "file://" + str; + Application.DeferredInvoke(new DeferredInvokeHandler(this.AsyncUpdateAlbumArtUrl), (object)str); + }), (object)null); + } + if (iMediaId < 0) + return; + int[] columnIndexes3 = new int[1] { 138 }; + object[] fieldValues3 = new object[1]; + ZuneLibrary.GetFieldValues(iMediaId, EListType.eArtistList, columnIndexes3.Length, columnIndexes3, fieldValues3, PlaylistManager.Instance.QueryContext); + this._artistName = (string)fieldValues3[0]; + } + else if (track.MediaType == MediaType.PodcastEpisode) + { + this._trackId = track.MediaId; + this._trackTitle = track.Title; + int[] columnIndexes1 = new int[2] { 311, 24 }; + object[] fieldValues1 = new object[2] + { + (object) -1, + null + }; + ZuneLibrary.GetFieldValues(this._trackId, EListType.ePodcastEpisodeList, columnIndexes1.Length, columnIndexes1, fieldValues1, PlaylistManager.Instance.QueryContext); + int iMediaId = (int)fieldValues1[0]; + this._artistName = (string)fieldValues1[1]; + if (iMediaId < 0) + return; + int[] columnIndexes2 = new int[2] { 344, 17 }; + object[] fieldValues2 = new object[2]; + ZuneLibrary.GetFieldValues(iMediaId, EListType.ePodcastList, columnIndexes2.Length, columnIndexes2, fieldValues2, PlaylistManager.Instance.QueryContext); + this._albumTitle = (string)fieldValues2[0]; + this._albumArtUrl = (string)fieldValues2[1]; + } + else + { + if (track.MediaType != MediaType.Video) + return; + this._trackId = track.MediaId; + this._trackTitle = track.Title; + int[] columnIndexes = new int[3] { 380, 382, 312 }; + object[] fieldValues = new object[3]; + ZuneLibrary.GetFieldValues(this._trackId, EListType.eVideoList, columnIndexes.Length, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + this._artistName = (string)fieldValues[0]; + this._albumTitle = (string)fieldValues[1]; + if (string.IsNullOrEmpty(this._albumTitle)) + this._albumTitle = (string)fieldValues[2]; + if (Application.RenderingType != RenderingType.GDI) + return; + ThreadPool.QueueUserWorkItem((WaitCallback)(args => + { + string artUrl = LibraryDataProviderItemBase.GetArtUrl(this._trackId, "Video", false); + if (string.IsNullOrEmpty(artUrl)) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.AsyncUpdateThumbnailUrl), (object)("file://" + artUrl)); + }), (object)null); + } + } + + private void AsyncUpdateAlbumArtUrl(object args) + { + this._albumArtUrl = (string)args; + this.FirePropertyChanged("AlbumArtUrl"); + this.OnAsyncUpdateAlbumArtUrlCompleted.Invoke(); + } + + public ICommand OnAsyncUpdateAlbumArtUrlCompleted => this._onAsyncUpdateAlbumArtUrlCompleted; + + private void AsyncUpdateThumbnailUrl(object args) + { + string source = (string)args; + Image.RemoveCache(source); + this._thumbnailImage = new Image(source); + this.FirePropertyChanged("ThumbnailImage"); + } + + public string TrackTitle => this._trackTitle; + + public string AlbumTitle => this._albumTitle; + + public string ArtistName => this._artistName; + + public string AlbumArtUrl => this._albumArtUrl; + + public Guid ZuneMediaId => this._zuneMediaId; + + public Image ThumbnailImage => this._thumbnailImage; + } +} diff --git a/ZuneUI/LibraryHelper.cs b/ZuneUI/LibraryHelper.cs new file mode 100644 index 0000000..438b77d --- /dev/null +++ b/ZuneUI/LibraryHelper.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LibraryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public static class LibraryHelper + { + public static Guid GetZuneMediaId(MediaType type, int libraryId) => PlaylistManager.GetFieldValue(libraryId, PlaylistManager.MediaTypeToListType(type), 233, Guid.Empty); + } +} diff --git a/ZuneUI/LibraryPage.cs b/ZuneUI/LibraryPage.cs new file mode 100644 index 0000000..4fc0048 --- /dev/null +++ b/ZuneUI/LibraryPage.cs @@ -0,0 +1,215 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LibraryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using MicrosoftZuneLibrary; +using System.Collections; +using System.ComponentModel; +using System.Threading; + +namespace ZuneUI +{ + public class LibraryPage : ZunePage, IDeviceContentsPage, IPage + { + private Choice _views; + private Choice _contentTypes; + private BooleanChoice _showContentTypes; + private bool _showDeviceContents; + private MediaType _mediaType; + private bool _canAddMedia; + private CanAddMediaArgs _canAddMediaArgs; + private bool _isEmpty; + private Command _escapePressed; + private QueryTracker _tracker; + private long _drmStateMask; + + public LibraryPage() + : this(MediaType.Undefined) + { + } + + public LibraryPage(MediaType mediaType) + : this(false, mediaType) + { + } + + public LibraryPage(bool showDeviceContents, MediaType mediaType) + { + this.UI = LibraryPage.LibraryTemplate; + this.ShowDeviceContents = showDeviceContents; + this._mediaType = mediaType; + this._escapePressed = new Command((IModelItemOwner)this); + this._tracker = new QueryTracker(); + this._tracker.PropertyChanged += new PropertyChangedEventHandler(this.TrackerPropertyChanged); + this._drmStateMask = ZuneUI.DrmStateMask.All(); + this._showContentTypes = new BooleanChoice((IModelItemOwner)this); + } + + public Choice Views + { + get => this._views; + set + { + if (this._views == value) + return; + this._views = value; + this.FirePropertyChanged(nameof(Views)); + } + } + + public Choice ContentTypes + { + get => this._contentTypes; + set + { + if (this._contentTypes == value) + return; + this._contentTypes = value; + this.FirePropertyChanged(nameof(ContentTypes)); + } + } + + public BooleanChoice ShowContentTypes => this._showContentTypes; + + public long DrmStateMask + { + get => this._drmStateMask; + set + { + if (this._drmStateMask == value) + return; + this._drmStateMask = value; + this.FirePropertyChanged(nameof(DrmStateMask)); + } + } + + public Command EscapePressed => this._escapePressed; + + public bool IsEmpty + { + get => this._isEmpty; + set + { + if (this._isEmpty == value) + return; + this._isEmpty = value; + this.FirePropertyChanged(nameof(IsEmpty)); + } + } + + public bool ShowDeviceContents + { + get => this._showDeviceContents; + set => this._showDeviceContents = value; + } + + public MediaType MediaType => this._mediaType; + + public bool CanAddMedia + { + get => this._canAddMedia; + set + { + if (this._canAddMedia != value) + { + this._canAddMedia = value; + this.FirePropertyChanged(nameof(CanAddMedia)); + } + this.StopCheckingCanAddMedia(); + } + } + + public QueryTracker Tracker => this._tracker; + + private void TrackerPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "Status") || !QueryHelper.HasCompletedOrFailed(this.Tracker.Status)) + return; + ZuneApplication.PageLoadComplete(); + } + + public virtual void CheckCanAddMedia(IList filenames) + { + this.CanAddMedia = false; + if (this.ShowDeviceContents) + return; + ArrayList tempFilenames = new ArrayList((ICollection)filenames); + CanAddMediaArgs args = new CanAddMediaArgs(); + this._canAddMediaArgs = args; + ThreadPool.QueueUserWorkItem((WaitCallback)(ignored => + { + bool canAddMedia = ZuneApplication.CanAddMedia((IList)tempFilenames, this.MediaType, args); + if (args.Aborted) + return; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (args.Aborted) + return; + this.CanAddMedia = canAddMedia; + }, (object)null); + })); + } + + public void StopCheckingCanAddMedia() + { + if (this._canAddMediaArgs == null) + return; + this._canAddMediaArgs.Aborted = true; + this._canAddMediaArgs = (CanAddMediaArgs)null; + } + + public virtual void AddMedia(IList filenames) + { + ArrayList tempFilenames = new ArrayList((ICollection)filenames); + ThreadPool.QueueUserWorkItem((WaitCallback)(o => + { + if (ZuneApplication.AddMedia((IList)tempFilenames, this.MediaType)) + return; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + NotificationArea.Instance.Add((Notification)new MessageNotification(ZuneUI.Shell.LoadString(StringId.IDS_LIBRARY_ADD_FILE_FAILED), NotificationTask.Library, NotificationState.OneShot) + { + SubMessage = ZuneUI.Shell.LoadString(StringId.IDS_LIBRARY_ADD_FILE_FAILED_SUBMESSAGE) + }); + }, (object)null); + })); + } + + public override IPageState SaveAndRelease() => (IPageState)new DevicePivotManagingPageState((IDeviceContentsPage)this); + + public static void BlockUpdatesFromDBList( + IList list, + BlockListUpdatesReason reason, + bool block) + { + if (!(list is VirtualDatabaseList virtualDatabaseList)) + return; + virtualDatabaseList.SetBlockChangesFlag((int)reason, block); + } + + public static void DisableAutoRefresh(IList list) + { + if (!(list is LibraryVirtualList libraryVirtualList)) + return; + libraryVirtualList.DisableAutoRefresh(); + } + + public override void InvokeSettings() + { + if (this.ShowDeviceContents) + ZuneUI.Shell.SettingsFrame.Settings.Device.Invoke(); + else if (this.MediaType == MediaType.Photo) + ZuneUI.Shell.SettingsFrame.Settings.Software.Invoke(SettingCategories.Photo); + else if (this.MediaType == MediaType.PodcastEpisode || this.MediaType == MediaType.Podcast) + ZuneUI.Shell.SettingsFrame.Settings.Software.Invoke(SettingCategories.Podcast); + else + base.InvokeSettings(); + } + + private static string LibraryTemplate => "res://ZuneShellResources!Library.uix#Library"; + } +} diff --git a/ZuneUI/LibraryPanel.cs b/ZuneUI/LibraryPanel.cs new file mode 100644 index 0000000..d14286f --- /dev/null +++ b/ZuneUI/LibraryPanel.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LibraryPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class LibraryPanel : PropertySet + { + private string _ui; + private LibraryPage _libraryPage; + + public LibraryPanel() + : this((IModelItemOwner)null) + { + } + + public LibraryPanel(IModelItemOwner owner) + : base(owner) + => this._libraryPage = owner as LibraryPage; + + public string UI + { + get => this._ui; + set + { + if (!(this._ui != value)) + return; + this._ui = value; + this.FirePropertyChanged(nameof(UI)); + } + } + + public virtual MediaType MediaType => this.LibraryPage.MediaType; + + public virtual SyncCategory SyncCategory => UIDeviceList.MapMediaTypeToSyncCategory(this.MediaType); + + public LibraryPage LibraryPage => this._libraryPage; + + internal virtual void Release() + { + } + } +} diff --git a/ZuneUI/LibraryPlaybackTrack.cs b/ZuneUI/LibraryPlaybackTrack.cs new file mode 100644 index 0000000..b32c774 --- /dev/null +++ b/ZuneUI/LibraryPlaybackTrack.cs @@ -0,0 +1,511 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LibraryPlaybackTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Playlist; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using MicrosoftZunePlayback; +using System; +using System.Threading; + +namespace ZuneUI +{ + [Serializable] + public class LibraryPlaybackTrack : PlaybackTrack + { + private const long c_bookmarkInterval = 10000000; + private int _mediaId; + private Guid _zuneMediaInstanceId; + private Guid? _zuneMediaId; + private MediaType _mediaType; + private EListType _listType; + private LibraryPlaybackTrack.Streaming _isStreaming; + private bool _isInCollection; + private bool? _isVideo; + private int? _userRating; + private long _markPlayedAt; + private bool _hasMarkedPlayed; + private bool _hasIncrementedPlayCount; + private bool _hasIncrementedSkipCount; + private long _lastStoredBookmark; + private long _duration; + private static long[] c_podcastVideoLengths = new long[3] + { + 0L, + 3000000000L, + 6000000000L + }; + private static long[] c_podcastVideoMarkPlayedAtEOFMinus = new long[3] + { + 300000000L, + 600000000L, + 1200000000L + }; + + public LibraryPlaybackTrack( + int mediaId, + MediaType mediaType, + ContainerPlayMarker containerPlayMarker) + { + this._mediaId = mediaId; + this._mediaType = mediaType; + this._listType = PlaylistManager.MediaTypeToListType(mediaType); + this._containerPlayMarker = containerPlayMarker; + ThreadPool.QueueUserWorkItem((WaitCallback)(args => + { + this._isInCollection = PlaylistManager.IsInCollection(this._mediaId, this._mediaType); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.RatingChanged.Invoke(); + }, (object)null); + }), (object)null); + } + + public int MediaId => this._mediaId; + + public override Guid ZuneMediaInstanceId => this._zuneMediaInstanceId; + + public override MediaType MediaType => this._mediaType; + + public EListType ListType => this._listType; + + public override bool IsVideo + { + get + { + if (!this._isVideo.HasValue) + this._isVideo = new bool?(PlaylistManager.IsVideo(this._mediaId, this._mediaType)); + return this._isVideo.Value; + } + } + + public override bool IsMusic => this._mediaType == MediaType.Track; + + public override bool IsHD => this.IsVideo && VideoDefinitionHelper.IsHD((VideoDefinition)PlaylistManager.GetFieldValue(this._mediaId, this._listType, 440, -1)); + + public override bool IsStreaming + { + get + { + if (this._isStreaming == LibraryPlaybackTrack.Streaming.Unknown) + this._isStreaming = PlaylistManager.GetFieldValue(this._mediaId, this._listType, 177, -1) == 43 ? LibraryPlaybackTrack.Streaming.Yes : LibraryPlaybackTrack.Streaming.No; + return this._isStreaming == LibraryPlaybackTrack.Streaming.Yes; + } + } + + public override Guid ZuneMediaId + { + get + { + if (!this._zuneMediaId.HasValue) + this._zuneMediaId = new Guid?(PlaylistManager.GetFieldValue(this._mediaId, this._listType, 451, Guid.Empty)); + return this._zuneMediaId.Value; + } + } + + public override string Title => PlaylistManager.GetFieldValue(this._mediaId, this._listType, 344, string.Empty); + + public override TimeSpan Duration => PlaylistManager.GetFieldValue(this._mediaId, this._listType, 151, TimeSpan.Zero); + + public int AlbumLibraryId => PlaylistManager.GetFieldValue(this._mediaId, this._listType, 11, -1); + + public int AlbumArtistLibraryId + { + get + { + int albumLibraryId = this.AlbumLibraryId; + return albumLibraryId >= 0 ? PlaylistManager.GetFieldValue(albumLibraryId, EListType.eAlbumList, 78, -1) : -1; + } + } + + public override bool CanRate + { + get + { + bool flag1 = this._containerPlayMarker != null && this._containerPlayMarker.PlaylistType == PlaylistType.QuickMix; + bool flag2 = false; + if (this.MediaType == MediaType.Track) + flag2 = flag1 || this.IsInCollection; + return flag2; + } + } + + public override int UserRating + { + get + { + if (!this.CanRate) + return 0; + if (!this._userRating.HasValue) + this._userRating = new int?(PlaylistManager.GetFieldValue(this._mediaId, this._listType, 372, 0)); + return this._userRating.Value; + } + set + { + if (!this.CanRate) + return; + this._userRating = new int?(value); + PlaylistManager.SetFieldValue(this._mediaId, this._listType, 372, value); + this.RatingChanged.Invoke(); + } + } + + public override bool IsInCollection => this._isInCollection; + + public override bool IsInVisibleCollection => PlaylistManager.IsInVisibleCollection(this._mediaId, this._mediaType); + + private long Bookmark => this._mediaType == MediaType.PodcastEpisode || this._mediaType == MediaType.Video ? PlaylistManager.GetFieldValue(this._mediaId, this._listType, 35, 0L) : 0L; + + private string Album => PlaylistManager.GetFieldValue(this._mediaId, this._listType, this._mediaType == MediaType.PodcastEpisode ? 312 : 382, string.Empty); + + public string DisplayArtist => PlaylistManager.GetFieldValue(this._mediaId, this._listType, this._mediaType == MediaType.PodcastEpisode ? 24 : 138, string.Empty); + + public override string ServiceContext + { + get + { + int num = 0; + if (this.MediaType != MediaType.PodcastEpisode) + num = PlaylistManager.GetFieldValue(this._mediaId, this._listType, 358, 0); + return num != 0 ? num.ToString() : (string)null; + } + } + + private int TrackNumber => this._mediaType != MediaType.PodcastEpisode ? PlaylistManager.GetFieldValue(this._mediaId, this._listType, 437, 0) : 0; + + public override HRESULT GetURI(out string uri) + { + string uriOut = (string)null; + HRESULT hresult = HRESULT._S_OK; + Microsoft.Zune.Service.EContentType eContentType; + if (PlaylistManager.GetFieldValue(this._mediaId, this._listType, 177, -1) == 43) + { + eContentType = Microsoft.Zune.Service.EContentType.Video; + } + else + { + eContentType = Microsoft.Zune.Service.EContentType.MusicTrack; + uriOut = PlaylistManager.GetFieldValue(this._mediaId, this._listType, 317, (string)null); + if (!string.IsNullOrEmpty(uriOut)) + { + try + { + if (new Uri(uriOut).Scheme == Uri.UriSchemeFile) + { + if (!ZuneLibrary.DoesFileExist(uriOut)) + uriOut = (string)null; + } + } + catch (UriFormatException ex) + { + } + } + } + if (string.IsNullOrEmpty(uriOut) && this.ZuneMediaId != Guid.Empty) + hresult = ZuneApplication.Service.GetContentUri(this.ZuneMediaId, eContentType, Microsoft.Zune.Service.EContentUriFlags.None, out uriOut, out this._zuneMediaInstanceId); + uri = uriOut; + return hresult; + } + + internal override void OnBeginPlayback(PlayerInterop playbackWrapper) + { + base.OnBeginPlayback(playbackWrapper); + this._hasMarkedPlayed = false; + this._markPlayedAt = 0L; + this._hasIncrementedPlayCount = false; + this._hasIncrementedSkipCount = false; + this._lastStoredBookmark = 0L; + this._duration = playbackWrapper.Duration; + if (this._mediaType == MediaType.PodcastEpisode || this._mediaType == MediaType.Video) + { + LibraryPlaybackTrack.PodcastVideoLengthGroup videoLengthGroup = LibraryPlaybackTrack.PodcastVideoLengthGroup.Long; + while (videoLengthGroup > LibraryPlaybackTrack.PodcastVideoLengthGroup.Short && this._duration <= LibraryPlaybackTrack.c_podcastVideoLengths[(int)videoLengthGroup]) + --videoLengthGroup; + this._markPlayedAt = this._duration - LibraryPlaybackTrack.c_podcastVideoMarkPlayedAtEOFMinus[(int)videoLengthGroup]; + if (this._markPlayedAt < 1L) + this._markPlayedAt = 1L; + this._lastStoredBookmark = this.Bookmark; + if (this._lastStoredBookmark != 0L) + { + playbackWrapper.SeekToAbsolutePosition(this._lastStoredBookmark); + if (this._lastStoredBookmark > 200000000L) + this._hasIncrementedPlayCount = true; + } + if (this._mediaType == MediaType.PodcastEpisode) + { + if (this.IsVideo) + SQMLog.Log(SQMDataId.PodcastVideoEpisodePlayed, 1); + else + SQMLog.Log(SQMDataId.PodcastAudioEpisodePlayed, 1); + } + } + EMediaTypes MediaType; + switch (this.MediaType) + { + case MediaType.Track: + MediaType = EMediaTypes.eMediaTypeAudio; + break; + case MediaType.Video: + MediaType = EMediaTypes.eMediaTypeVideo; + break; + case MediaType.PodcastEpisode: + MediaType = EMediaTypes.eMediaTypePodcastEpisode; + break; + default: + MediaType = EMediaTypes.eMediaTypeInvalid; + break; + } + Microsoft.Zune.Util.Notification.BroadcastNowPlaying(MediaType, this.Album, this.DisplayArtist, this.Title, this.TrackNumber, this.ZuneMediaId); + } + + internal override void OnPositionChanged(long position) + { + bool markPlayed = false; + bool incrementPlayCount = false; + if (position <= 0L || position >= this._duration) + return; + if (!this._hasMarkedPlayed && this._markPlayedAt > 0L && position >= this._markPlayedAt) + { + this._hasMarkedPlayed = true; + markPlayed = true; + } + if (!this._hasIncrementedPlayCount && position >= 200000000L) + { + this._hasIncrementedPlayCount = true; + incrementPlayCount = true; + } + long num = 0; + if (!this._hasMarkedPlayed) + num = position / 10000000L * 10000000L; + if (this._lastStoredBookmark != num) + this._lastStoredBookmark = num; + if (!markPlayed && !incrementPlayCount) + return; + this.UpdatePlayedStates(markPlayed, incrementPlayCount, false); + } + + internal override void OnSkip() + { + if (this._hasIncrementedPlayCount || this._hasIncrementedSkipCount || this.MediaType == MediaType.PodcastEpisode) + return; + this._hasIncrementedSkipCount = true; + this.UpdatePlayedStates(false, false, true); + } + + internal override void OnEndPlayback(bool endOfMedia) + { + base.OnEndPlayback(endOfMedia); + Microsoft.Zune.Util.Notification.ResetNowPlaying(); + if (endOfMedia) + { + this._lastStoredBookmark = 0L; + if (!this._hasIncrementedPlayCount) + this.UpdatePlayedStates(false, true, false); + } + this.CommitLastStoredBookmark(); + } + + private void UpdatePlayedStates( + bool markPlayed, + bool incrementPlayCount, + bool incrementSkipCount) + { + int mediaId = this.MediaId; + if (mediaId == -1) + return; + EListType listType = this.ListType; + ContainerPlayMarker containerPlayMarker = this._containerPlayMarker; + ThreadPool.QueueUserWorkItem(new WaitCallback(LibraryPlaybackTrack.UpdatePlayedStatesWorker), (object)new LibraryPlaybackTrack.UpdatePlayedStatesTask(markPlayed, incrementPlayCount, incrementSkipCount, mediaId, listType, containerPlayMarker)); + bool flag = this._containerPlayMarker != null && this._containerPlayMarker.PlaylistType == PlaylistType.QuickMix; + if (incrementPlayCount) + { + if (this._mediaType == MediaType.Track) + ++ZuneUI.Shell.MainFrame.Social.PlayCount; + if (flag) + SQMLog.Log(SQMDataId.QuickMixTrackPlays, 1); + } + if (!incrementSkipCount || !flag) + return; + if (this.IsInVisibleCollection) + SQMLog.Log(SQMDataId.QuickMixLocalSkips, 1); + else + SQMLog.Log(SQMDataId.QuickMixRemoteSkips, 1); + } + + private static void UpdatePlayedStatesWorker(object o) + { + if (!(o is LibraryPlaybackTrack.UpdatePlayedStatesTask playedStatesTask)) + return; + int num1 = 0; + int num2 = 0; + int num3 = 0; + int[] columnIndexes = new int[7]; + object[] fieldValues = new object[7]; + if (playedStatesTask.IncrementPlayCount) + { + columnIndexes[0] = 367; + fieldValues[0] = (object)0; + ZuneLibrary.GetFieldValues(playedStatesTask.MediaID, playedStatesTask.ListType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + num2 = (int)fieldValues[0]; + columnIndexes[0] = 366; + fieldValues[0] = (object)0; + ZuneLibrary.GetFieldValues(playedStatesTask.MediaID, playedStatesTask.ListType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + num1 = (int)fieldValues[0]; + } + if (playedStatesTask.IncrementSkipCount) + { + columnIndexes[0] = 374; + fieldValues[0] = (object)0; + ZuneLibrary.GetFieldValues(playedStatesTask.MediaID, playedStatesTask.ListType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + num3 = (int)fieldValues[0]; + } + int cValues = 0; + if (playedStatesTask.MarkPlayed) + { + columnIndexes[cValues] = 262; + fieldValues[cValues] = (object)1; + ++cValues; + } + if (playedStatesTask.IncrementPlayCount) + { + int num4 = num2 + 1; + columnIndexes[cValues] = 367; + fieldValues[cValues] = (object)num4; + int index1 = cValues + 1; + int num5 = num1 + 1; + columnIndexes[index1] = 366; + fieldValues[index1] = (object)num5; + int index2 = index1 + 1; + columnIndexes[index2] = 363; + fieldValues[index2] = (object)DateTime.UtcNow; + cValues = index2 + 1; + } + if (playedStatesTask.IncrementSkipCount) + { + int num4 = num3 + 1; + columnIndexes[cValues] = 374; + fieldValues[cValues] = (object)num4; + int index = cValues + 1; + columnIndexes[index] = 365; + fieldValues[index] = (object)DateTime.UtcNow; + cValues = index + 1; + } + if (cValues > 0) + ZuneLibrary.SetFieldValues(playedStatesTask.MediaID, playedStatesTask.ListType, cValues, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + if (!playedStatesTask.IncrementPlayCount || playedStatesTask.ContainerPlayMarker == null) + return; + bool flag = false; + lock (playedStatesTask.ContainerPlayMarker) + { + if (!playedStatesTask.ContainerPlayMarker.Marked) + { + playedStatesTask.ContainerPlayMarker.Marked = true; + flag = true; + } + } + if (!flag) + return; + if (playedStatesTask.ContainerPlayMarker.LibraryId == -1 && playedStatesTask.ListType == EListType.eTrackList) + { + fieldValues[0] = (object)-1; + if (playedStatesTask.ContainerPlayMarker.MediaType == MediaType.Album) + { + columnIndexes[0] = 11; + ZuneLibrary.GetFieldValues(playedStatesTask.MediaID, playedStatesTask.ListType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + playedStatesTask.ContainerPlayMarker.LibraryId = (int)fieldValues[0]; + } + else if (playedStatesTask.ContainerPlayMarker.MediaType == MediaType.Genre) + { + columnIndexes[0] = 399; + ZuneLibrary.GetFieldValues(playedStatesTask.MediaID, playedStatesTask.ListType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + playedStatesTask.ContainerPlayMarker.LibraryId = (int)fieldValues[0]; + } + else if (playedStatesTask.ContainerPlayMarker.MediaType == MediaType.Artist) + { + columnIndexes[0] = 11; + ZuneLibrary.GetFieldValues(playedStatesTask.MediaID, playedStatesTask.ListType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + int iMediaId = (int)fieldValues[0]; + fieldValues[0] = (object)-1; + columnIndexes[0] = 78; + ZuneLibrary.GetFieldValues(iMediaId, EListType.eAlbumList, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + playedStatesTask.ContainerPlayMarker.LibraryId = (int)fieldValues[0]; + } + } + if (playedStatesTask.ContainerPlayMarker.LibraryId == -1) + return; + columnIndexes[0] = 363; + fieldValues[0] = (object)DateTime.UtcNow; + EListType listType = PlaylistManager.MediaTypeToListType(playedStatesTask.ContainerPlayMarker.MediaType); + ZuneLibrary.SetFieldValues(playedStatesTask.ContainerPlayMarker.LibraryId, listType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + } + + private void CommitLastStoredBookmark() + { + if (this.MediaType != MediaType.PodcastEpisode && this.MediaType != MediaType.Video) + return; + int[] columnIndexes = new int[1]; + object[] fieldValues = new object[1]; + columnIndexes[0] = 35; + fieldValues[0] = (object)this._lastStoredBookmark; + ZuneLibrary.SetFieldValues(this.MediaId, this.ListType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + } + + public void FindInCollection() + { + if (this._mediaType != MediaType.Track) + return; + MusicLibraryPage.FindInCollection(this.AlbumArtistLibraryId, this.AlbumLibraryId, this.MediaId); + } + + public void RatingUpdatedExternally(int newRating) + { + this._userRating = new int?(newRating); + this.RatingChanged.Invoke(); + } + + private class UpdatePlayedStatesTask + { + public readonly bool MarkPlayed; + public readonly bool IncrementPlayCount; + public readonly bool IncrementSkipCount; + public readonly int MediaID; + public readonly EListType ListType; + public readonly ContainerPlayMarker ContainerPlayMarker; + + public UpdatePlayedStatesTask( + bool markPlayed, + bool incrementPlayCount, + bool incrementSkipCount, + int mediaID, + EListType listType, + ContainerPlayMarker containerPlayMarker) + { + this.MarkPlayed = markPlayed; + this.IncrementPlayCount = incrementPlayCount; + this.IncrementSkipCount = incrementSkipCount; + this.MediaID = mediaID; + this.ListType = listType; + this.ContainerPlayMarker = containerPlayMarker; + } + } + + public enum Streaming + { + Unknown, + Yes, + No, + } + + private enum PodcastVideoLengthGroup + { + Short, + Medium, + Long, + } + } +} diff --git a/ZuneUI/LibraryVideoActionCommand.cs b/ZuneUI/LibraryVideoActionCommand.cs new file mode 100644 index 0000000..6d95dda --- /dev/null +++ b/ZuneUI/LibraryVideoActionCommand.cs @@ -0,0 +1,64 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LibraryVideoActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class LibraryVideoActionCommand : MarketplaceActionCommand + { + public override bool CanFindInCollection => false; + + protected override string ZuneMediaIdPropertyName => "ZuneMediaId"; + + public override void FindInCollection() + { + } + + public override void UpdateState() + { + this.Progress = -1f; + this.CollectionId = -1; + this.HasPoints = false; + this.Downloading = false; + bool fIsDownloadPending = false; + bool fIsHidden = false; + if (this.AllowDownload) + { + if (ZuneApplication.Service.IsDownloading(this.Id, this.ContentType, out fIsDownloadPending, out fIsHidden)) + { + this.Downloading = true; + if (fIsDownloadPending) + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_PENDING); + } + else + { + this.Description = string.Empty; + DownloadTask task = DownloadManager.Instance.GetTask(this.Id.ToString()); + if (task == null) + return; + this.UpdateProgress(this.Id, task.GetProgress()); + } + } + else + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD); + this.Downloading = false; + } + } + else + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_NOT_AVAILABLE); + this.Available = false; + } + } + + protected override EContentType ContentType => EContentType.Video; + } +} diff --git a/ZuneUI/LinkOptions.cs b/ZuneUI/LinkOptions.cs new file mode 100644 index 0000000..176e034 --- /dev/null +++ b/ZuneUI/LinkOptions.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LinkOptions +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum LinkOptions + { + Skip, + Link, + } +} diff --git a/ZuneUI/ListAndAddPaymentInstrumentStep.cs b/ZuneUI/ListAndAddPaymentInstrumentStep.cs new file mode 100644 index 0000000..43d058a --- /dev/null +++ b/ZuneUI/ListAndAddPaymentInstrumentStep.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ListAndAddPaymentInstrumentStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ListAndAddPaymentInstrumentStep : SelectPaymentInstrumentStep + { + public ListAndAddPaymentInstrumentStep( + Wizard owner, + AccountManagementWizardState state, + bool parent) + : base(owner, state, parent) + { + this.NextTextOverride = Shell.LoadString(StringId.IDS_BILLING_EDIT_CC_ADD_BTN); + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#ListAndAddPaymentInstrumentStep"; + + protected override void ResetNextTextOverride() + { + } + } +} diff --git a/ZuneUI/ListHelper.cs b/ZuneUI/ListHelper.cs new file mode 100644 index 0000000..61de15d --- /dev/null +++ b/ZuneUI/ListHelper.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ListHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public static class ListHelper + { + public static IList Merge( + IList list1, + IList list2, + bool matchesOnly, + IComparer comparer, + ListHelper.MergeObjects mergeDelegate) + { + ArrayList arrayList = new ArrayList(); + if (list1 != null && list2 != null) + { + for (int index1 = 0; index1 < list1.Count; ++index1) + { + bool flag = false; + for (int index2 = 0; index2 < list2.Count; ++index2) + { + if (comparer.Compare(list1[index1], list2[index2]) == 0) + { + arrayList.Add(mergeDelegate(list1[index1], list2[index2])); + list2.RemoveAt(index2); + flag = true; + break; + } + } + if (!flag && !matchesOnly) + arrayList.Add(mergeDelegate(list1[index1], (object)null)); + } + if (!matchesOnly) + { + foreach (object obj in (IEnumerable)list2) + arrayList.Add(mergeDelegate(obj, (object)null)); + } + } + else if (!matchesOnly && (list1 != null || list2 != null)) + { + foreach (object obj in list1 != null ? (IEnumerable)list1 : (IEnumerable)list2) + arrayList.Add(mergeDelegate(obj, (object)null)); + } + return (IList)arrayList; + } + + public delegate object MergeObjects(object item1, object item2); + } +} diff --git a/ZuneUI/ListPanel.cs b/ZuneUI/ListPanel.cs new file mode 100644 index 0000000..189c778 --- /dev/null +++ b/ZuneUI/ListPanel.cs @@ -0,0 +1,132 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ListPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System.Collections; + +namespace ZuneUI +{ + public class ListPanel : LibraryPanel + { + private IList _content; + private object _selectedItem; + + public ListPanel() + : this((IModelItemOwner)null) + { + } + + public ListPanel(IModelItemOwner owner) + : base(owner) + { + } + + public IList Content + { + get => this._content; + set + { + if (this._content == value) + return; + this._content = value; + this.FirePropertyChanged(nameof(Content)); + } + } + + public object SelectedItem + { + get => this._selectedItem; + set + { + if (this._selectedItem == value) + return; + if (this._selectedItem is ModelItem selectedItem) + selectedItem.Selected = false; + if (value is ModelItem modelItem) + modelItem.Selected = true; + this._selectedItem = value; + this.FirePropertyChanged(nameof(SelectedItem)); + } + } + + public virtual IList SelectedLibraryIds + { + get => (IList)null; + set + { + } + } + + public int GetIndexFromLibraryId(int libraryIdToFind) + { + int num1 = -1; + int num2 = 0; + if (this.Content != null) + { + foreach (object obj in (IEnumerable)this.Content) + { + if (obj is LibraryDataProviderItemBase providerItemBase && (int)providerItemBase.GetProperty("LibraryId") == libraryIdToFind) + { + num1 = num2; + break; + } + ++num2; + } + } + return num1; + } + + public IList ComputeSelectedIndicies() + { + ArrayList arrayList1; + if (this.SelectedLibraryIds != null && this.Content != null) + { + arrayList1 = new ArrayList(this.SelectedLibraryIds.Count); + if (!this.IsContentDisposed()) + { + ArrayList arrayList2 = new ArrayList((ICollection)this.SelectedLibraryIds); + int num = 0; + foreach (object obj in (IEnumerable)this.Content) + { + if (obj is LibraryDataProviderItemBase providerItemBase) + { + int property = (int)providerItemBase.GetProperty("LibraryId"); + if (arrayList2.Contains((object)property)) + { + arrayList1.Add((object)num); + arrayList2.Remove((object)property); + if (arrayList2.Count == 0) + break; + } + } + ++num; + } + } + } + else + arrayList1 = new ArrayList(); + return (IList)arrayList1; + } + + internal override void Release() + { + this.Content = (IList)null; + base.Release(); + } + + private bool IsContentDisposed() + { + if (this.Content is LibraryVirtualList content) + { + ZuneQueryList queryList = content.QueryList; + if (queryList != null) + return queryList.IsDisposed; + } + return false; + } + } +} diff --git a/ZuneUI/ListReleaseBehaviorManager.cs b/ZuneUI/ListReleaseBehaviorManager.cs new file mode 100644 index 0000000..5cbe8c1 --- /dev/null +++ b/ZuneUI/ListReleaseBehaviorManager.cs @@ -0,0 +1,38 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ListReleaseBehaviorManager +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System.Collections; + +namespace ZuneUI +{ + public class ListReleaseBehaviorManager + { + private LibraryVirtualList _virtualList; + private ReleaseBehavior _cachedBehavior; + + public void KeepItemsInMemory(IList list) + { + if (list == null || list.Count <= 0) + return; + LibraryVirtualList owner = ((LibraryDataProviderListItem)list[0]).GetOwner(); + if (owner.VisualReleaseBehavior != ReleaseBehavior.ReleaseReference) + return; + this._cachedBehavior = owner.VisualReleaseBehavior; + owner.VisualReleaseBehavior = ReleaseBehavior.KeepReference; + this._virtualList = owner; + } + + public void RestoreDefaultBehavior() + { + if (this._virtualList == null) + return; + this._virtualList.VisualReleaseBehavior = this._cachedBehavior; + this._virtualList = (LibraryVirtualList)null; + } + } +} diff --git a/ZuneUI/LocalizationHelper.cs b/ZuneUI/LocalizationHelper.cs new file mode 100644 index 0000000..195c10c --- /dev/null +++ b/ZuneUI/LocalizationHelper.cs @@ -0,0 +1,37 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.LocalizationHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Shell; +using System; +using System.IO; + +namespace ZuneUI +{ + public static class LocalizationHelper + { + public static string GetLocalizedFolderName(string path) + { + try + { + string fileName = LocalizationHelper.GetLocalizedFolderPath(path); + FileInfo fileInfo = new FileInfo(fileName); + if (!string.IsNullOrEmpty(fileInfo.Name)) + fileName = fileInfo.Name; + return fileName; + } + catch (Exception ex) + { + return path; + } + } + + public static string GetLocalizedFolderPath(string path) + { + string localizedPath; + return !string.IsNullOrEmpty(path) && ((HRESULT)ZuneApplication.ZuneLibrary.GetLocalizedPathOfFolder(path, false, out localizedPath)).IsSuccess ? localizedPath : path; + } + } +} diff --git a/ZuneUI/MainFrame.cs b/ZuneUI/MainFrame.cs new file mode 100644 index 0000000..748c1d2 --- /dev/null +++ b/ZuneUI/MainFrame.cs @@ -0,0 +1,175 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MainFrame +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System.Collections; + +namespace ZuneUI +{ + public class MainFrame : Frame + { + private ArrayListDataSet _experiences; + private QuickplayExperience _quickplay; + private CollectionExperience _collection; + private DeviceExperience _device; + private MarketplaceExperience _marketplace; + private SocialExperience _social; + private TestExperience _test; + private DiscExperience _disc; + + public MainFrame(IModelItemOwner owner) + : base(owner) + { + } + + public override IList ExperiencesList + { + get + { + if (this._experiences == null) + { + this._experiences = new ArrayListDataSet((IModelItemOwner)this); + if (FeatureEnablement.IsFeatureEnabled(Features.eQuickplay)) + this._experiences.Add((object)this.Quickplay); + this._experiences.Add((object)this.Collection); + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace)) + this._experiences.Add((object)this.Marketplace); + if (FeatureEnablement.IsFeatureEnabled(Features.eSocial)) + this._experiences.Add((object)this.Social); + } + return (IList)this._experiences; + } + } + + public QuickplayExperience Quickplay + { + get + { + if (this._quickplay == null) + this._quickplay = new QuickplayExperience((Frame)this); + return this._quickplay; + } + } + + public CollectionExperience Collection + { + get + { + if (this._collection == null) + this._collection = new CollectionExperience((Frame)this); + return this._collection; + } + } + + public MarketplaceExperience Marketplace + { + get + { + if (this._marketplace == null) + this._marketplace = new MarketplaceExperience((Frame)this); + return this._marketplace; + } + } + + public SocialExperience Social + { + get + { + if (this._social == null) + this._social = new SocialExperience((Frame)this); + return this._social; + } + } + + public DeviceExperience Device + { + get + { + if (this._device == null) + { + this._device = new DeviceExperience((Frame)this); + this._device.UpdateShowDevice(); + } + return this._device; + } + } + + public TestExperience Test + { + get + { + if (this._test == null) + this._test = new TestExperience((Frame)this); + return this._test; + } + } + + public DiscExperience Disc + { + get + { + if (this._disc == null) + { + this._disc = new DiscExperience((Frame)this); + IList experiencesList = this.ExperiencesList; + if (experiencesList == null || experiencesList[experiencesList.Count - 1] != this._disc) + this._disc.Available = false; + } + return this._disc; + } + } + + internal void ShowDevice(bool show) + { + IList experiencesList = this.ExperiencesList; + int index = experiencesList.Count - 1; + bool flag = experiencesList[index] == this.Device || index > 0 && experiencesList[index - 1] == this.Device; + if (show == flag) + return; + this.Device.Available = show; + if (show) + { + if (experiencesList[index] == this.Disc) + experiencesList.Insert(index, (object)this.Device); + else + experiencesList.Add((object)this.Device); + } + else + experiencesList.Remove((object)this.Device); + } + + internal void ShowDisc(bool show) + { + IList experiencesList = this.ExperiencesList; + int index = experiencesList.Count - 1; + bool flag = experiencesList[index] == this.Disc; + if (show == flag) + return; + this.Disc.Available = show; + if (show) + experiencesList.Add((object)this.Disc); + else + experiencesList.RemoveAt(index); + } + + internal void ShowTest(bool show) + { + IList experiencesList = this.ExperiencesList; + bool flag = experiencesList.Contains((object)this.Test); + int index = experiencesList.Count - 1; + while (index >= 0 && (experiencesList[index] == this.Disc || experiencesList[index] == this.Device)) + --index; + if (show == flag) + return; + this.Test.Available = show; + if (show) + experiencesList.Insert(index + 1, (object)this.Test); + else + experiencesList.Remove((object)this.Test); + } + } +} diff --git a/ZuneUI/Management.cs b/ZuneUI/Management.cs new file mode 100644 index 0000000..dadbf89 --- /dev/null +++ b/ZuneUI/Management.cs @@ -0,0 +1,2188 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Management +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Subscription; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Threading; +using UIXControls; + +namespace ZuneUI +{ + public class Management : ModelItem + { + private static CategoryPage _currentCategoryPage; + private Category _alertedDeviceCategory; + private DeviceManagement _deviceManagement; + private bool _deviceManagementLocked; + private CommitListHashtable _commitList; + private bool _hasPendingCommits; + private bool _changeRequiresElevation; + private BooleanChoice _sqmChoice; + private ListDataSet _monitoredAudioFolders; + private ListDataSet _monitoredPhotoFolders; + private ListDataSet _monitoredPodcastFolders; + private ListDataSet _monitoredVideoFolders; + private BooleanChoice _mediaInfoChoice; + private BooleanChoice _metadataChoice; + private List _removedMonitoredFoldersToRemoveFromCollection; + private ProxySettingDelegate[] _actionsToCommitOnLibraryIntegrate; + private Choice _podcastDefaultKeepEpisodesChoice; + private Choice _podcastPlaybackChoice; + private string[] _defaultFileTypeExtensions = new string[7] + { + ".mp3", + ".m4a", + ".mp4", + ".m4b", + ".m4v", + ".mbr", + ".zpl" + }; + private Microsoft.Zune.Configuration.IFileAssociationHandler _fileAssocHandler; + private IList _allFileTypes; + private IList _audioFileTypes; + private IList _videoFileTypes; + private IList _fileAssociationInfoList; + private bool _canFileAssociationBeChanged; + private ITunerInfoHandler _tunerHandler; + private ArrayListDataSet _registeredComputersModelList; + private ArrayListDataSet _registeredDevicesModelList; + private ArrayListDataSet _registeredAppStoreDevicesModelList; + private string _nextPCDeregistrationDate; + private string _nextSubscriptionDeviceDeregistrationDate; + private string _nextAppStoreDeviceDeregistrationDate; + private IntRangedValue _slideShowSpeed; + private Choice _burnDiscFormat; + private BooleanChoice _autoEjectCDAfterBurn; + private Choice _burnSpeed; + private Choice _recordMode; + private Choice _recordRate; + private BooleanChoice _autoCopyCD; + private BooleanChoice _autoEjectCD; + private string _mediaFolder; + private string _videoMediaFolder; + private string _photoMediaFolder; + private string _podcastMediaFolder; + private Choice _wmaRate; + private Choice _wmavRate; + private Choice _mp3Rate; + private string _sharingError; + private string _sharingDisplayName; + private BooleanChoice _sharingEnableMusic; + private BooleanChoice _sharingEnableVideo; + private BooleanChoice _sharingEnablePhoto; + private Choice _sharingSelectDeviceChoice; + private IList _sharingSelectDeviceOptions; + private bool _sharingAllDevicesEnabled; + private IList _sharingDeviceList; + private uint _sharingDeviceIndex; + private HMESettings _HME; + private bool _nssDeviceListChangeEventAdded; + private string _backgroundImage; + private WindowColor _backgroundColor; + private BooleanChoice _showNowPlayingBackgroundOnIdle; + private Choice _screenGraphicsSlider; + private BooleanChoice _playSounds; + private BooleanChoice _compactModeAlwaysOnTop; + private BooleanChoice _ratingsChoice; + private BooleanChoice _applyRatingsChoice; + private Choice _startupPageChoice; + private bool _autoLaunchZuneOnConnect; + private object mylock = new object(); + + public Management() + { + this._autoLaunchZuneOnConnect = ClientConfiguration.Devices.AutoLaunchZuneOnConnect; + ClientConfiguration.Groveler.OnConfigurationChanged += new ConfigurationChangeEventHandler(this.OnGrovelerConfigurationChanged); + this._actionsToCommitOnLibraryIntegrate = new ProxySettingDelegate[5] + { + new ProxySettingDelegate(this.OnMonitoredFoldersCommit), + new ProxySettingDelegate(this.OnMediaFolderCommit), + new ProxySettingDelegate(this.OnVideoMediaFolderCommit), + new ProxySettingDelegate(this.OnPhotoMediaFolderCommit), + new ProxySettingDelegate(this.OnPodcastMediaFolderCommit) + }; + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + this.DisposeDeviceManagement(true); + ClientConfiguration.Groveler.OnConfigurationChanged -= new ConfigurationChangeEventHandler(this.OnGrovelerConfigurationChanged); + } + if (this._fileAssocHandler != null) + { + ((IDisposable)this._fileAssocHandler).Dispose(); + this._fileAssocHandler = (Microsoft.Zune.Configuration.IFileAssociationHandler)null; + } + base.OnDispose(disposing); + } + + private Microsoft.Zune.Configuration.IFileAssociationHandler FileAssocHandler + { + get + { + if (this._fileAssocHandler == null) + this._fileAssocHandler = FileAssociationHandlerFactory.CreateFileAssociationHandler(); + return this._fileAssocHandler; + } + } + + public DeviceManagement DeviceManagement + { + get + { + if (this._deviceManagement == null && !this.DeviceManagementLocked) + this._deviceManagement = new DeviceManagement(); + return this._deviceManagement; + } + } + + public bool DeviceManagementLocked + { + get => this._deviceManagementLocked; + private set + { + if (this._deviceManagementLocked == value) + return; + this._deviceManagementLocked = value; + this.FirePropertyChanged(nameof(DeviceManagementLocked)); + } + } + + public void DisposeDeviceManagement(bool deviceManagementLocked) + { + this.DeviceManagementLocked = deviceManagementLocked; + if (this._deviceManagement == null) + return; + UIDevice currentDeviceOverride = SyncControls.Instance.CurrentDeviceOverride; + if (currentDeviceOverride.IsValid) + { + this.CommitList.RemoveByIntValue(currentDeviceOverride.IsGuest ? -1 : currentDeviceOverride.ID); + this.CommitList.RemoveByStringValue("OnSyncPartnershipCommit"); + } + else + this.CommitList.RemoveByIntValue(-1); + this._deviceManagement.Dispose(); + this._deviceManagement = (DeviceManagement)null; + this.FirePropertyChanged("DeviceManagementChanged"); + } + + public bool DeviceManagementChanged => true; + + public CommitListHashtable CommitList + { + get + { + if (this._commitList == null) + this._commitList = new CommitListHashtable(); + return this._commitList; + } + set + { + if (this._commitList == value) + return; + this._commitList = value; + this.FirePropertyChanged(nameof(CommitList)); + if (value != null) + return; + this.HasPendingCommits = false; + } + } + + public bool HasPendingCommits + { + get => this._hasPendingCommits; + internal set + { + if (this._hasPendingCommits == value) + return; + this._hasPendingCommits = value; + this.FirePropertyChanged(nameof(HasPendingCommits)); + } + } + + public bool ActiveDeviceHasPendingCommits => this.CommitList.ContainsIntValue(SyncControls.Instance.CurrentDevice.ID); + + public bool ChangeRequiresElevation + { + get => this._changeRequiresElevation; + set + { + if (this._changeRequiresElevation == value) + return; + this._changeRequiresElevation = value; + this.FirePropertyChanged(nameof(ChangeRequiresElevation)); + } + } + + public string BuildNumber => VersionInfo.BuildNumber; + + public Choice RecordMode + { + get + { + if (this._recordMode == null) + { + this._wmaRate = new Choice((IModelItemOwner)this); + this._wmaRate.Options = (IList)new NamedIntOption[6] + { + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMA_48), 48000), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMA_64), 64000), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMA_96), 96000), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMA_128), 128000), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMA_160), 160000), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMA_192), 192000) + }; + NamedIntOption.SelectOptionByValue(this._wmaRate, ClientConfiguration.Recorder.WMARecordRate); + this._wmaRate.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnWmaRateCommit)] = (object)null); + this._wmavRate = new Choice((IModelItemOwner)this); + this._wmavRate.Options = (IList)new NamedIntOption[5] + { + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMAV_25), 25), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMAV_50), 50), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMAV_75), 75), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMAV_90), 90), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_WMAV_98), 98) + }; + NamedIntOption.SelectOptionByValue(this._wmavRate, ClientConfiguration.Recorder.WMAVBRRecordQuality); + this._wmavRate.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnWmavRateCommit)] = (object)null); + this._mp3Rate = new Choice((IModelItemOwner)this); + this._mp3Rate.Options = (IList)new NamedIntOption[4] + { + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_MP3_128), 128000), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_MP3_192), 192000), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_MP3_256), 256000), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_RIP_MP3_320), 320000) + }; + NamedIntOption.SelectOptionByValue(this._mp3Rate, ClientConfiguration.Recorder.MP3RecordRate); + this._mp3Rate.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnMp3RateCommit)] = (object)null); + this._recordMode = new Choice((IModelItemOwner)this); + this._recordMode.Options = (IList)new RecordModeOption[4] + { + new RecordModeOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_WMA_OPTION), 0, this._wmaRate), + new RecordModeOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_WMA_VARIABLE_OPTION), 3, this._wmavRate), + new RecordModeOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_WMA_LOSSLESS_OPTION), 1, (Choice) null), + new RecordModeOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_MP3_OPTION), 2, this._mp3Rate) + }; + NamedIntOption.SelectOptionByValue(this._recordMode, ClientConfiguration.Recorder.RecordMode); + this._recordMode.ChosenChanged += (EventHandler)((sender, args) => + { + this.CommitList[(object)new ProxySettingDelegate(this.OnRecordModeCommit)] = (object)null; + this.RecordRate = ((RecordModeOption)this._recordMode.ChosenValue).BitRate; + }); + this.RecordRate = ((RecordModeOption)this._recordMode.ChosenValue).BitRate; + } + return this._recordMode; + } + } + + private void OnWmaRateCommit(object data) => ClientConfiguration.Recorder.WMARecordRate = ((NamedIntOption)this._wmaRate.ChosenValue).Value; + + private void OnWmavRateCommit(object data) => ClientConfiguration.Recorder.WMAVBRRecordQuality = ((NamedIntOption)this._wmavRate.ChosenValue).Value; + + private void OnMp3RateCommit(object data) => ClientConfiguration.Recorder.MP3RecordRate = ((NamedIntOption)this._mp3Rate.ChosenValue).Value; + + private void OnRecordModeCommit(object data) => ClientConfiguration.Recorder.RecordMode = ((NamedIntOption)this._recordMode.ChosenValue).Value; + + public Choice RecordRate + { + get => this._recordRate; + private set + { + if (this._recordRate == value) + return; + this._recordRate = value; + this.FirePropertyChanged(nameof(RecordRate)); + } + } + + public Category AlertedDeviceCategory + { + get => this._alertedDeviceCategory; + set + { + if (this._alertedDeviceCategory == value) + return; + if (Management._currentCategoryPage != null && value != null && this._alertedDeviceCategory != null) + { + Management._currentCategoryPage.CurrentCategory = this._alertedDeviceCategory; + this._alertedDeviceCategory = (Category)null; + } + else + { + this._alertedDeviceCategory = value; + this.FirePropertyChanged(nameof(AlertedDeviceCategory)); + } + } + } + + public CategoryPage CurrentCategoryPage + { + get => Management._currentCategoryPage; + set + { + if (Management._currentCategoryPage == value) + return; + Management._currentCategoryPage = value; + this.FirePropertyChanged(nameof(CurrentCategoryPage)); + } + } + + public static void NavigateToSetupLandWizard(SetupLandPage page) => Management.NavigateAwayFromCategory((Command)new SetupLandWizardNavigationCommand(page)); + + public static void NavigateToCategory(Category category) + { + if (ZuneShell.DefaultInstance.Management.CurrentCategoryPage == null) + return; + ZuneShell.DefaultInstance.Management.CurrentCategoryPage.CurrentCategory = category; + } + + public static void NavigateAwayFromCategory(Command confirmed) + { + Management management = ZuneShell.DefaultInstance.Management; + if (management.HasPendingCommits) + { + Command yesCommand = new Command((IModelItemOwner)null, ZuneUI.Shell.LoadString(StringId.IDS_DIALOG_YES), (EventHandler)null); + yesCommand.Invoked += (EventHandler)((sender, args) => + { + management.CommitListSave(); + Management.NavigateAwayFromCategory(confirmed); + }); + Command noCommand = new Command((IModelItemOwner)null, ZuneUI.Shell.LoadString(StringId.IDS_DIALOG_NO), (EventHandler)null); + noCommand.Invoked += (EventHandler)((sender, args) => + { + management.CommitList = (CommitListHashtable)null; + Management.NavigateAwayFromCategory(confirmed); + }); + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_SAVE_CHANGES_DIALOG_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_SAVE_CHANGES_ON_BACK_DIALOG_TEXT), yesCommand, noCommand, (BooleanChoice)null); + } + else + { + if (ZuneUI.Shell.SettingsFrame.IsCurrent && !ZuneUI.Shell.SettingsFrame.Wizard.FUE.IsCurrent && management.CurrentCategoryPage != null) + management.CurrentCategoryPage.CancelAndExit(); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + confirmed?.Invoke(); + }, (object)null); + } + } + + public void CommitListSave() + { + this.CheckForAutomatedRequirements(); + this.CommitList.Save(); + } + + public void CheckForAutomatedRequirements() + { + if (DeviceManagement.SetupDevice == null) + return; + this.DeviceManagement.CheckForAutomatedRequirements(); + } + + public bool CanFileAssociationBeChanged + { + get => this._canFileAssociationBeChanged; + private set + { + if (this._canFileAssociationBeChanged == value) + return; + this._canFileAssociationBeChanged = value; + this.FirePropertyChanged(nameof(CanFileAssociationBeChanged)); + } + } + + public SubscriptionState SubscribeToChannelFeed( + bool isPersonalChannel, + Guid channelId, + string feedUrl, + string title, + ESubscriptionSource source) + { + return this.SubscribeToFeed(feedUrl, title, channelId, isPersonalChannel, source, EMediaTypes.eMediaTypePlaylist, ZuneUI.Shell.LoadString(StringId.IDS_PLAYLIST_SUBSCRIPTION_ERROR)); + } + + public SubscriptionState SubscribeToPodcastFeed( + string feedUrl, + string title, + ESubscriptionSource source) + { + return this.SubscribeToPodcastFeed(feedUrl, title, Guid.Empty, source); + } + + public SubscriptionState SubscribeToPodcastFeed( + string feedUrl, + string title, + Guid serviceId, + ESubscriptionSource source) + { + return this.SubscribeToFeed(feedUrl, title, serviceId, false, source, EMediaTypes.eMediaTypePodcastSeries, ZuneUI.Shell.LoadString(StringId.IDS_PODCAST_SUBSCRIPTION_ERROR)); + } + + private SubscriptionState SubscribeToFeed( + string feedUrl, + string title, + Guid serviceId, + bool isPersonalChannel, + ESubscriptionSource source, + EMediaTypes mediaType, + string errorDialogHeader) + { + int subscriptionMediaId = 0; + SubscriptionState subscriptionState = (SubscriptionState)null; + HRESULT hresult = (HRESULT)SubscriptionManager.Instance.Subscribe(feedUrl, title, serviceId, isPersonalChannel, mediaType, source, out subscriptionMediaId); + if (hresult.IsSuccess) + subscriptionState = new SubscriptionState(true, true, subscriptionMediaId); + else + ErrorDialogInfo.Show(hresult.Int, errorDialogHeader); + return subscriptionState; + } + + public SubscriptionState GetSubscriptionState( + string feedURL, + EMediaTypes subscriptionType) + { + if (string.IsNullOrEmpty(feedURL)) + return (SubscriptionState)null; + try + { + int subscriptionMediaId = -1; + bool isSubscribed; + bool byUrl = SubscriptionManager.Instance.FindByUrl(feedURL, subscriptionType, out subscriptionMediaId, out isSubscribed); + return new SubscriptionState(isSubscribed, byUrl, subscriptionMediaId); + } + catch (ApplicationException ex) + { + } + return (SubscriptionState)null; + } + + public SubscriptionState GetSubscriptionState( + Guid serviceId, + EMediaTypes subscriptionType) + { + if (serviceId == Guid.Empty) + return (SubscriptionState)null; + try + { + int subscriptionMediaId = -1; + bool isSubscribed; + bool byServiceId = SubscriptionManager.Instance.FindByServiceId(serviceId, subscriptionType, out subscriptionMediaId, out isSubscribed); + return new SubscriptionState(isSubscribed, byServiceId, subscriptionMediaId); + } + catch (ApplicationException ex) + { + } + return (SubscriptionState)null; + } + + private void OnGrovelerConfigurationChanged(object sender, ConfigurationChangeEventArgs e) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!this.UsingWin7Libraries) + return; + if (e.PropertyName == "RipDirectory" || e.PropertyName == "MonitoredAudioFolders") + { + if (this._monitoredAudioFolders != null) + { + this._monitoredAudioFolders = (ListDataSet)null; + this.FirePropertyChanged("MonitoredAudioFolders"); + } + if (this._mediaFolder == null) + return; + this._mediaFolder = (string)null; + this.FirePropertyChanged("MediaFolder"); + } + else if (e.PropertyName == "PhotoMediaFolder" || e.PropertyName == "MonitoredPhotoFolders") + { + if (this._monitoredPhotoFolders != null) + { + this._monitoredPhotoFolders = (ListDataSet)null; + this.FirePropertyChanged("MonitoredPhotoFolders"); + } + if (this._photoMediaFolder == null) + return; + this._photoMediaFolder = (string)null; + this.FirePropertyChanged("PhotoMediaFolder"); + } + else if (e.PropertyName == "PodcastMediaFolder" || e.PropertyName == "MonitoredPodcastFolders") + { + if (this._monitoredPodcastFolders != null) + { + this._monitoredPodcastFolders = (ListDataSet)null; + this.FirePropertyChanged("MonitoredPodcastFolders"); + } + if (this._podcastMediaFolder == null) + return; + this._podcastMediaFolder = (string)null; + this.FirePropertyChanged("PodcastMediaFolder"); + } + else + { + if (!(e.PropertyName == "VideoMediaFolder") && !(e.PropertyName == "MonitoredVideoFolders")) + return; + if (this._monitoredVideoFolders != null) + { + this._monitoredVideoFolders = (ListDataSet)null; + this.FirePropertyChanged("MonitoredVideoFolders"); + } + if (this._videoMediaFolder == null) + return; + this._videoMediaFolder = (string)null; + this.FirePropertyChanged("VideoMediaFolder"); + } + }, (object)null); + + public ListDataSet MonitoredAudioFolders + { + get + { + if (this._monitoredAudioFolders == null) + { + if (this.UsingWin7Libraries) + this._monitoredAudioFolders = this.StringsToListDataSet((object)ClientConfiguration.Groveler.RipDirectory, (object)ClientConfiguration.Groveler.MonitoredAudioFolders); + else + this._monitoredAudioFolders = this.StringsToListDataSet((object)ClientConfiguration.Groveler.MonitoredAudioFolders); + } + return this._monitoredAudioFolders; + } + } + + public ListDataSet MonitoredPhotoFolders + { + get + { + if (this._monitoredPhotoFolders == null) + { + if (this.UsingWin7Libraries) + this._monitoredPhotoFolders = this.StringsToListDataSet((object)ClientConfiguration.Groveler.PhotoMediaFolder, (object)ClientConfiguration.Groveler.MonitoredPhotoFolders); + else + this._monitoredPhotoFolders = this.StringsToListDataSet((object)ClientConfiguration.Groveler.MonitoredPhotoFolders); + } + return this._monitoredPhotoFolders; + } + } + + public ListDataSet MonitoredPodcastFolders + { + get + { + if (this._monitoredPodcastFolders == null) + { + if (this.UsingWin7Libraries) + this._monitoredPodcastFolders = this.StringsToListDataSet((object)ClientConfiguration.Groveler.PodcastMediaFolder, (object)ClientConfiguration.Groveler.MonitoredPodcastFolders); + else + this._monitoredPodcastFolders = this.StringsToListDataSet((object)ClientConfiguration.Groveler.MonitoredPodcastFolders); + } + return this._monitoredPodcastFolders; + } + } + + public ListDataSet MonitoredVideoFolders + { + get + { + if (this._monitoredVideoFolders == null) + { + if (this.UsingWin7Libraries) + this._monitoredVideoFolders = this.StringsToListDataSet((object)ClientConfiguration.Groveler.VideoMediaFolder, (object)ClientConfiguration.Groveler.MonitoredVideoFolders); + else + this._monitoredVideoFolders = this.StringsToListDataSet((object)ClientConfiguration.Groveler.MonitoredVideoFolders); + } + return this._monitoredVideoFolders; + } + } + + public bool Win7LibrariesAreAvailable => OSVersion.IsWin7(); + + public bool UsingWin7Libraries => this.Win7LibrariesAreAvailable && ClientConfiguration.Groveler.LibrarySync != -1; + + public void UseWin7Libraries() + { + foreach (ProxySettingDelegate proxySettingDelegate in this._actionsToCommitOnLibraryIntegrate) + { + if (this.CommitList.ContainsKey((object)proxySettingDelegate)) + { + this.CommitList.Remove((object)proxySettingDelegate); + proxySettingDelegate((object)null); + } + } + SQMLog.Log(SQMDataId.ZuneWin7LibraryOpt, 0); + this.SetWin7LibrariesUsage(Win7LibrariesUsage.BeginIntegration); + } + + public void DoNotUseWin7Libraries() + { + SQMLog.Log(SQMDataId.ZuneWin7LibraryOpt, 1); + this.SetWin7LibrariesUsage(Win7LibrariesUsage.DoNotIntegrate); + } + + private void SetWin7LibrariesUsage(Win7LibrariesUsage usage) + { + ClientConfiguration.Groveler.LibrarySync = (int)usage; + this.FirePropertyChanged("UsingWin7Libraries"); + } + + private ListDataSet StringsToListDataSet(params object[] source) + { + ListDataSet listDataSet = (ListDataSet)new ArrayListDataSet((IModelItemOwner)this); + if (source != null && source.Length > 0) + { + Dictionary dictionary = new Dictionary(); + foreach (object obj in source) + { + if (obj != null) + { + if (!(obj is IEnumerable strings)) + strings = (IEnumerable)new string[1] + { + obj.ToString() + }; + if (strings != null) + { + foreach (string str in strings) + { + if (!string.IsNullOrEmpty(str)) + { + string lower = str.ToLower(); + if (!dictionary.ContainsKey(lower)) + { + dictionary.Add(lower, (object)null); + listDataSet.Add((object)str); + } + } + } + } + } + } + } + listDataSet.Sort(); + return listDataSet; + } + + private IList ListDataSetToIList(ListDataSet listDataSet) + { + if (listDataSet == null) + return (IList)new List(); + IList stringList = (IList)new List(listDataSet.Count); + for (int itemIndex = 0; itemIndex < listDataSet.Count; ++itemIndex) + stringList.Add((string)listDataSet[itemIndex]); + return stringList; + } + + internal bool IsMonitored(ListDataSet monitoredFolders, string path) + { + DirectoryInfo directoryInfo = new DirectoryInfo(path); + foreach (string monitoredFolder in monitoredFolders) + { + if (this.IsSubfolder(monitoredFolder, path)) + return true; + } + return false; + } + + private bool IsSubfolder(string root, string subfolder) + { + try + { + for (; subfolder != null; subfolder = Path.GetDirectoryName(subfolder)) + { + if (subfolder.Equals(root, StringComparison.OrdinalIgnoreCase)) + return true; + } + } + catch (ArgumentException ex) + { + } + catch (PathTooLongException ex) + { + } + return false; + } + + public void AddMonitoredFolder(ListDataSet monitoredFolders) => FolderBrowseDialog.Show(ZuneUI.Shell.LoadString(StringId.IDS_ADD_MONITORED_FOLDER_DIALOG_TITLE), (DeferredInvokeHandler)(args => + { + if (args == null) + return; + string str = (string)args; + if (ZuneApplication.ZuneLibrary.CanAddFromFolder(str)) + this.AddMonitoredFolder(monitoredFolders, str, false); + else + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_INVALID_MONITORED_FOLDER_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_INVALID_MONITORED_FOLDER_MESSAGE), (EventHandler)null); + })); + + public void AddMonitoredFolder(ListDataSet monitoredFolders, string path, bool commit) + { + bool flag = false; + for (int itemIndex = 0; itemIndex < monitoredFolders.Count; ++itemIndex) + { + if (monitoredFolders[itemIndex].Equals((object)path)) + { + flag = true; + break; + } + } + if (!flag) + monitoredFolders.Add((object)path); + this.SaveMonitoredFolders(commit); + } + + public void OpenMediaFile() => FileOpenDialog.Show(ZuneUI.Shell.LoadString(StringId.IDS_OPEN_FILE_DIALOG_TITLE), this.MediaFolder, (DeferredInvokeHandler)(args => { })); + + public bool RemoveChildMonitoredFolders(string path, bool commit) + { + bool flag = false | this.RemoveChildMonitoredFolders(this.MonitoredAudioFolders, EMediaTypes.eMediaTypeAudio, path) | this.RemoveChildMonitoredFolders(this.MonitoredPhotoFolders, EMediaTypes.eMediaTypeImage, path) | this.RemoveChildMonitoredFolders(this.MonitoredPodcastFolders, EMediaTypes.eMediaTypePodcastEpisode, path) | this.RemoveChildMonitoredFolders(this.MonitoredVideoFolders, EMediaTypes.eMediaTypeVideo, path); + this.SaveMonitoredFolders(commit); + return flag; + } + + private bool RemoveChildMonitoredFolders( + ListDataSet monitoredFolders, + EMediaTypes type, + string path) + { + EWin7LibraryKind libraryKind; + switch (type) + { + case EMediaTypes.eMediaTypeAudio: + libraryKind = EWin7LibraryKind.eMusicLibrary; + break; + case EMediaTypes.eMediaTypeVideo: + libraryKind = EWin7LibraryKind.eVideoLibrary; + break; + case EMediaTypes.eMediaTypeImage: + libraryKind = EWin7LibraryKind.ePicturesLibrary; + break; + case EMediaTypes.eMediaTypePodcastEpisode: + libraryKind = EWin7LibraryKind.ePodcastLibrary; + break; + default: + return false; + } + List intList = new List(); + for (int itemIndex = 0; itemIndex < monitoredFolders.Count; ++itemIndex) + { + if (this.IsSubfolder(path, (string)monitoredFolders[itemIndex])) + intList.Add(itemIndex); + } + foreach (int num in intList) + { + if (this.UsingWin7Libraries) + Win7ShellManager.Instance.RemoveLocationFromLibrary(libraryKind, out bool _, (string)monitoredFolders[num]); + else + this.RemoveMonitoredFolder(monitoredFolders, num, type); + } + return intList.Count > 0; + } + + public void RemoveMonitoredFolder(ListDataSet monitoredFolders, string path, bool commit) + { + for (int index = 0; index < monitoredFolders.Count; ++index) + { + if (path.Equals((string)monitoredFolders[index], StringComparison.OrdinalIgnoreCase)) + { + this.RemoveMonitoredFolder(monitoredFolders, index, commit); + break; + } + } + } + + private void RemoveMonitoredFolder(ListDataSet monitoredFolders, int index) => this.RemoveMonitoredFolder(monitoredFolders, index, false); + + public void RemoveMonitoredFolder( + ListDataSet monitoredFolders, + int index, + EMediaTypes mediaType) + { + if (this._removedMonitoredFoldersToRemoveFromCollection == null) + this._removedMonitoredFoldersToRemoveFromCollection = new List(); + this._removedMonitoredFoldersToRemoveFromCollection.Add(new Management.MonitoredFolder((string)monitoredFolders[index], mediaType)); + this.RemoveMonitoredFolder(monitoredFolders, index, false); + } + + private void RemoveMonitoredFolder(ListDataSet monitoredFolders, int index, bool commit) + { + monitoredFolders.RemoveAt(index); + this.SaveMonitoredFolders(commit); + } + + private void SaveMonitoredFolders() => this.SaveMonitoredFolders(false); + + public void SaveMonitoredFolders(bool commit) + { + if (commit) + this.OnMonitoredFoldersCommit((object)null); + else + this.CommitList[(object)new ProxySettingDelegate(this.OnMonitoredFoldersCommit)] = (object)null; + } + + public void OpenLibraryDialog(EMediaTypes mediaType) + { + IntPtr winHandle = Application.Window.Handle; + Thread thread = new Thread((ParameterizedThreadStart)(args => + { + EWin7LibraryKind libraryKind = EWin7LibraryKind.eMusicLibrary; + switch (mediaType) + { + case EMediaTypes.eMediaTypeAudio: + libraryKind = EWin7LibraryKind.eMusicLibrary; + break; + case EMediaTypes.eMediaTypeVideo: + libraryKind = EWin7LibraryKind.eVideoLibrary; + break; + case EMediaTypes.eMediaTypeImage: + libraryKind = EWin7LibraryKind.ePicturesLibrary; + break; + case EMediaTypes.eMediaTypePodcastEpisode: + libraryKind = EWin7LibraryKind.ePodcastLibrary; + break; + } + Win7ShellManager.Instance.ShowLibraryDialog(libraryKind, winHandle, (string)null, (string)null); + })); + thread.TrySetApartmentState(ApartmentState.STA); + thread.Start(); + } + + private void OnMonitoredFoldersCommit(object data) + { + SQMLog.LogToStream(SQMDataId.MonitoredAudioFolders, (uint)this.MonitoredAudioFolders.Count); + SQMLog.LogToStream(SQMDataId.MonitoredPhotoFolders, (uint)this.MonitoredPhotoFolders.Count); + SQMLog.LogToStream(SQMDataId.MonitoredPodcastFolders, (uint)this.MonitoredPodcastFolders.Count); + SQMLog.LogToStream(SQMDataId.MonitoredVideoFolders, (uint)this.MonitoredVideoFolders.Count); + if (!this.UsingWin7Libraries) + { + if (this._removedMonitoredFoldersToRemoveFromCollection != null) + { + foreach (Management.MonitoredFolder foldersToRemoveFrom in this._removedMonitoredFoldersToRemoveFromCollection) + ZuneApplication.ZuneLibrary.DeleteRootFolder(foldersToRemoveFrom.Path, foldersToRemoveFrom.Schema); + } + ClientConfiguration.Groveler.MonitoredAudioFolders = this.ListDataSetToIList(this.MonitoredAudioFolders); + ClientConfiguration.Groveler.MonitoredPhotoFolders = this.ListDataSetToIList(this.MonitoredPhotoFolders); + ClientConfiguration.Groveler.MonitoredPodcastFolders = this.ListDataSetToIList(this.MonitoredPodcastFolders); + ClientConfiguration.Groveler.MonitoredVideoFolders = this.ListDataSetToIList(this.MonitoredVideoFolders); + this._removedMonitoredFoldersToRemoveFromCollection = (List)null; + this._monitoredAudioFolders = (ListDataSet)null; + this._monitoredPhotoFolders = (ListDataSet)null; + this._monitoredPodcastFolders = (ListDataSet)null; + this._monitoredVideoFolders = (ListDataSet)null; + } + if (!this.HME.SharingEnabled) + return; + this.HME.SetSharedFoldersList(true); + } + + public BooleanChoice AutoCopyCD + { + get + { + if (this._autoCopyCD == null) + { + this._autoCopyCD = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_AUTO_RIP)); + this._autoCopyCD.Value = ClientConfiguration.Recorder.AutoCopyCD != 0; + this._autoCopyCD.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnAutoCopyCDCommit)] = (object)null); + } + return this._autoCopyCD; + } + } + + private void OnAutoCopyCDCommit(object data) => ClientConfiguration.Recorder.AutoCopyCD = this._autoCopyCD.Value ? 1 : 0; + + public BooleanChoice AutoEjectCD + { + get + { + if (this._autoEjectCD == null) + { + this._autoEjectCD = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_EJECT_AFTER_RIP)); + this._autoEjectCD.Value = ClientConfiguration.Recorder.AutoEjectCD != 0; + this._autoEjectCD.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnAutoEjectCDCommit)] = (object)null); + } + return this._autoEjectCD; + } + } + + private void OnAutoEjectCDCommit(object data) => ClientConfiguration.Recorder.AutoEjectCD = this._autoEjectCD.Value ? 1 : 0; + + public bool MediaFolderHasSharedPathWithMonitoredFolder( + string monitoredFolder, + string mediaFolder) + { + bool flag = false; + if (!string.IsNullOrEmpty(monitoredFolder) && !string.IsNullOrEmpty(mediaFolder)) + { + string localizedFolderPath1 = LocalizationHelper.GetLocalizedFolderPath(monitoredFolder); + string localizedFolderPath2 = LocalizationHelper.GetLocalizedFolderPath(mediaFolder); + if ((int)localizedFolderPath1[localizedFolderPath1.Length - 1] != (int)Path.PathSeparator) + localizedFolderPath1 += (string)(object)Path.PathSeparator; + if ((int)localizedFolderPath2[localizedFolderPath2.Length - 1] != (int)Path.PathSeparator) + localizedFolderPath2 += (string)(object)Path.PathSeparator; + flag = localizedFolderPath1.ToLower().IndexOf(localizedFolderPath2.ToLower()) == 0; + } + return flag; + } + + public string MediaFolder + { + get + { + if (this._mediaFolder == null) + this._mediaFolder = LocalizationHelper.GetLocalizedFolderPath(ClientConfiguration.Groveler.RipDirectory); + return this._mediaFolder; + } + set + { + if (!(this._mediaFolder != value)) + return; + this.CommitList[(object)new ProxySettingDelegate(this.OnMediaFolderCommit)] = (object)null; + this._mediaFolder = value; + this.FirePropertyChanged(nameof(MediaFolder)); + } + } + + private void OnMediaFolderCommit(object data) + { + if (this.UsingWin7Libraries) + return; + ClientConfiguration.Groveler.RipDirectory = this._mediaFolder; + this.UpdateSharedFoldersList(); + this._mediaFolder = (string)null; + } + + public string VideoMediaFolder + { + get + { + if (this._videoMediaFolder == null) + { + this._videoMediaFolder = ClientConfiguration.Groveler.VideoMediaFolder; + string[] strArray; + string str; + string videoMediaFolder; + if (string.IsNullOrEmpty(this._videoMediaFolder) && ((HRESULT)ZuneApplication.ZuneLibrary.GetKnownFolders(out strArray, out strArray, out strArray, out strArray, out strArray, out str, out videoMediaFolder, out str, out str, out str)).IsSuccess) + this._videoMediaFolder = LocalizationHelper.GetLocalizedFolderPath(videoMediaFolder); + } + return this._videoMediaFolder; + } + set + { + if (!(this._videoMediaFolder != value)) + return; + this.CommitList[(object)new ProxySettingDelegate(this.OnVideoMediaFolderCommit)] = (object)null; + this._videoMediaFolder = value; + this.FirePropertyChanged(nameof(VideoMediaFolder)); + } + } + + private void OnVideoMediaFolderCommit(object data) + { + if (this.UsingWin7Libraries) + return; + ClientConfiguration.Groveler.VideoMediaFolder = this._videoMediaFolder; + this.UpdateSharedFoldersList(); + this._videoMediaFolder = (string)null; + } + + public string PhotoMediaFolder + { + get + { + if (this._photoMediaFolder == null) + { + this._photoMediaFolder = ClientConfiguration.Groveler.PhotoMediaFolder; + string[] strArray; + string str; + string photoMediaFolder; + if (string.IsNullOrEmpty(this._photoMediaFolder) && ((HRESULT)ZuneApplication.ZuneLibrary.GetKnownFolders(out strArray, out strArray, out strArray, out strArray, out strArray, out str, out str, out photoMediaFolder, out str, out str)).IsSuccess) + this._photoMediaFolder = LocalizationHelper.GetLocalizedFolderPath(photoMediaFolder); + } + return this._photoMediaFolder; + } + set + { + if (!(this._photoMediaFolder != value)) + return; + this.CommitList[(object)new ProxySettingDelegate(this.OnPhotoMediaFolderCommit)] = (object)null; + this._photoMediaFolder = value; + this.FirePropertyChanged(nameof(PhotoMediaFolder)); + } + } + + private void OnPhotoMediaFolderCommit(object data) + { + if (this.UsingWin7Libraries) + return; + ClientConfiguration.Groveler.PhotoMediaFolder = this._photoMediaFolder; + this.UpdateSharedFoldersList(); + this._photoMediaFolder = (string)null; + } + + public string PodcastMediaFolder + { + get + { + if (this._podcastMediaFolder == null) + { + this._podcastMediaFolder = ClientConfiguration.Groveler.PodcastMediaFolder; + string[] strArray; + string str; + string podcastMediaFolder; + if (string.IsNullOrEmpty(this._podcastMediaFolder) && ((HRESULT)ZuneApplication.ZuneLibrary.GetKnownFolders(out strArray, out strArray, out strArray, out strArray, out strArray, out str, out str, out str, out podcastMediaFolder, out str)).IsSuccess) + this._podcastMediaFolder = LocalizationHelper.GetLocalizedFolderPath(podcastMediaFolder); + } + return this._podcastMediaFolder; + } + set + { + if (!(this._podcastMediaFolder != value)) + return; + this.CommitList[(object)new ProxySettingDelegate(this.OnPodcastMediaFolderCommit)] = (object)null; + this._podcastMediaFolder = value; + this.FirePropertyChanged(nameof(PodcastMediaFolder)); + } + } + + private void OnPodcastMediaFolderCommit(object data) + { + if (this.UsingWin7Libraries) + return; + ClientConfiguration.Groveler.PodcastMediaFolder = this._podcastMediaFolder; + this.UpdateSharedFoldersList(); + this._podcastMediaFolder = (string)null; + } + + private void UpdateSharedFoldersList() + { + if (!this.HME.SharingEnabled) + return; + this.HME.SetSharedFoldersList(true); + } + + public void ChooseMediaFolder(MediaType mediaType) => FolderBrowseDialog.Show(ZuneUI.Shell.LoadString(StringId.IDS_CHANGE_MEDIA_FOLDER_DIALOG_TITLE), (DeferredInvokeHandler)(args => + { + string folder = (string)args; + if (folder == null) + return; + if (FolderBrowseDialog.CanWriteToFolder(folder) && ZuneApplication.ZuneLibrary.CanAddFromFolder(folder)) + { + switch (mediaType) + { + case MediaType.Track: + this.MediaFolder = folder; + break; + case MediaType.Video: + this.VideoMediaFolder = folder; + break; + case MediaType.Photo: + this.PhotoMediaFolder = folder; + break; + case MediaType.Podcast: + this.PodcastMediaFolder = folder; + break; + } + } + else + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_INVALID_MEDIA_FOLDER_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_INVALID_MEDIA_FOLDER_MESSAGE), (EventHandler)null); + }), true); + + public BooleanChoice AutoEjectCDAfterBurn + { + get + { + if (this._autoEjectCDAfterBurn == null) + { + this._autoEjectCDAfterBurn = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_BURN_AUTO_EJECT_CHECK)); + this._autoEjectCDAfterBurn.Value = ClientConfiguration.CDBurn.AutoEject; + this._autoEjectCDAfterBurn.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnAutoEjectCDAfterBurnCommit)] = (object)null); + } + return this._autoEjectCDAfterBurn; + } + } + + private void OnAutoEjectCDAfterBurnCommit(object data) => ClientConfiguration.CDBurn.AutoEject = this._autoEjectCDAfterBurn.Value; + + public Choice BurnFormat + { + get + { + if (this._burnDiscFormat == null) + { + this._burnDiscFormat = new Choice((IModelItemOwner)this); + this._burnDiscFormat.Options = (IList)new NamedIntOption[2] + { + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_BURN_AUDIO_OPTION), 0), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_BURN_DATA_OPTION), 1) + }; + NamedIntOption.SelectOptionByValue(this._burnDiscFormat, ClientConfiguration.CDBurn.DiscFormat); + this._burnDiscFormat.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnBurnDiscFormatCommit)] = (object)null); + } + return this._burnDiscFormat; + } + } + + private void OnBurnDiscFormatCommit(object data) + { + ClientConfiguration.CDBurn.DiscFormat = ((NamedIntOption)this._burnDiscFormat.ChosenValue).Value; + CDAccess.Instance.UpdateIsAudioBurn(); + } + + public Choice BurnSpeed + { + get + { + if (this._burnSpeed == null) + { + this._burnSpeed = new Choice((IModelItemOwner)this); + this._burnSpeed.Options = (IList)new NamedIntOption[4] + { + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_BURN_FASTEST_OPTION), 0), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_BURN_FAST_OPTION), 1), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_BURN_MEDIUM_OPTION), 2), + new NamedIntOption((IModelItemOwner) null, ZuneUI.Shell.LoadString(StringId.IDS_BURN_SLOW_OPTION), 3) + }; + NamedIntOption.SelectOptionByValue(this._burnSpeed, ClientConfiguration.CDBurn.BurnSpeed); + this._burnSpeed.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnBurnSpeedCommit)] = (object)null); + } + return this._burnSpeed; + } + } + + private void OnBurnSpeedCommit(object data) => ClientConfiguration.CDBurn.BurnSpeed = ((NamedIntOption)this._burnSpeed.ChosenValue).Value; + + public BooleanChoice MediaInfoChoice + { + get + { + if (this._mediaInfoChoice == null) + { + StringId stringId = StringId.IDS_UPDATE_METADATA_CHECK; + if (FeatureEnablement.IsFeatureEnabled(Features.eQuickMixZmp) || FeatureEnablement.IsFeatureEnabled(Features.eQuickMixLocal)) + stringId = !FeatureEnablement.IsFeatureEnabled(Features.eMixview) ? StringId.IDS_UPDATE_METADATA_QUICKMIX_CHECK : StringId.IDS_UPDATE_METADATA_FEATURES_CHECK; + this._mediaInfoChoice = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(stringId)); + this._mediaInfoChoice.Value = ClientConfiguration.MediaStore.ConnectToInternetForAlbumMetadata; + this._mediaInfoChoice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnMediaInfoChoiceCommit)] = (object)null); + } + return this._mediaInfoChoice; + } + } + + private void OnMediaInfoChoiceCommit(object data) => ClientConfiguration.MediaStore.ConnectToInternetForAlbumMetadata = this._mediaInfoChoice.Value; + + public void ScanAndClearDeletedMedia() => ZuneLibrary.ScanAndClearDeletedMedia(); + + public BooleanChoice SqmChoice + { + get + { + if (this._sqmChoice == null) + { + this._sqmChoice = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_USAGE_DATA_CHECK)); + this._sqmChoice.Value = ClientConfiguration.SQM.UsageTracking; + this._sqmChoice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnSqmChoiceCommit)] = (object)null); + } + return this._sqmChoice; + } + } + + private void OnSqmChoiceCommit(object data) + { + ClientConfiguration.SQM.UsageTracking = this._sqmChoice.Value; + ClientConfiguration.FUE.AcceptedPrivacyStatement = this._sqmChoice.Value; + } + + public Choice PodcastDefaultKeepEpisodesChoice + { + get + { + if (this._podcastDefaultKeepEpisodesChoice == null) + { + Choice choice = new Choice((IModelItemOwner)this); + choice.Options = (IList)NamedIntOption.PodcastKeepOptions; + NamedIntOption.SelectOptionByValue(choice, ClientConfiguration.Series.PodcastDefaultKeepEpisodes); + this._podcastDefaultKeepEpisodesChoice = choice; + choice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnPodcastDefaultKeepEpisodesChoiceCommit)] = (object)null); + } + return this._podcastDefaultKeepEpisodesChoice; + } + } + + private void OnPodcastDefaultKeepEpisodesChoiceCommit(object data) => ClientConfiguration.Series.PodcastDefaultKeepEpisodes = ((NamedIntOption)this._podcastDefaultKeepEpisodesChoice.ChosenValue).Value; + + public Choice PodcastPlaybackChoice + { + get + { + if (this._podcastPlaybackChoice == null) + { + this._podcastPlaybackChoice = new Choice((IModelItemOwner)this); + this._podcastPlaybackChoice.Options = (IList)NamedIntOption.PodcastPlaybackOptions; + NamedIntOption.SelectOptionByValue(this._podcastPlaybackChoice, ClientConfiguration.Series.PodcastDefaultPlaybackOrder); + this._podcastPlaybackChoice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnPodcastPlaybackChoiceCommit)] = (object)null); + } + return this._podcastPlaybackChoice; + } + } + + private void OnPodcastPlaybackChoiceCommit(object data) => ClientConfiguration.Series.PodcastDefaultPlaybackOrder = ((NamedIntOption)this._podcastPlaybackChoice.ChosenValue).Value; + + public BooleanChoice MetadataChoice + { + get + { + if (this._metadataChoice == null) + { + Command[] commandArray = new Command[2]; + Command command1 = new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_MISSING_METADATA), (EventHandler)null); + commandArray[0] = command1; + Command command2 = new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_OVERWRITE_METADATA), (EventHandler)null); + commandArray[1] = command2; + this._metadataChoice = new BooleanChoice((IModelItemOwner)this); + this._metadataChoice.Options = (IList)commandArray; + this._metadataChoice.Value = ClientConfiguration.MediaStore.OverwriteAllMetadata; + this._metadataChoice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnMetadataChoiceCommit)] = (object)null); + } + return this._metadataChoice; + } + } + + private void OnMetadataChoiceCommit(object data) => ClientConfiguration.MediaStore.OverwriteAllMetadata = this._metadataChoice.Value; + + public IList AudioFileTypes + { + get + { + if (this._audioFileTypes == null) + this.PopulateFileTypes(); + return (IList)this._audioFileTypes; + } + } + + public IList VideoFileTypes + { + get + { + if (this._videoFileTypes == null) + this.PopulateFileTypes(); + return (IList)this._videoFileTypes; + } + } + + private void PopulateFileTypes() + { + if (this._audioFileTypes != null && this._videoFileTypes != null) + return; + this._allFileTypes = (IList)new List(); + this._audioFileTypes = (IList)new List(); + this._videoFileTypes = (IList)new List(); + HRESULT associationInfoList = (HRESULT)this.FileAssocHandler.GetFileAssociationInfoList(out this._fileAssociationInfoList); + if (associationInfoList.IsSuccess) + { + this.CanFileAssociationBeChanged = this.FileAssocHandler.CanAssociationBeChanged(); + string format = ZuneUI.Shell.LoadString(StringId.IDS_FILE_TYPES_DESCRIPTION_FORMAT); + for (int index = 0; index < this._fileAssociationInfoList.Count; ++index) + { + string extension = this._fileAssociationInfoList[index].Extension; + BooleanInputChoice booleanInputChoice = new BooleanInputChoice((ModelItem)this, string.Format(format, (object)extension.Substring(1), (object)this._fileAssociationInfoList[index].Description), this.CanFileAssociationBeChanged); + if (ClientConfiguration.FUE.ShowFUE && this.CanFileAssociationBeChanged && Array.IndexOf(this._defaultFileTypeExtensions, extension) >= 0) + this._fileAssociationInfoList[index].IsCurrentlyOwned = true; + booleanInputChoice.Value = this._fileAssociationInfoList[index].IsCurrentlyOwned; + booleanInputChoice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnFileTypesCommit)] = (object)null); + switch (this._fileAssociationInfoList[index].MediaType) + { + case EMediaTypes.eMediaTypeAudio: + this._audioFileTypes.Add(booleanInputChoice); + break; + case EMediaTypes.eMediaTypeVideo: + this._videoFileTypes.Add(booleanInputChoice); + break; + } + this._allFileTypes.Add(booleanInputChoice); + } + } + else + ErrorDialogInfo.Show(associationInfoList.Int, ZuneUI.Shell.LoadString(StringId.IDS_FILE_TYPES_ERROR_DIALOG_TITLE)); + } + + private void OnFileTypesCommit(object data) + { + if (this.FileAssocHandler == null || !this.CanFileAssociationBeChanged) + return; + for (int index = 0; index < this._allFileTypes.Count; ++index) + this._fileAssociationInfoList[index].IsCurrentlyOwned = this._allFileTypes[index].Value; + HRESULT hresult = (HRESULT)this.FileAssocHandler.SetFileAssociationInfo(this._fileAssociationInfoList); + if (hresult.IsError) + ErrorDialogInfo.Show(hresult.Int, ZuneUI.Shell.LoadString(StringId.IDS_FILE_TYPES_ERROR_DIALOG_TITLE)); + if (!ZuneUI.Shell.SettingsFrame.Wizard.IsCurrent) + return; + Fue.Instance.SetFileTypeAssociationsAreSet(); + } + + public void SelectAllFileTypes() + { + if (!this.CanFileAssociationBeChanged) + return; + for (int index = 0; index < this._allFileTypes.Count; ++index) + this._allFileTypes[index].Value = true; + } + + public void SaveFileTypesAsDefault() + { + if (!this.FileAssocHandler.CanAssociationBeChanged()) + return; + IList fileAssociationInfoList; + HRESULT hresult = (HRESULT)this.FileAssocHandler.GetFileAssociationInfoList(out fileAssociationInfoList); + if (hresult.IsSuccess) + { + for (int index = 0; index < fileAssociationInfoList.Count; ++index) + { + if (Array.IndexOf(this._defaultFileTypeExtensions, fileAssociationInfoList[index].Extension) >= 0) + fileAssociationInfoList[index].IsCurrentlyOwned = true; + } + hresult = (HRESULT)this.FileAssocHandler.SetFileAssociationInfo(fileAssociationInfoList); + if (!hresult.IsError) + return; + ErrorDialogInfo.Show(hresult.Int, ZuneUI.Shell.LoadString(StringId.IDS_FILE_TYPES_ERROR_DIALOG_TITLE)); + } + else + ErrorDialogInfo.Show(hresult.Int, ZuneUI.Shell.LoadString(StringId.IDS_FILE_TYPES_ERROR_DIALOG_TITLE)); + } + + public void ResetWarningMessages() + { + ClientConfiguration.MediaStore.LibraryDefaultDeleteChoice = 0; + ClientConfiguration.MediaStore.PlaylistDefaultDeleteChoice = 0; + ClientConfiguration.Pictures.DisplayAutouploadNotification = true; + ClientConfiguration.Series.PodcastDefaultUnsubscribeChoice = 0; + ClientConfiguration.Service.InhibitSubscriptionMachineCountExceededSignInWarning = false; + ClientConfiguration.Service.InhibitSubscriptionBillingViolationSignInWarning = false; + ClientConfiguration.Service.InhibitSubscriptionEndingWarning = false; + ClientConfiguration.Service.InhibitSubscriptionFreePurchasePrompt = false; + ClientConfiguration.Service.InhibitWinPhoneAppPurchaseConfirmation = false; + ClientConfiguration.Service.InhibitReviewRefreshWarning = false; + ClientConfiguration.Shell.ShowAppsForZuneHDOnlyHeader = true; + ClientConfiguration.Shell.ShowAppsForWindowsPhoneOnlyHeader = true; + ClientConfiguration.MediaStore.ConfirmAccountDevicePCDeletion = true; + ClientConfiguration.MediaStore.ConfirmAccountDevicePortableDeletion = true; + ClientConfiguration.MediaStore.ConfirmDeviceMediaDeletion = true; + ClientConfiguration.MediaStore.ConfirmMultiAlbumEdit = true; + ClientConfiguration.MediaStore.ConfirmMultiSongEdit = true; + ClientConfiguration.MediaStore.ConfirmMultiVideoEdit = true; + ClientConfiguration.MediaStore.ConfirmPasteAlbumArt = true; + ClientConfiguration.MediaStore.AlertSyncAllFriendsBehavior = true; + ClientConfiguration.Social.ConfirmAcceptFriend = true; + ClientConfiguration.Social.ConfirmDeleteFriend = true; + ClientConfiguration.QuickMix.OnlyEnableItemsWithQuickMix = false; + ClientConfiguration.Devices.ShowExcludeFromSyncWarning = true; + ClientConfiguration.Devices.ShowSyncInstructionsToast = true; + foreach (UIDevice uiDevice in SingletonModelItem.Instance) + uiDevice.PromptForAccountLinkage = true; + } + + public bool InhibitSubscriptionMachineCountExceededSignInWarning + { + get => ClientConfiguration.Service.InhibitSubscriptionMachineCountExceededSignInWarning; + set => ClientConfiguration.Service.InhibitSubscriptionMachineCountExceededSignInWarning = value; + } + + public bool InhibitSubscriptionBillingViolationSignInWarning + { + get => ClientConfiguration.Service.InhibitSubscriptionBillingViolationSignInWarning; + set => ClientConfiguration.Service.InhibitSubscriptionBillingViolationSignInWarning = value; + } + + public bool InhibitSubscriptionEndingWarning + { + get => ClientConfiguration.Service.InhibitSubscriptionEndingWarning; + set => ClientConfiguration.Service.InhibitSubscriptionEndingWarning = value; + } + + public bool InhibitSubscriptionFreePurchasePrompt + { + get => ClientConfiguration.Service.InhibitSubscriptionFreePurchasePrompt; + set => ClientConfiguration.Service.InhibitSubscriptionFreePurchasePrompt = value; + } + + public int LibraryDefaultDeleteChoice + { + get => ClientConfiguration.MediaStore.LibraryDefaultDeleteChoice; + set => ClientConfiguration.MediaStore.LibraryDefaultDeleteChoice = value; + } + + public int PlaylistDefaultDeleteChoice + { + get => ClientConfiguration.MediaStore.PlaylistDefaultDeleteChoice; + set => ClientConfiguration.MediaStore.PlaylistDefaultDeleteChoice = value; + } + + public bool ConfirmAcceptFriend + { + get => ClientConfiguration.Social.ConfirmAcceptFriend; + set => ClientConfiguration.Social.ConfirmAcceptFriend = value; + } + + public bool ConfirmDeleteFriend + { + get => ClientConfiguration.Social.ConfirmDeleteFriend; + set => ClientConfiguration.Social.ConfirmDeleteFriend = value; + } + + public bool ConfirmAccountDevicePCDeletion + { + get => ClientConfiguration.MediaStore.ConfirmAccountDevicePCDeletion; + set => ClientConfiguration.MediaStore.ConfirmAccountDevicePCDeletion = value; + } + + public bool ConfirmAccountDevicePortableDeletion + { + get => ClientConfiguration.MediaStore.ConfirmAccountDevicePortableDeletion; + set => ClientConfiguration.MediaStore.ConfirmAccountDevicePortableDeletion = value; + } + + public bool ConfirmDeviceMediaDeletion + { + get => ClientConfiguration.MediaStore.ConfirmDeviceMediaDeletion; + set => ClientConfiguration.MediaStore.ConfirmDeviceMediaDeletion = value; + } + + public bool ConfirmMultiAlbumEdit + { + get => ClientConfiguration.MediaStore.ConfirmMultiAlbumEdit; + set => ClientConfiguration.MediaStore.ConfirmMultiAlbumEdit = value; + } + + public bool ConfirmMultiSongEdit + { + get => ClientConfiguration.MediaStore.ConfirmMultiSongEdit; + set => ClientConfiguration.MediaStore.ConfirmMultiSongEdit = value; + } + + public bool ConfirmMultiVideoEdit + { + get => ClientConfiguration.MediaStore.ConfirmMultiVideoEdit; + set => ClientConfiguration.MediaStore.ConfirmMultiVideoEdit = value; + } + + public bool ConfirmPasteAlbumArt + { + get => ClientConfiguration.MediaStore.ConfirmPasteAlbumArt; + set => ClientConfiguration.MediaStore.ConfirmPasteAlbumArt = value; + } + + public ArrayListDataSet DeviceList + { + get + { + if (this._registeredDevicesModelList == null) + this.InitRegisteredTuners(); + return this._registeredDevicesModelList; + } + } + + public ArrayListDataSet AppStoreDeviceList + { + get + { + if (this._registeredAppStoreDevicesModelList == null) + this.InitRegisteredTuners(); + return this._registeredAppStoreDevicesModelList; + } + } + + public ArrayListDataSet ComputerList + { + get + { + if (this._registeredComputersModelList == null) + this.InitRegisteredTuners(); + return this._registeredComputersModelList; + } + } + + public string NextPCDeregistrationDate + { + get => this._nextPCDeregistrationDate; + private set + { + if (!(this._nextPCDeregistrationDate != value)) + return; + this._nextPCDeregistrationDate = value; + this.FirePropertyChanged(nameof(NextPCDeregistrationDate)); + } + } + + public string NextSubscriptionDeviceDeregistrationDate + { + get => this._nextSubscriptionDeviceDeregistrationDate; + private set + { + if (!(this._nextSubscriptionDeviceDeregistrationDate != value)) + return; + this._nextSubscriptionDeviceDeregistrationDate = value; + this.FirePropertyChanged(nameof(NextSubscriptionDeviceDeregistrationDate)); + } + } + + public string NextAppStoreDeviceDeregistrationDate + { + get => this._nextAppStoreDeviceDeregistrationDate; + private set + { + if (!(this._nextAppStoreDeviceDeregistrationDate != value)) + return; + this._nextAppStoreDeviceDeregistrationDate = value; + this.FirePropertyChanged(nameof(NextAppStoreDeviceDeregistrationDate)); + } + } + + public bool CanShowDeviceList + { + get + { + if (this._tunerHandler == null) + this.InitRegisteredTuners(); + return this._tunerHandler.CanQueryTunerList(); + } + } + + public void RemoveTuner(Microsoft.Zune.Configuration.TunerInfo tunerInfo) + { + if (this._tunerHandler == null) + this.InitRegisteredTuners(); + this._tunerHandler.DeregisterTuner(tunerInfo); + } + + public void RefreshTunerList() + { + if (!this._tunerHandler.CanQueryTunerList()) + return; + this._tunerHandler.RefreshTunerList(); + } + + private void OnTunerInfoChanged(object oSenderUNUSED, EventArgs eargs) + { + if (eargs != null && eargs.GetType() == typeof(EventArgsHR) && (HRESULT)((EventArgsHR)eargs).HResult == HRESULT._ZEST_E_TOO_MANY_DEREGISTRATIONS_WITHIN_MONTH) + Application.DeferredInvoke(new DeferredInvokeHandler(this.DisplayServiceErrorMessage), (object)eargs); + else + Application.DeferredInvoke(new DeferredInvokeHandler(this.UpdateRegisteredTunersList), DeferredInvokePriority.Normal); + } + + private void DisplayServiceErrorMessage(object eargs) => ZuneUI.Shell.ShowErrorDialog(((EventArgsHR)eargs).HResult, StringId.IDS_REGDEVICES_CANT_REMOVE); + + private void UpdateRegisteredTunersList(object argsUNUSED) + { + if (this._registeredComputersModelList == null || this._registeredDevicesModelList == null || this._registeredAppStoreDevicesModelList == null) + return; + int count1 = this._registeredComputersModelList.Count; + int count2 = this._registeredDevicesModelList.Count; + int count3 = this._registeredAppStoreDevicesModelList.Count; + this._registeredComputersModelList.Clear(); + this._registeredDevicesModelList.Clear(); + this._registeredAppStoreDevicesModelList.Clear(); + foreach (object pcs in (IEnumerable)this._tunerHandler.GetPCsList()) + this._registeredComputersModelList.Add(pcs); + foreach (object devices in (IEnumerable)this._tunerHandler.GetDevicesList()) + this._registeredDevicesModelList.Add(devices); + foreach (object appStoreDevices in (IEnumerable)this._tunerHandler.GetAppStoreDevicesList()) + this._registeredAppStoreDevicesModelList.Add(appStoreDevices); + DateTime deregistrationDate1 = this._tunerHandler.GetNextPCDeregistrationDate(); + this.NextPCDeregistrationDate = !(deregistrationDate1 != DateTime.MinValue) || !(deregistrationDate1 > DateTime.Now) ? (string)null : deregistrationDate1.AddDays(1.0).ToShortDateString(); + DateTime deregistrationDate2 = this._tunerHandler.GetNextSubscriptionDeviceDeregistrationDate(); + this.NextSubscriptionDeviceDeregistrationDate = !(deregistrationDate2 != DateTime.MinValue) || !(deregistrationDate2 > DateTime.Now) ? (string)null : deregistrationDate2.AddDays(1.0).ToShortDateString(); + DateTime deregistrationDate3 = this._tunerHandler.GetNextAppStoreDeviceDeregistrationDate(); + this.NextAppStoreDeviceDeregistrationDate = !(deregistrationDate3 != DateTime.MinValue) || !(deregistrationDate3 > DateTime.Now) ? (string)null : deregistrationDate3.AddDays(1.0).ToShortDateString(); + if (this._registeredComputersModelList.Count >= count1 && this._registeredDevicesModelList.Count >= count2 && this._registeredAppStoreDevicesModelList.Count >= count3) + return; + SignIn.Instance.RefreshAccount(); + } + + private void InitRegisteredTuners() + { + this._tunerHandler = TunerInfoHandlerFactory.CreateTunerInfoHandler(); + this._tunerHandler.OnChanged += new EventHandler(this.OnTunerInfoChanged); + this._registeredComputersModelList = new ArrayListDataSet(); + this._registeredDevicesModelList = new ArrayListDataSet(); + this._registeredAppStoreDevicesModelList = new ArrayListDataSet(); + this._nextPCDeregistrationDate = (string)null; + this._nextSubscriptionDeviceDeregistrationDate = (string)null; + this._nextAppStoreDeviceDeregistrationDate = (string)null; + if (!this._tunerHandler.CanQueryTunerList()) + return; + this._tunerHandler.RefreshTunerList(); + } + + public IntRangedValue SlideShowSpeed + { + get + { + if (this._slideShowSpeed == null) + { + this._slideShowSpeed = new IntRangedValue((IModelItemOwner)this); + this._slideShowSpeed.MinValue = 3000; + this._slideShowSpeed.MaxValue = 10000; + this._slideShowSpeed.Step = 1000; + this._slideShowSpeed.Value = ClientConfiguration.GeneralSettings.SlideShowSpeed; + this._slideShowSpeed.PropertyChanged += (PropertyChangedEventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnSlideShowSpeedCommit)] = (object)null); + } + return this._slideShowSpeed; + } + } + + private void OnSlideShowSpeedCommit(object data) => ClientConfiguration.GeneralSettings.SlideShowSpeed = this._slideShowSpeed.Value; + + public HMESettings HME + { + get + { + if (this._HME == null) + { + lock (this.mylock) + { + if (this._HME == null) + { + HMESettings hmeSettings = new HMESettings(); + int num = ((HRESULT)hmeSettings.Init()).IsError ? 1 : 0; + this._sharingAllDevicesEnabled = hmeSettings.GetAllDevicesEnabled(); + this._HME = hmeSettings; + } + } + } + return this._HME; + } + } + + public bool UserCanModifySharing => Environment.OSVersion.Version.Major >= 6 || !this.SharingEnableRequiresElevation || this.SharingEnabled; + + public bool SharingEnableRequiresElevation => Environment.OSVersion.Version.Major < 6 ? this.HME.SharingEnableRequiresLoginAsAdmin : this.HME.SharingEnableRequiresElevation; + + public bool SharingEnabled => this.HME.SharingEnabled; + + private void SetSharingEnabledForAllMediaTypes(bool music, bool video, bool pictures) + { + this.HME.SetSharingEnabledForMediaType(EMediaTypes.eMediaTypeAudio, music); + this.HME.SetSharingEnabledForMediaType(EMediaTypes.eMediaTypeVideo, video); + this.HME.SetSharingEnabledForMediaType(EMediaTypes.eMediaTypeImage, pictures); + } + + private void OnMediaSharingUpdate(object data) + { + if (this.HME == null) + return; + bool flag = this._sharingEnableMusic.Value || this._sharingEnableVideo.Value || this._sharingEnablePhoto.Value; + HRESULT hresult1 = (HRESULT)0; + if (flag) + { + if (((HRESULT)this.HME.EnableSharingForUser()).IsSuccess) + this.SetSharingEnabledForAllMediaTypes(this._sharingEnableMusic.Value, this._sharingEnableVideo.Value, this._sharingEnablePhoto.Value); + else + this.SetSharingEnabledForAllMediaTypes(false, false, false); + } + else + { + HRESULT hresult2 = (HRESULT)this.HME.DisableSharingForMachine(); + if (hresult2.IsSuccess) + hresult2 = (HRESULT)this.HME.DisableSharingForUser(); + if (hresult2.IsSuccess) + this.SetSharingEnabledForAllMediaTypes(false, false, false); + } + this.HME.SetAllDevicesEnabled(this._sharingAllDevicesEnabled); + if (!this._sharingAllDevicesEnabled) + this.HME.EnableDevice(this._sharingDeviceIndex, true); + this.HME.SetDisplayName(this._sharingDisplayName); + } + + public string SharingDisplayName + { + get + { + if (this._sharingDisplayName == null) + this.HME.GetDisplayName(ref this._sharingDisplayName); + return this._sharingDisplayName; + } + set + { + if (string.IsNullOrEmpty(value)) + { + this.SharingError = ZuneUI.Shell.LoadString(StringId.IDS_SHARE_NAME_EMPTY); + } + else + { + if (!(this._sharingDisplayName != value)) + return; + this.SharingError = string.Empty; + this._sharingDisplayName = value; + this.CommitList[(object)new ProxySettingDelegate(this.OnMediaSharingUpdate)] = (object)null; + } + } + } + + public string SharingError + { + get => this._sharingError; + set + { + if (!(this._sharingError != value)) + return; + this._sharingError = value; + this.FirePropertyChanged(nameof(SharingError)); + } + } + + public BooleanChoice SharingEnableMusic + { + get + { + if (this._sharingEnableMusic == null) + { + this._sharingEnableMusic = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_SHARE_MUSIC_CHECK)); + this._sharingEnableMusic.Value = this.HME.GetSharingEnabledForMediaType(EMediaTypes.eMediaTypeAudio); + this._sharingEnableMusic.ChosenChanged += (EventHandler)((sender, args) => + { + this.CommitList[(object)new ProxySettingDelegate(this.OnMediaSharingUpdate)] = (object)null; + if (!this.SharingEnableRequiresElevation) + return; + this.ChangeRequiresElevation = true; + }); + } + return this._sharingEnableMusic; + } + } + + public BooleanChoice SharingEnableVideo + { + get + { + if (this._sharingEnableVideo == null) + { + this._sharingEnableVideo = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_SHARE_VIDEOS_CHECK)); + this._sharingEnableVideo.Value = this.HME.GetSharingEnabledForMediaType(EMediaTypes.eMediaTypeVideo); + this._sharingEnableVideo.ChosenChanged += (EventHandler)((sender, args) => + { + this.CommitList[(object)new ProxySettingDelegate(this.OnMediaSharingUpdate)] = (object)null; + if (!this.SharingEnableRequiresElevation) + return; + this.ChangeRequiresElevation = true; + }); + } + return this._sharingEnableVideo; + } + } + + public BooleanChoice SharingEnablePhoto + { + get + { + if (this._sharingEnablePhoto == null) + { + this._sharingEnablePhoto = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_SHARE_PICTURES_CHECK)); + this._sharingEnablePhoto.Value = this.HME.GetSharingEnabledForMediaType(EMediaTypes.eMediaTypeImage); + this._sharingEnablePhoto.ChosenChanged += (EventHandler)((sender, args) => + { + this.CommitList[(object)new ProxySettingDelegate(this.OnMediaSharingUpdate)] = (object)null; + if (!this.SharingEnableRequiresElevation) + return; + this.ChangeRequiresElevation = true; + }); + } + return this._sharingEnablePhoto; + } + } + + public Choice SharingSelectDeviceChoice + { + get + { + if (this._sharingSelectDeviceChoice == null) + { + this._sharingSelectDeviceOptions = (IList)new List(); + Command command1 = new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_GLOBAL_SHARING_OPTION), (EventHandler)null); + command1.Data.Add((object)"value", (object)true); + this._sharingSelectDeviceOptions.Add(command1); + Command command2 = new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_SELECTIVE_SHARING_OPTION), (EventHandler)null); + command2.Data.Add((object)"value", (object)false); + command2.Available = this.SharingEnabled; + this._sharingSelectDeviceOptions.Add(command2); + this._sharingSelectDeviceChoice = new Choice((IModelItemOwner)this); + this._sharingSelectDeviceChoice.Options = (IList)this._sharingSelectDeviceOptions; + this._sharingSelectDeviceChoice.ChosenChanged += (EventHandler)((sender, args) => this.SharingAllDevicesEnabled = (bool)this._sharingSelectDeviceOptions[((Choice)sender).ChosenIndex].Data[(object)"value"]); + } + return this._sharingSelectDeviceChoice; + } + } + + public bool SharingAllDevicesEnabled + { + get => this._sharingAllDevicesEnabled; + set + { + if (this._sharingAllDevicesEnabled == value) + return; + this._sharingAllDevicesEnabled = value; + this.CommitList[(object)new ProxySettingDelegate(this.OnMediaSharingUpdate)] = (object)null; + this.FirePropertyChanged(nameof(SharingAllDevicesEnabled)); + } + } + + public IList SharingDeviceList + { + get + { + if (this._sharingDeviceList == null) + this._sharingDeviceList = this.CreateSharingDeviceList(); + return (IList)this._sharingDeviceList; + } + } + + private IList CreateSharingDeviceList() + { + IList booleanInputChoiceList = (IList)new List(); + uint deviceCount = this.HME.GetDeviceCount(); + string strName = ""; + string strMAC = ""; + string strSerialNumber = ""; + for (uint dwIndex = 0; dwIndex < deviceCount; ++dwIndex) + { + this.HME.GetDeviceProps(dwIndex, ref strName, ref strMAC, ref strSerialNumber); + BooleanInputChoice booleanInputChoice = new BooleanInputChoice((ModelItem)this, deviceCount > 1U ? string.Format(ZuneUI.Shell.LoadString(StringId.IDS_XBOX360_NAME_AND_SERIAL_NUMBER), (object)strName, (object)strSerialNumber) : strName, true); + booleanInputChoice.Data[(object)"index"] = (object)dwIndex; + booleanInputChoice.Value = this.HME.GetDeviceEnabled(dwIndex); + booleanInputChoice.ChosenChanged += new EventHandler(this.HandleSharingDeviceListValueChanged); + booleanInputChoiceList.Add(booleanInputChoice); + } + if (!this._nssDeviceListChangeEventAdded) + { + this.HME.NSSDeviceListChangeEvent += new NSSDeviceListChangeHandler(this.HandleNSSDeviceListChangeEvent); + this._nssDeviceListChangeEventAdded = true; + } + return booleanInputChoiceList; + } + + public void RemoveNSSDeviceListChangeEvent() + { + if (!this._nssDeviceListChangeEventAdded) + return; + this.HME.NSSDeviceListChangeEvent -= new NSSDeviceListChangeHandler(this.HandleNSSDeviceListChangeEvent); + this._nssDeviceListChangeEventAdded = false; + this._sharingDeviceList = (IList)null; + } + + private void HandleNSSDeviceListChangeEvent() => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this._sharingDeviceList == null) + return; + this._sharingDeviceList = this.CreateSharingDeviceList(); + this.FirePropertyChanged("SharingDeviceList"); + }, (object)null); + + private void HandleSharingDeviceListValueChanged(object sender, EventArgs args) => this._sharingDeviceIndex = (uint)((ModelItem)sender).Data[(object)"index"]; + + public bool ReevaluateVideoSettings + { + get => ClientConfiguration.GeneralSettings.ReevaluateVideoSettings; + set + { + ClientConfiguration.GeneralSettings.ReevaluateVideoSettings = value; + this.FirePropertyChanged(nameof(ReevaluateVideoSettings)); + } + } + + public RenderingType RequestedRenderingType + { + get + { + RenderingType renderingType = (RenderingType)ClientConfiguration.GeneralSettings.RenderingType; + if (renderingType == RenderingType.Default) + renderingType = Application.RenderingType; + return renderingType; + } + set + { + ClientConfiguration.GeneralSettings.RenderingType = (int)value; + this.ReevaluateVideoSettings = Application.RenderingType != RenderingType.DX9 && value == RenderingType.DX9; + this.FirePropertyChanged(nameof(RequestedRenderingType)); + } + } + + private void ReevaluateVideoAcceleration(object sender, EventArgs args) => this.RequestedRenderingType = RenderingType.DX9; + + public RenderingQuality RequestedRenderingQuality + { + get => (RenderingQuality)ClientConfiguration.GeneralSettings.RenderingQuality; + set + { + ClientConfiguration.GeneralSettings.RenderingQuality = (int)value; + this.FirePropertyChanged(nameof(RequestedRenderingQuality)); + } + } + + public bool AnimationsEnabled + { + get => ClientConfiguration.GeneralSettings.AnimationsEnabled; + set + { + ClientConfiguration.GeneralSettings.AnimationsEnabled = value; + this.FirePropertyChanged(nameof(AnimationsEnabled)); + } + } + + public Choice ScreenGraphicsSlider + { + get + { + if (this._screenGraphicsSlider == null) + { + Choice choice = new Choice((IModelItemOwner)this); + choice.Options = (IList)NamedIntOption.ScreenGraphicsOptions; + ScreenGraphics screenGraphics = Application.RenderingType != RenderingType.GDI ? (Application.RenderingQuality != RenderingQuality.MaxQuality ? (!Application.AnimationsEnabled ? ScreenGraphics.Advanced : ScreenGraphics.AdvancedWithAnimation) : ScreenGraphics.Premium) : ScreenGraphics.Basic; + NamedIntOption.SelectOptionByValue(choice, (int)screenGraphics); + this._screenGraphicsSlider = choice; + choice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnScreenGraphicsSliderCommit)] = (object)null); + } + return this._screenGraphicsSlider; + } + } + + private void OnScreenGraphicsSliderCommit(object data) + { + ScreenGraphics screenGraphics = (ScreenGraphics)((NamedIntOption)this._screenGraphicsSlider.ChosenValue).Value; + RenderingType requestedRenderingType = this.RequestedRenderingType; + switch (screenGraphics) + { + case ScreenGraphics.Basic: + this.RequestedRenderingType = RenderingType.GDI; + this.RequestedRenderingQuality = RenderingQuality.MinQuality; + this.AnimationsEnabled = false; + break; + case ScreenGraphics.Advanced: + this.RequestedRenderingType = RenderingType.DX9; + this.RequestedRenderingQuality = RenderingQuality.MinQuality; + this.AnimationsEnabled = false; + break; + case ScreenGraphics.AdvancedWithAnimation: + this.RequestedRenderingType = RenderingType.DX9; + this.RequestedRenderingQuality = RenderingQuality.MinQuality; + this.AnimationsEnabled = true; + break; + case ScreenGraphics.Premium: + this.RequestedRenderingType = RenderingType.DX9; + this.RequestedRenderingQuality = RenderingQuality.MaxQuality; + this.AnimationsEnabled = true; + break; + } + if (requestedRenderingType == RenderingType.GDI && this.RequestedRenderingType == RenderingType.DX9) + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_SCREEN_GRAPHICS_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_ACCELERATION_PROMPT_TEXT), (EventHandler)null); + else + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_SCREEN_GRAPHICS_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_ACCELERATION_RESTART_TEXT), (EventHandler)null); + } + + public string BackgroundImage + { + get + { + if (this._backgroundImage == null) + this._backgroundImage = ClientConfiguration.Shell.BackgroundImage; + return this._backgroundImage; + } + set + { + if (!(this._backgroundImage != value)) + return; + this.CommitList[(object)new ProxySettingDelegate(this.OnBackgroundImageCommit)] = (object)null; + this._backgroundImage = value; + this.FirePropertyChanged(nameof(BackgroundImage)); + } + } + + public WindowColor BackgroundColor + { + get => this._backgroundColor; + set => this._backgroundColor = value; + } + + private void OnBackgroundImageCommit(object data) + { + ClientConfiguration.Shell.BackgroundImage = this._backgroundImage; + ClientConfiguration.Shell.BackgroundColor = ZuneUI.Shell.WindowColorToRGB(this._backgroundColor); + ((ZuneUI.Shell)ZuneShell.DefaultInstance).BackgroundImage = this._backgroundImage; + Application.Window.SetBackgroundColor(this._backgroundColor); + } + + public BooleanChoice ShowNowPlayingBackgroundOnIdle + { + get + { + if (this._showNowPlayingBackgroundOnIdle == null) + { + this._showNowPlayingBackgroundOnIdle = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_SHOW_NOWPLAYING_ON_IDLE_DESCRIPTION)); + this._showNowPlayingBackgroundOnIdle.Value = ClientConfiguration.Shell.ShowNowPlayingBackgroundOnIdleTimeout > 0; + this._showNowPlayingBackgroundOnIdle.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnShowNowPlayingBackgroundOnIdleCommit)] = (object)null); + } + return this._showNowPlayingBackgroundOnIdle; + } + } + + private void OnShowNowPlayingBackgroundOnIdleCommit(object data) + { + int num = this._showNowPlayingBackgroundOnIdle.Value ? 90 : 0; + ClientConfiguration.Shell.ShowNowPlayingBackgroundOnIdleTimeout = num; + ((ZuneUI.Shell)ZuneShell.DefaultInstance).ShowNowPlayingBackgroundOnIdleTimeout = num; + } + + public BooleanChoice PlaySounds + { + get + { + if (this._playSounds == null) + { + this._playSounds = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_SOUNDS_DESCRIPTION)); + this._playSounds.Value = ClientConfiguration.Shell.Sounds; + this._playSounds.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnPlaySoundsCommit)] = (object)null); + } + return this._playSounds; + } + } + + private void OnPlaySoundsCommit(object data) + { + ClientConfiguration.Shell.Sounds = this._playSounds.Value; + ((ZuneUI.Shell)ZuneShell.DefaultInstance).PlaySounds = this._playSounds.Value; + } + + public BooleanChoice CompactModeAlwaysOnTop + { + get + { + if (this._compactModeAlwaysOnTop == null) + { + this._compactModeAlwaysOnTop = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_COMPACT_MODE_ALWAYS_ON_TOP)); + this._compactModeAlwaysOnTop.Value = ClientConfiguration.GeneralSettings.CompactModeAlwaysOnTop; + this._compactModeAlwaysOnTop.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnCompactModeAlwaysOnTopCommit)] = (object)null); + } + return this._compactModeAlwaysOnTop; + } + } + + private void OnCompactModeAlwaysOnTopCommit(object data) + { + ClientConfiguration.GeneralSettings.CompactModeAlwaysOnTop = this._compactModeAlwaysOnTop.Value; + ((ZuneUI.Shell)ZuneShell.DefaultInstance).CompactModeAlwaysOnTop = this._compactModeAlwaysOnTop.Value; + SQMLog.Log(SQMDataId.CompactModeOnTopSetting, 1); + } + + public BooleanChoice RatingsChoice + { + get + { + if (this._ratingsChoice == null) + { + Command[] commandArray = new Command[2] + { + (Command) new RichLayoutCommand((IModelItemOwner) this, ZuneUI.Shell.LoadString(StringId.IDS_COMMON_RATINGS_ALL_USERS_OPTION), true), + (Command) new RichLayoutCommand((IModelItemOwner) this, ZuneUI.Shell.LoadString(StringId.IDS_PERSONAL_RATINGS_EACH_USER_OPTION), false) + }; + this._ratingsChoice = new BooleanChoice((IModelItemOwner)this); + this._ratingsChoice.Options = (IList)commandArray; + this._ratingsChoice.Value = !ClientConfiguration.MediaStore.SharedUserRatings; + this._ratingsChoice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnRatingsCommit)] = (object)null); + } + return this._ratingsChoice; + } + } + + private void OnRatingsCommit(object data) + { + ClientConfiguration.MediaStore.SharedUserRatings = !this._ratingsChoice.Value; + if (!this._applyRatingsChoice.Value || this._ratingsChoice.Value) + return; + ZuneLibrary.ExportUserRatings(SignIn.Instance.LastSignedInUserId, EMediaTypes.eMediaTypeAudio); + } + + public BooleanChoice ApplyRatingsChoice + { + get + { + if (this._applyRatingsChoice == null) + { + this._applyRatingsChoice = new BooleanChoice((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_APPLY_RATINGS_DIALOG_DESCRIPTION)); + this._applyRatingsChoice.Value = false; + this._applyRatingsChoice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnRatingsCommit)] = (object)null); + } + return this._applyRatingsChoice; + } + } + + public Choice StartupPageChoice + { + get + { + if (this._startupPageChoice == null) + { + List commandList = new List(); + if (FeatureEnablement.IsFeatureEnabled(Features.eQuickplay)) + commandList.Add((Command)new NamedStringOption(ZuneUI.Shell.LoadString(StringId.IDS_VIEW_STARTUPPAGE_QUICKPLAY_CHOICE), ZuneUI.Shell.MainFrame.Quickplay.DefaultUIPath)); + commandList.Add((Command)new NamedStringOption(ZuneUI.Shell.LoadString(StringId.IDS_VIEW_STARTUPPAGE_COLLECTION_CHOICE), ZuneUI.Shell.MainFrame.Collection.DefaultUIPath)); + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace)) + commandList.Add((Command)new NamedStringOption(ZuneUI.Shell.LoadString(StringId.IDS_VIEW_STARTUPPAGE_MARKETPLACE_CHOICE), ZuneUI.Shell.MainFrame.Marketplace.DefaultUIPath)); + if (FeatureEnablement.IsFeatureEnabled(Features.eSocial)) + commandList.Add((Command)new NamedStringOption(ZuneUI.Shell.LoadString(StringId.IDS_VIEW_STARTUPPAGE_SOCIAL_CHOICE), ZuneUI.Shell.MainFrame.Social.DefaultUIPath)); + this._startupPageChoice = new Choice((IModelItemOwner)this); + this._startupPageChoice.Options = (IList)commandList; + foreach (NamedStringOption namedStringOption in commandList) + { + if (namedStringOption.Value == ClientConfiguration.Shell.StartupPage) + { + this._startupPageChoice.ChosenValue = (object)namedStringOption; + break; + } + } + this._startupPageChoice.ChosenChanged += (EventHandler)((sender, args) => this.CommitList[(object)new ProxySettingDelegate(this.OnStartupPageCommit)] = (object)null); + } + return this._startupPageChoice; + } + } + + private void OnStartupPageCommit(object data) + { + ClientConfiguration.Shell.StartupPage = ((NamedStringOption)this._startupPageChoice.ChosenValue).Value; + ClientConfiguration.Quickplay.CheckUseCount = false; + } + + public bool AutoLaunchZuneOnConnect + { + get => this._autoLaunchZuneOnConnect; + set + { + if (this._autoLaunchZuneOnConnect == value) + return; + this._autoLaunchZuneOnConnect = value; + this.CommitList[(object)new ProxySettingDelegate(this.OnAutoLaunchZuneOnConnectCommit)] = (object)null; + this.FirePropertyChanged(nameof(AutoLaunchZuneOnConnect)); + } + } + + private void OnAutoLaunchZuneOnConnectCommit(object data) => ClientConfiguration.Devices.AutoLaunchZuneOnConnect = this._autoLaunchZuneOnConnect; + + private struct MonitoredFolder + { + public readonly string Path; + public readonly EMediaTypes Schema; + + public MonitoredFolder(string path, EMediaTypes schema) + { + this.Path = path; + this.Schema = schema; + } + } + } +} diff --git a/ZuneUI/MappedError.cs b/ZuneUI/MappedError.cs new file mode 100644 index 0000000..4c157ea --- /dev/null +++ b/ZuneUI/MappedError.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MappedError +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.ErrorMapperApi; + +namespace ZuneUI +{ + public struct MappedError + { + private string _text; + private string _url; + + public MappedError(int hr) + { + ErrorMapperResult descriptionAndUrl = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr); + this._text = descriptionAndUrl.Description; + this._url = descriptionAndUrl.WebHelpUrl; + } + + public string Text => this._text; + + public string URL => this._url; + } +} diff --git a/ZuneUI/MarketplaceActionCommand.cs b/ZuneUI/MarketplaceActionCommand.cs new file mode 100644 index 0000000..51d5a5c --- /dev/null +++ b/ZuneUI/MarketplaceActionCommand.cs @@ -0,0 +1,284 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public abstract class MarketplaceActionCommand : ProgressCommand + { + private bool m_allowPlay = true; + private bool m_allowDownload = true; + private bool m_hasPoints; + private bool m_downloading; + private bool m_downloadingHidden; + private bool m_showHiddenProgress; + private int m_collectionId = -1; + private DataProviderObject m_model; + private Guid m_id; + private StringId m_addToCollectionStringId = StringId.IDS_ADD_TO_COLLECTION; + + public MarketplaceActionCommand() + { + this.UniqueId = Guid.NewGuid(); + Download.Instance.DownloadEvent += new DownloadEventHandler(this.OnDownloadEvent); + Download.Instance.DownloadProgressEvent += new DownloadEventProgressHandler(this.OnDownloadProgressEvent); + } + + public virtual bool CanFindInCollection => this.m_collectionId >= 0; + + public virtual bool CanFindInCollectionShortcut => this.m_collectionId >= 0 && ZuneApplication.Service.GetMediaStatus(this.Id, this.ContentType) == EMediaStatus.StatusInCollectionShortcut; + + public virtual bool CanFindInCollectionOwned => this.m_collectionId >= 0 && ZuneApplication.Service.GetMediaStatus(this.Id, this.ContentType) == EMediaStatus.StatusInCollectionOwned; + + public virtual bool CanFindInHiddenCollection => ZuneApplication.Service.InHiddenCollection(this.Id, this.ContentType); + + public virtual bool ShowHiddenProgress + { + get => this.m_showHiddenProgress; + set + { + if (value == this.m_showHiddenProgress) + return; + this.m_showHiddenProgress = value; + this.FirePropertyChanged(nameof(ShowHiddenProgress)); + } + } + + public bool AllowPlay + { + get => this.m_allowPlay; + set + { + if (value == this.m_allowPlay) + return; + this.m_allowPlay = value; + this.FirePropertyChanged(nameof(AllowPlay)); + } + } + + public bool AllowDownload + { + get => this.m_allowDownload; + set + { + if (this.m_allowDownload == value) + return; + this.m_allowDownload = value; + this.FirePropertyChanged(nameof(AllowDownload)); + this.UpdateState(); + } + } + + public abstract void FindInCollection(); + + public bool CanFindInZuneDotNet => this.Model.GetProperty("AlbumId") is Guid property && property != Guid.Empty; + + public bool Downloading + { + get => this.m_downloading; + protected set + { + if (value == this.m_downloading) + return; + this.m_downloading = value; + this.FirePropertyChanged(nameof(Downloading)); + } + } + + public bool DownloadingHidden + { + get => this.m_downloadingHidden; + protected set + { + if (value == this.m_downloadingHidden) + return; + this.m_downloadingHidden = value; + this.FirePropertyChanged(nameof(DownloadingHidden)); + } + } + + public void FindInZuneDotNet() + { + object property = this.Model.GetProperty("AlbumId"); + if (!(property is Guid guid) || !(guid != Guid.Empty)) + return; + ZuneDotNet.ViewAlbum((Guid)property); + } + + public void FindInDownloads() + { + if (!this.Downloading) + return; + ZuneShell.DefaultInstance.Execute("Marketplace\\Downloads\\Home", (IDictionary)null); + } + + public virtual void UpdateState() + { + this.Progress = -1f; + this.CollectionId = -1; + this.HasPoints = false; + this.Downloading = false; + bool fIsDownloadPending = false; + bool fIsHidden = false; + if (this.AllowDownload) + { + int dbMediaId; + if (ZuneApplication.Service.InVisibleCollection(this.Id, this.ContentType, out dbMediaId)) + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_INCOLLECTION); + this.Available = true; + this.CollectionId = dbMediaId; + } + else if (ZuneApplication.Service.InHiddenCollection(this.Id, this.ContentType)) + { + this.Description = ZuneUI.Shell.LoadString(this.AddToCollectionStringId); + this.Available = true; + } + else if (ZuneApplication.Service.IsDownloading(this.Id, this.ContentType, out fIsDownloadPending, out fIsHidden) && (!fIsHidden || this.ShowHiddenProgress)) + { + this.Downloading = true; + this.Available = true; + if (fIsDownloadPending) + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_PENDING); + } + else + { + this.Description = string.Empty; + DownloadTask task = DownloadManager.Instance.GetTask(this.Id.ToString()); + if (task != null) + this.OnDownloadProgressEvent(this.Id, task.GetProgress()); + } + } + else + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_NOT_AVAILABLE); + this.Available = false; + } + } + else + { + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_NOT_AVAILABLE); + this.Available = false; + } + this.DownloadingHidden = fIsHidden; + } + + private void OnDownloadProgressEvent(Guid trackId, float percent) + { + if (!(trackId == this.m_id) || this.DownloadingHidden && !this.ShowHiddenProgress) + return; + this.UpdateProgress(trackId, percent); + this.HasPoints = false; + if (this.SecondsToProgressivePlayback == 0 && this.AllowPlay) + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_PLAY_SONG); + else + this.Description = string.Format(ZuneUI.Shell.LoadString(StringId.IDS_DOWNLOAD_PROGRESS), (object)(int)percent); + this.Downloading = true; + this.Available = true; + } + + private void OnDownloadEvent(Guid trackId, HRESULT hr) + { + if (!(trackId == this.m_id)) + return; + if (hr == HRESULT._E_PENDING && (!this.DownloadingHidden || this.ShowHiddenProgress)) + { + this.HasPoints = false; + this.Description = ZuneUI.Shell.LoadString(StringId.IDS_PENDING); + this.Downloading = true; + this.Available = true; + } + else + this.UpdateState(); + } + + public DataProviderObject Model + { + get => this.m_model; + set + { + if (this.m_model == value) + return; + this.m_model = value; + this.m_id = value != null ? (Guid)this.m_model.GetProperty(this.ZuneMediaIdPropertyName) : Guid.Empty; + this.UpdateProgress(Guid.Empty, -1f); + this.UpdateState(); + this.FirePropertyChanged(nameof(Model)); + } + } + + protected virtual string ZuneMediaIdPropertyName => "Id"; + + public Guid Id + { + get => this.m_id; + set + { + if (!(this.m_id != value)) + return; + this.m_id = value; + this.FirePropertyChanged(nameof(Id)); + } + } + + public bool HasPoints + { + get => this.m_hasPoints; + set + { + if (this.m_hasPoints == value) + return; + this.m_hasPoints = value; + this.FirePropertyChanged(nameof(HasPoints)); + } + } + + protected abstract EContentType ContentType { get; } + + protected int CollectionId + { + get => this.m_collectionId; + set + { + if (this.m_collectionId == value) + return; + this.m_collectionId = value; + this.FirePropertyChanged(nameof(CollectionId)); + this.FirePropertyChanged("CanFindInCollection"); + this.FirePropertyChanged("CanFindInCollectionOwned"); + this.FirePropertyChanged("CanFindInHiddenCollection"); + } + } + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + if (!fDisposing) + return; + Download.Instance.DownloadEvent -= new DownloadEventHandler(this.OnDownloadEvent); + Download.Instance.DownloadProgressEvent -= new DownloadEventProgressHandler(this.OnDownloadProgressEvent); + } + + public StringId AddToCollectionStringId + { + get => this.m_addToCollectionStringId; + set + { + if (this.m_addToCollectionStringId == value) + return; + this.m_addToCollectionStringId = value; + this.FirePropertyChanged(nameof(AddToCollectionStringId)); + } + } + } +} diff --git a/ZuneUI/MarketplaceAppActionCommand.cs b/ZuneUI/MarketplaceAppActionCommand.cs new file mode 100644 index 0000000..0e44ced --- /dev/null +++ b/ZuneUI/MarketplaceAppActionCommand.cs @@ -0,0 +1,139 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceAppActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System; +using ZuneXml; + +namespace ZuneUI +{ + public class MarketplaceAppActionCommand : MarketplaceActionCommand + { + private string _serviceVersionString; + private bool _allowPurchaseFull = true; + private bool _allowPurchaseTrial = true; + + public override void FindInCollection() + { + if (!this.CanFindInCollection) + return; + ApplicationLibraryPage.FindInCollection(this.CollectionId); + } + + internal AppData AppData => (AppData)this.Model; + + public bool AllowPurchaseFull + { + get => this._allowPurchaseFull; + set + { + if (this._allowPurchaseFull == value) + return; + this._allowPurchaseFull = value; + this.FirePropertyChanged(nameof(AllowPurchaseFull)); + this.FirePropertyChanged("CanPurchaseFull"); + this.UpdateState(); + } + } + + public bool AllowPurchaseTrial + { + get => this._allowPurchaseTrial; + set + { + if (this._allowPurchaseTrial == value) + return; + this._allowPurchaseTrial = value; + this.FirePropertyChanged(nameof(AllowPurchaseTrial)); + this.FirePropertyChanged("CanPurchaseTrial"); + this.UpdateState(); + } + } + + private string ServiceVersionString + { + get + { + if (this._serviceVersionString == null) + this._serviceVersionString = this.Model != null ? (string)this.Model.GetProperty("Version") : (string)null; + return this._serviceVersionString; + } + } + + public bool NeedsUpdate + { + get + { + bool flag = false; + return this.CanFindInCollection ? ApplicationLibraryPage.DoesApplicationNeedUpdate(this.CollectionId, this.ServiceVersionString) : flag; + } + } + + public bool CanDownload => this.AppData != null && this.AppData.CanDownload && this.AllowDownload; + + public bool CanPurchaseFull => this.AppData != null && this.AppData.CanPurchaseFull && this.AllowPurchaseFull; + + public bool CanPurchaseTrial => this.AppData != null && this.AppData.CanPurchaseTrial && this.AllowPurchaseTrial; + + protected override EContentType ContentType => EContentType.App; + + protected override void OnPropertyChanged(string property) + { + base.OnPropertyChanged(property); + if ("Model" == property) + { + this.Id = this.Model != null ? (Guid)this.Model.GetProperty("Id") : Guid.Empty; + this._serviceVersionString = (string)null; + this.FirePropertyChanged("CanDownload"); + this.FirePropertyChanged("CanPurchaseFull"); + this.FirePropertyChanged("CanPurchaseTrial"); + } + else + { + if (!("AllowDownload" == property)) + return; + this.FirePropertyChanged("CanDownload"); + } + } + + public override void UpdateState() + { + base.UpdateState(); + if (this.Downloading) + return; + if (this.NeedsUpdate) + { + this.Description = Shell.LoadString(StringId.IDS_UPDATE); + this.Available = true; + } + else + { + if (this.CanFindInCollection) + return; + if (this.CanDownload) + { + this.Description = Shell.LoadString(StringId.IDS_DOWNLOAD); + this.Available = true; + } + else if (this.CanPurchaseFull) + { + if (this.AppData.Price == 0.0) + this.Description = Shell.LoadString(StringId.IDS_FREE); + else + this.Description = string.Format(Shell.LoadString(StringId.IDS_BUY_CURRENCY), (object)this.AppData.DisplayPriceFull); + this.Available = true; + } + else + { + if (!this.CanPurchaseTrial) + return; + this.Description = Shell.LoadString(StringId.IDS_TRY); + this.Available = true; + } + } + } + } +} diff --git a/ZuneUI/MarketplaceArtistPageState.cs b/ZuneUI/MarketplaceArtistPageState.cs new file mode 100644 index 0000000..11defa0 --- /dev/null +++ b/ZuneUI/MarketplaceArtistPageState.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceArtistPageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class MarketplaceArtistPageState + { + private string _pivot; + private string _album; + private bool _showSongs; + + public MarketplaceArtistPageState( + string selectedPivotId, + string selectedAlbumId, + bool showSongs) + { + this._pivot = selectedPivotId; + this._album = selectedAlbumId; + this._showSongs = showSongs; + } + + public string SelectedPivotId + { + get => this._pivot; + set => this._pivot = value; + } + + public string SelectedAlbumId + { + get => this._album; + set => this._album = value; + } + + public bool ShowSongs + { + get => this._showSongs; + set => this._showSongs = value; + } + } +} diff --git a/ZuneUI/MarketplaceCredentialsForDevice.cs b/ZuneUI/MarketplaceCredentialsForDevice.cs new file mode 100644 index 0000000..438c080 --- /dev/null +++ b/ZuneUI/MarketplaceCredentialsForDevice.cs @@ -0,0 +1,90 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceCredentialsForDevice +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class MarketplaceCredentialsForDevice : ModelItem + { + private string _email; + private string _password; + private string _zuneTag; + private Guid _userGuid; + private bool _purchaseEnabled; + private bool _newTagSet; + private Choice _enableMarketplaceChoice; + private int _hr = HRESULT._E_PENDING.Int; + + public MarketplaceCredentialsForDevice( + string email, + string password, + bool purchaseEnabled, + bool alreadyAssociated, + string zuneTag, + Choice enableMarketplaceChoice) + { + this._email = email; + this._password = password; + this._purchaseEnabled = purchaseEnabled; + this._zuneTag = zuneTag; + this._enableMarketplaceChoice = enableMarketplaceChoice; + this._newTagSet = alreadyAssociated; + } + + public string Email + { + get => this._email; + set => this._email = value; + } + + public string Password + { + get => this._password; + set => this._password = value; + } + + public string ZuneTag + { + get => this._zuneTag; + set + { + if (!(this._zuneTag != value)) + return; + this._zuneTag = value; + this._newTagSet = !string.IsNullOrEmpty(this.ZuneTag); + this.FirePropertyChanged("IsAssociated"); + } + } + + public Guid UserGuid + { + get => this._userGuid; + set => this._userGuid = value; + } + + public bool PurchaseEnabled + { + get => this._purchaseEnabled; + set + { + if (this._purchaseEnabled == value) + return; + this._purchaseEnabled = value; + this.FirePropertyChanged(nameof(PurchaseEnabled)); + } + } + + public bool IsAssociated => this._enableMarketplaceChoice.ChosenIndex != 0 && this._newTagSet; + + public int hr + { + get => this._hr; + set => this._hr = value; + } + } +} diff --git a/ZuneUI/MarketplaceExperience.cs b/ZuneUI/MarketplaceExperience.cs new file mode 100644 index 0000000..f7e9499 --- /dev/null +++ b/ZuneUI/MarketplaceExperience.cs @@ -0,0 +1,221 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceExperience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System.Collections; + +namespace ZuneUI +{ + public class MarketplaceExperience : Experience + { + private ArrayListDataSet _nodes; + private Node _recommendations; + private Node _music; + private Node _videos; + private Node _podcasts; + private Node _apps; + private Node _channels; + private Node _cart; + private Node _downloads; + private int _cartItemsCount; + private bool _cartItemsCountInitialized; + + public MarketplaceExperience(Frame frameOwner) + : base(frameOwner, StringId.IDS_MARKETPLACE_PIVOT, SQMDataId.MarketplaceClicks) + { + } + + public override IList NodesList + { + get + { + if (this._nodes == null) + { + this._nodes = new ArrayListDataSet((IModelItemOwner)this); + if (FeatureEnablement.IsFeatureEnabled(Features.ePicks)) + this._nodes.Add((object)this.Recommendations); + if (FeatureEnablement.IsFeatureEnabled(Features.eMusic)) + this._nodes.Add((object)this.Music); + if (FeatureEnablement.IsFeatureEnabled(Features.eVideos)) + this._nodes.Add((object)this.Videos); + if (FeatureEnablement.IsFeatureEnabled(Features.ePodcasts)) + this._nodes.Add((object)this.Podcasts); + if (FeatureEnablement.IsFeatureEnabled(Features.eChannels)) + this._nodes.Add((object)this.Channels); + if (FeatureEnablement.IsFeatureEnabled(Features.eGames) || FeatureEnablement.IsFeatureEnabled(Features.eApps)) + this._nodes.Add((object)this.Apps); + } + return (IList)this._nodes; + } + } + + protected override void OnIsCurrentChanged() + { + base.OnIsCurrentChanged(); + if (!this.IsCurrent) + return; + CultureHelper.CheckMarketplaceCulture(); + } + + public Node Recommendations + { + get + { + if (this._recommendations == null) + this._recommendations = new Node((Experience)this, StringId.IDS_RECOMMENDATIONS_PIVOT, "Marketplace\\Recommendations\\Home", SQMDataId.MarketplaceRecommendationsClicks); + return this._recommendations; + } + } + + public Node Music + { + get + { + if (this._music == null) + this._music = new Node((Experience)this, StringId.IDS_MUSIC_PIVOT, "Marketplace\\Music\\Home", SQMDataId.MarketplaceMusicClicks); + return this._music; + } + } + + public Node Videos + { + get + { + if (this._videos == null) + this._videos = new Node((Experience)this, StringId.IDS_VIDEO_PIVOT, "Marketplace\\Videos\\Home", SQMDataId.MarketplaceVideosClicks); + return this._videos; + } + } + + public Node Podcasts + { + get + { + if (this._podcasts == null) + this._podcasts = new Node((Experience)this, StringId.IDS_PODCASTS_PIVOT, "Marketplace\\Podcasts\\Home", SQMDataId.MarketplacePodcastsClicks); + return this._podcasts; + } + } + + public Node Apps + { + get + { + if (this._apps == null) + this._apps = new Node((Experience)this, StringId.IDS_APPS_PIVOT, "Marketplace\\Apps\\Home", SQMDataId.Invalid); + return this._apps; + } + } + + public Node Channels + { + get + { + if (this._channels == null) + this._channels = new Node((Experience)this, StringId.IDS_CHANNELS_PIVOT, "Marketplace\\Channels\\Home", SQMDataId.MarketplaceChannelsClicks); + return this._channels; + } + } + + public Node Cart + { + get + { + if (this._cart == null) + this._cart = new Node((Experience)this, StringId.IDS_CART_PIVOT, "Marketplace\\Cart", SQMDataId.MarketplaceCartClicks); + return this._cart; + } + } + + public Node Downloads + { + get + { + if (this._downloads == null) + this._downloads = new Node((Experience)this, StringId.IDS_DOWNLOADS_PIVOT, "Marketplace\\Downloads\\Home", SQMDataId.MarketplaceDownloadsClicks); + return this._downloads; + } + } + + public int CartItemsCount + { + get => this._cartItemsCount; + set + { + if (this._cartItemsCount == value) + return; + this._cartItemsCount = value; + this.FirePropertyChanged(nameof(CartItemsCount)); + Shell.MainFrame.Marketplace.UpdatePivots(); + } + } + + public bool CartItemsCountInitialized + { + get => this._cartItemsCountInitialized; + set + { + if (this._cartItemsCountInitialized == value) + return; + this._cartItemsCountInitialized = value; + this.FirePropertyChanged(nameof(CartItemsCountInitialized)); + } + } + + public void UpdatePivots() => this.ShowCart(FeatureEnablement.IsFeatureEnabled(Features.eMusic) && this.CartItemsCount > 0); + + public void UpdateDownloadPivot(bool show) + { + int nodeIndex = this.GetNodeIndex(this.Downloads); + bool flag = nodeIndex != -1; + if (show == flag) + return; + this.Downloads.Available = show; + if (show) + this.NodesList.Add((object)this.Downloads); + else + this.NodesList.RemoveAt(nodeIndex); + } + + private void ShowCart(bool show) + { + int nodeIndex = this.GetNodeIndex(this.Cart); + bool flag = nodeIndex != -1; + if (show == flag) + return; + this.Cart.Available = show; + if (show) + { + int index = this.GetNodeIndex(this.Downloads); + if (index == -1) + index = this.NodesList.Count; + this.NodesList.Insert(index, (object)this.Cart); + } + else + this.NodesList.RemoveAt(nodeIndex); + } + + protected override void OnInvoked() + { + if (!this.IsCurrent && (Node)this.Nodes.ChosenValue == this._recommendations && !SignIn.Instance.SignedIn) + this.Nodes.ChosenIndex = 1; + base.OnInvoked(); + } + + public override string DefaultUIPath + { + get + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMusic)) + return "Marketplace\\Music\\Home"; + if (FeatureEnablement.IsFeatureEnabled(Features.eVideos)) + return "Marketplace\\Videos\\Home"; + return FeatureEnablement.IsFeatureEnabled(Features.eApps) ? "Marketplace\\Apps\\Home" : "Marketplace\\Default"; + } + } + } +} diff --git a/ZuneUI/MarketplacePlaybackTrack.cs b/ZuneUI/MarketplacePlaybackTrack.cs new file mode 100644 index 0000000..41eaabd --- /dev/null +++ b/ZuneUI/MarketplacePlaybackTrack.cs @@ -0,0 +1,133 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplacePlaybackTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using MicrosoftZunePlayback; +using System; + +namespace ZuneUI +{ + [Serializable] + public class MarketplacePlaybackTrack : PlaybackTrack + { + private bool _subscriptionPlay; + private Guid _zuneMediaId; + private string _title; + private string _album; + private string _artist; + private TimeSpan _duration; + private int _trackNumber; + private string _genre; + private Guid _albumId; + private string _context; + private long _incrementPlayCountAfter; + private bool _hasReportedStreamPlayback; + private bool _hasReportedStreamPlaySkip; + + public MarketplacePlaybackTrack( + bool subscriptionPlay, + Guid zuneMediaId, + string title, + TimeSpan duration, + string album, + string artist, + int trackNumber, + string genre, + Guid albumId, + string context) + { + this._subscriptionPlay = subscriptionPlay; + this._zuneMediaId = zuneMediaId; + this._title = title; + this._duration = duration; + this._album = album; + this._artist = artist; + this._trackNumber = trackNumber; + this._genre = genre; + this._albumId = albumId; + if (!string.IsNullOrEmpty(context)) + this._context = context; + this._incrementPlayCountAfter = subscriptionPlay ? 200000000L : 1L; + } + + public override HRESULT GetURI(out string uri) + { + string uriOut = (string)null; + if (ZuneApplication.Service.InCompleteCollection(this._zuneMediaId, Microsoft.Zune.Service.EContentType.MusicTrack)) + ZuneApplication.Service.GetContentUri(this._zuneMediaId, Microsoft.Zune.Service.EContentType.MusicTrack, Microsoft.Zune.Service.EContentUriFlags.FallbackToPreview, out uriOut, out Guid _); + if (string.IsNullOrEmpty(uriOut)) + uriOut = "vnd.ms.zunecp://CP/?ContentPartnerKeyName=zune&StreamType=Music&TrackID=" + this._zuneMediaId.ToString(); + uri = uriOut; + return HRESULT._S_OK; + } + + internal override void OnBeginPlayback(PlayerInterop playbackWrapper) + { + base.OnBeginPlayback(playbackWrapper); + this._hasReportedStreamPlayback = false; + this._hasReportedStreamPlaySkip = false; + Microsoft.Zune.Util.Notification.BroadcastNowPlaying(EMediaTypes.eMediaTypeAudio, this.Album, this.Artist, this.Title, this.TrackNumber, this.ZuneMediaId); + } + + internal override void OnEndPlayback(bool endOfMedia) + { + base.OnEndPlayback(endOfMedia); + Microsoft.Zune.Util.Notification.ResetNowPlaying(); + } + + internal override void OnPositionChanged(long position) + { + if (this._hasReportedStreamPlayback || position < this._incrementPlayCountAfter) + return; + this._hasReportedStreamPlayback = true; + if (this._subscriptionPlay) + { + UsageDataService.ReportTrackSubscriptionPlayback(this._zuneMediaId, this._context); + if (this.MediaType != MediaType.Track) + return; + ++ZuneUI.Shell.MainFrame.Social.PlayCount; + } + else + UsageDataService.ReportTrackPreviewPlayback(this._zuneMediaId, this._context); + } + + internal override void OnSkip() + { + if (this._hasReportedStreamPlayback || this._hasReportedStreamPlaySkip) + return; + this._hasReportedStreamPlaySkip = true; + if (this._subscriptionPlay) + UsageDataService.ReportTrackSubscriptionSkipPlay(this._zuneMediaId, this._context); + else + UsageDataService.ReportTrackPreviewSkipPlay(this._zuneMediaId, this._context); + } + + public override string Title => this._title; + + public string Album => this._album; + + public string Artist => this._artist; + + public override TimeSpan Duration => this._duration; + + public override Guid ZuneMediaId => this._zuneMediaId; + + public override bool IsMusic => true; + + public override bool IsStreaming => true; + + public int TrackNumber => this._trackNumber; + + public string Genre => this._genre; + + public Guid AlbumId => this._albumId; + + public override MediaType MediaType => MediaType.Track; + + public override string ServiceContext => this._context; + } +} diff --git a/ZuneUI/MarketplacePlaylistTrack.cs b/ZuneUI/MarketplacePlaylistTrack.cs new file mode 100644 index 0000000..36226fe --- /dev/null +++ b/ZuneUI/MarketplacePlaylistTrack.cs @@ -0,0 +1,30 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplacePlaylistTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class MarketplacePlaylistTrack : MarketplaceTrackActionCommand + { + public MarketplacePlaylistTrack() => Download.Instance.DownloadAllPendingEvent += new EventHandler(this.OnDownloadAllPendingEvent); + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing) + return; + Download.Instance.DownloadAllPendingEvent -= new EventHandler(this.OnDownloadAllPendingEvent); + } + + private void OnDownloadAllPendingEvent(object sender, object args) + { + if (this.Downloading || this.DownloadingHidden && !this.ShowHiddenProgress) + return; + this.UpdateState(); + } + } +} diff --git a/ZuneUI/MarketplaceReportAConcernCommand.cs b/ZuneUI/MarketplaceReportAConcernCommand.cs new file mode 100644 index 0000000..f2befba --- /dev/null +++ b/ZuneUI/MarketplaceReportAConcernCommand.cs @@ -0,0 +1,108 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceReportAConcernCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public class MarketplaceReportAConcernCommand : Command + { + private HRESULT m_lastError; + private EConcernType m_concernType; + private EContentType m_contentType; + private Guid m_mediaId; + private string m_message; + + public MarketplaceReportAConcernCommand() + { + } + + public MarketplaceReportAConcernCommand(IModelItem owner) + : base((IModelItemOwner)owner) + { + } + + public event EventHandler Completed; + + public HRESULT LastError + { + get => this.m_lastError; + private set + { + if (!(this.m_lastError != value)) + return; + this.m_lastError = value; + this.FirePropertyChanged(nameof(LastError)); + } + } + + public EConcernType ConcernType + { + get => this.m_concernType; + set + { + if (this.m_concernType == value) + return; + this.m_concernType = value; + this.FirePropertyChanged(nameof(ConcernType)); + } + } + + public EContentType ContentType + { + get => this.m_contentType; + set + { + if (this.m_contentType == value) + return; + this.m_contentType = value; + this.FirePropertyChanged(nameof(ContentType)); + } + } + + public Guid MediaId + { + get => this.m_mediaId; + set + { + if (!(this.m_mediaId != value)) + return; + this.m_mediaId = value; + this.FirePropertyChanged(nameof(MediaId)); + } + } + + public string Message + { + get => this.m_message; + set + { + if (!(this.m_message != value)) + return; + this.m_message = value; + this.FirePropertyChanged(nameof(Message)); + } + } + + protected override void OnInvoked() => Microsoft.Zune.Service.Service.Instance.ReportAConcern(this.m_concernType, this.m_contentType, this.m_mediaId, this.m_message, new AsyncCompleteHandler(this.OnCompleteHandler)); + + private void OnCompleteHandler(HRESULT hr) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnCompleteHandler), (object)hr); + + private void OnCompleteHandler(object arg) + { + this.LastError = (HRESULT)arg; + if (this.Completed != null) + this.Completed((object)this, (EventArgs)null); + this.FirePropertyChanged("Completed"); + if (!this.LastError.IsError) + return; + ErrorDialogInfo.Show(this.LastError.Int, Shell.LoadString(StringId.IDS_PodcastConcernTitle)); + } + } +} diff --git a/ZuneUI/MarketplaceReportFavouriteArtistsCommand.cs b/ZuneUI/MarketplaceReportFavouriteArtistsCommand.cs new file mode 100644 index 0000000..a3cd6d1 --- /dev/null +++ b/ZuneUI/MarketplaceReportFavouriteArtistsCommand.cs @@ -0,0 +1,82 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceReportFavouriteArtistsCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class MarketplaceReportFavouriteArtistsCommand : Command + { + private HRESULT m_lastError; + private Guid m_userId; + private IList m_artists; + + public MarketplaceReportFavouriteArtistsCommand() + { + } + + public MarketplaceReportFavouriteArtistsCommand(IModelItem owner) + : base((IModelItemOwner)owner) + { + } + + public event EventHandler Completed; + + public HRESULT LastError + { + get => this.m_lastError; + private set + { + if (!(this.m_lastError != value)) + return; + this.m_lastError = value; + this.FirePropertyChanged(nameof(LastError)); + } + } + + public Guid UserId + { + get => this.m_userId; + set + { + if (!(this.m_userId != value)) + return; + this.m_userId = value; + this.FirePropertyChanged(nameof(UserId)); + } + } + + public IList Artists + { + get => this.m_artists; + set + { + if (this.m_artists == value) + return; + this.m_artists = value; + this.FirePropertyChanged(nameof(Artists)); + } + } + + protected override void OnInvoked() => Microsoft.Zune.Service.Service.Instance.ReportFavouriteArtists(this.m_userId, this.m_artists, new AsyncCompleteHandler(this.OnCompleteHandler)); + + private void OnCompleteHandler(HRESULT hr) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnCompleteHandler), (object)hr); + + private void OnCompleteHandler(object arg) + { + this.LastError = (HRESULT)arg; + if (this.Completed != null) + this.Completed((object)this, (EventArgs)null); + this.FirePropertyChanged("Completed"); + if (!this.LastError.IsError) + return; + ErrorDialogInfo.Show(this.LastError.Int, Shell.LoadString(StringId.IDS_ArtistChooserUploadFailedDialogTitle)); + } + } +} diff --git a/ZuneUI/MarketplaceTrackActionCommand.cs b/ZuneUI/MarketplaceTrackActionCommand.cs new file mode 100644 index 0000000..eaa57fb --- /dev/null +++ b/ZuneUI/MarketplaceTrackActionCommand.cs @@ -0,0 +1,92 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceTrackActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; +using ZuneXml; + +namespace ZuneUI +{ + public class MarketplaceTrackActionCommand : MarketplaceActionCommand + { + public MarketplaceTrackActionCommand() => SignIn.Instance.SignInStatusUpdatedEvent += new EventHandler(this.OnSignInEvent); + + internal Track TrackModel => this.Model as Track; + + public override void UpdateState() + { + base.UpdateState(); + if (this.TrackModel == null || this.CanFindInCollection || this.CanFindInHiddenCollection) + return; + if (!this.Downloading) + { + if (this.TrackModel.CanPurchaseFree) + { + this.Description = Shell.LoadString(StringId.IDS_FREE); + this.Available = true; + } + else if (this.TrackModel.CanDownload) + { + this.Description = Shell.LoadString(StringId.IDS_DOWNLOAD); + this.Available = !this.DownloadingHidden; + } + else if (this.TrackModel.CanPurchaseSubscriptionFree) + { + this.Description = Shell.LoadString(StringId.IDS_PURCHASE_BUTTON); + this.Available = true; + } + else if (this.TrackModel.CanPurchaseAlbumOnly) + { + this.Description = Shell.LoadString(StringId.IDS_ALBUM_ONLY); + this.Available = false; + } + else if (this.TrackModel.CanPurchase) + { + this.Description = string.Format(Shell.LoadString(StringId.IDS_BUY), (object)this.TrackModel.PointsPrice); + this.Available = true; + this.HasPoints = this.TrackModel.HasPoints; + } + else if (this.TrackModel.CanSubscriptionPlay) + { + this.Description = Shell.LoadString(StringId.IDS_PLAY_SONG); + this.Available = true; + } + else if (this.TrackModel.CanPreview) + { + this.Description = Shell.LoadString(StringId.IDS_PREVIEW_SONG); + this.Available = true; + } + else if (this.CanFindInZuneDotNet && !FeatureEnablement.IsFeatureEnabled(Features.eMusic)) + { + this.Description = Shell.LoadString(StringId.IDS_MORE_INFO); + this.Available = true; + } + } + if (this.TrackModel.CanPurchase || !((HRESULT)Download.Instance.GetErrorCode(this.Id) == HRESULT._NS_E_MEDIA_NOT_PURCHASED)) + return; + Download.Instance.SetErrorCode(this.Id, HRESULT._S_OK.Int); + } + + public override void FindInCollection() + { + if (!this.CanFindInCollection) + return; + MusicLibraryPage.FindInCollection(-1, -1, this.CollectionId); + } + + protected override Microsoft.Zune.Service.EContentType ContentType => Microsoft.Zune.Service.EContentType.MusicTrack; + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + if (!fDisposing) + return; + SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignInEvent); + } + + private void OnSignInEvent(object sender, EventArgs args) => this.UpdateState(); + } +} diff --git a/ZuneUI/MarketplaceTrackHistoryActionCommand.cs b/ZuneUI/MarketplaceTrackHistoryActionCommand.cs new file mode 100644 index 0000000..b41bfe1 --- /dev/null +++ b/ZuneUI/MarketplaceTrackHistoryActionCommand.cs @@ -0,0 +1,36 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceTrackHistoryActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using ZuneXml; + +namespace ZuneUI +{ + public class MarketplaceTrackHistoryActionCommand : MarketplaceTrackActionCommand + { + internal TrackHistory TrackHistoryModel => (TrackHistory)this.Model; + + public override void UpdateState() + { + base.UpdateState(); + if (!this.CanFindInCollection && !this.Downloading) + { + if (!this.TrackHistoryModel.CanDownload) + { + this.Description = Shell.LoadString(StringId.IDS_PURCHASE_BUTTON); + Download.Instance.SetHistoryErrorCode(this.Id, HRESULT._NS_E_MEDIA_DOWNLOAD_MAXIMUM_EXCEEDED.Int); + } + else + this.Description = Shell.LoadString(StringId.IDS_DOWNLOAD); + this.Available = true; + } + else + this.Available = false; + } + + protected override EContentType ContentType => EContentType.MusicTrack; + } +} diff --git a/ZuneUI/MarketplaceVideoActionCommand.cs b/ZuneUI/MarketplaceVideoActionCommand.cs new file mode 100644 index 0000000..0b42b21 --- /dev/null +++ b/ZuneUI/MarketplaceVideoActionCommand.cs @@ -0,0 +1,69 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceVideoActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using ZuneXml; + +namespace ZuneUI +{ + public class MarketplaceVideoActionCommand : MarketplaceActionCommand + { + private bool _enableForAlbumOnly; + + public override void FindInCollection() + { + if (!this.CanFindInCollection) + return; + VideoLibraryPage.FindInCollection(this.CollectionId); + } + + internal Video VideoModel => (Video)this.Model; + + public bool EnableForAlbumOnly + { + get => this._enableForAlbumOnly; + set + { + if (this._enableForAlbumOnly == value) + return; + this._enableForAlbumOnly = value; + this.FirePropertyChanged(nameof(EnableForAlbumOnly)); + } + } + + public override void UpdateState() + { + base.UpdateState(); + if (this.CanFindInCollection || this.Downloading) + return; + if (this.VideoModel.CanPurchaseAlbumOnly) + { + this.Description = Shell.LoadString(StringId.IDS_ALBUM_ONLY); + this.Available = this._enableForAlbumOnly; + } + else if (this.VideoModel.CanRent) + { + this.Description = Shell.LoadString(StringId.IDS_RENT_BUTTON); + this.Available = true; + } + else if (this.VideoModel.CanPurchase) + { + if (this.VideoModel.PointsPrice > 0) + this.Description = Shell.LoadString(StringId.IDS_PURCHASE_BUTTON); + else + this.Description = Shell.LoadString(StringId.IDS_FREE); + this.Available = true; + } + else + { + this.Description = Shell.LoadString(StringId.IDS_NOT_AVAILABLE); + this.Available = false; + } + } + + protected override EContentType ContentType => EContentType.Video; + } +} diff --git a/ZuneUI/MarketplaceVideoHistoryActionCommand.cs b/ZuneUI/MarketplaceVideoHistoryActionCommand.cs new file mode 100644 index 0000000..e12268e --- /dev/null +++ b/ZuneUI/MarketplaceVideoHistoryActionCommand.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceVideoHistoryActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using ZuneXml; + +namespace ZuneUI +{ + public abstract class MarketplaceVideoHistoryActionCommand : MarketplaceActionCommand + { + public MarketplaceVideoHistoryActionCommand() => this.AllowPlay = false; + + public override void FindInCollection() + { + if (!this.CanFindInCollection) + return; + VideoLibraryPage.FindInCollection(this.CollectionId); + } + + internal VideoHistory VideoHistoryModel => (VideoHistory)this.Model; + + protected override void OnInvoked() + { + if (this.Downloading) + return; + base.OnInvoked(); + } + + protected override EContentType ContentType => EContentType.Video; + } +} diff --git a/ZuneUI/MarketplaceVideoPurchaseHistoryActionCommand.cs b/ZuneUI/MarketplaceVideoPurchaseHistoryActionCommand.cs new file mode 100644 index 0000000..1980db8 --- /dev/null +++ b/ZuneUI/MarketplaceVideoPurchaseHistoryActionCommand.cs @@ -0,0 +1,48 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceVideoPurchaseHistoryActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class MarketplaceVideoPurchaseHistoryActionCommand : MarketplaceVideoHistoryActionCommand + { + public override void UpdateState() + { + base.UpdateState(); + if (!this.Downloading) + { + if (this.CanFindInCollectionShortcut) + { + this.Description = Shell.LoadString(StringId.IDS_DOWNLOAD); + this.Available = true; + } + else if (!this.CanFindInCollection) + { + if (!this.VideoHistoryModel.CanDownload && !this.VideoHistoryModel.CanPurchase) + { + this.Description = Shell.LoadString(StringId.IDS_NOT_AVAILABLE); + this.Available = false; + Download.Instance.SetHistoryErrorCode(this.Id, HRESULT._ZUNE_E_CONTENT_NOT_SUPPORTED_ON_TUNER.Int); + } + else if (!this.VideoHistoryModel.CanDownload) + { + this.Description = Shell.LoadString(StringId.IDS_PURCHASE_BUTTON); + this.Available = true; + Download.Instance.SetHistoryErrorCode(this.Id, HRESULT._NS_E_MEDIA_DOWNLOAD_MAXIMUM_EXCEEDED.Int); + } + else + { + this.Description = Shell.LoadString(StringId.IDS_DOWNLOAD); + this.Available = true; + } + } + else + this.Available = false; + } + else + this.Available = false; + } + } +} diff --git a/ZuneUI/MarketplaceVideoRentalHistoryActionCommand.cs b/ZuneUI/MarketplaceVideoRentalHistoryActionCommand.cs new file mode 100644 index 0000000..0c18b6c --- /dev/null +++ b/ZuneUI/MarketplaceVideoRentalHistoryActionCommand.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MarketplaceVideoRentalHistoryActionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class MarketplaceVideoRentalHistoryActionCommand : MarketplaceVideoHistoryActionCommand + { + public override void UpdateState() + { + base.UpdateState(); + if (!this.CanFindInCollection && !this.Downloading) + { + if (!this.VideoHistoryModel.CanDownload && !this.VideoHistoryModel.CanRent) + { + this.Description = Shell.LoadString(StringId.IDS_NOT_AVAILABLE); + this.Available = false; + Download.Instance.SetHistoryErrorCode(this.Id, HRESULT._ZUNE_E_CONTENT_NOT_SUPPORTED_ON_TUNER.Int); + } + else if (!this.VideoHistoryModel.CanDownload) + { + this.Description = Shell.LoadString(StringId.IDS_RENT_BUTTON); + this.Available = true; + Download.Instance.SetHistoryErrorCode(this.Id, HRESULT._NS_E_MEDIA_DOWNLOAD_MAXIMUM_EXCEEDED.Int); + } + else + { + this.Description = Shell.LoadString(StringId.IDS_DOWNLOAD); + this.Available = true; + } + } + else if (this.CanFindInCollection && DrmHelper.IsRentalExpired(26, this.Id)) + { + this.Description = Shell.LoadString(StringId.IDS_RENT_BUTTON); + this.Available = true; + } + else + this.Available = false; + } + } +} diff --git a/ZuneUI/MathConstants.cs b/ZuneUI/MathConstants.cs new file mode 100644 index 0000000..018c26f --- /dev/null +++ b/ZuneUI/MathConstants.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MathConstants +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class MathConstants + { + public static float PI => 3.141593f; + + public static float HalfPI => 1.570796f; + + public static float DegreeToRadian(float value) => (float)((double)value / 180.0 * Math.PI); + + public static float E => 2.718282f; + } +} diff --git a/ZuneUI/MediaDescriptions.cs b/ZuneUI/MediaDescriptions.cs new file mode 100644 index 0000000..68d5df4 --- /dev/null +++ b/ZuneUI/MediaDescriptions.cs @@ -0,0 +1,39 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MediaDescriptions +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections.Generic; + +namespace ZuneUI +{ + public static class MediaDescriptions + { + private static Dictionary _mappings = new Dictionary(); + + static MediaDescriptions() + { + MediaDescriptions._mappings[MediaType.AudioMP4] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_AUDIOMP4); + MediaDescriptions._mappings[MediaType.AudioMP3] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_AUDIOMP3); + MediaDescriptions._mappings[MediaType.AudioWMA] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_AUDIOWMA); + MediaDescriptions._mappings[MediaType.AudioWAV] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_AUDIOWAV); + MediaDescriptions._mappings[MediaType.ImageJPEG] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_IMAGEJPEG); + MediaDescriptions._mappings[MediaType.VideoAVI] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_VIDEOAVI); + MediaDescriptions._mappings[MediaType.VideoMP4] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_VIDEOMP4); + MediaDescriptions._mappings[MediaType.VideoMPG] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_VIDEOMPG); + MediaDescriptions._mappings[MediaType.VideoWMV] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_VIDEOWMV); + MediaDescriptions._mappings[MediaType.VideoQT] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_VIDEOQT); + MediaDescriptions._mappings[MediaType.VideoDVRMS] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_VIDEODVRMS); + MediaDescriptions._mappings[MediaType.VideoMBR] = Shell.LoadString(StringId.IDS_LIBRARY_MEDIATYPE_VIDEOMBR); + } + + public static string Map(MediaType mediaType) + { + string str; + if (!MediaDescriptions._mappings.TryGetValue(mediaType, out str)) + str = ""; + return str; + } + } +} diff --git a/ZuneUI/MediaIdAndType.cs b/ZuneUI/MediaIdAndType.cs new file mode 100644 index 0000000..27754fd --- /dev/null +++ b/ZuneUI/MediaIdAndType.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MediaIdAndType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class MediaIdAndType : IDatabaseMedia + { + private int _id; + private EMediaTypes _type; + + public MediaIdAndType(int mediaId, MediaType type) + : this(mediaId, (EMediaTypes)type) + { + } + + public MediaIdAndType(int mediaId, EMediaTypes type) + { + this._id = mediaId; + this._type = type; + } + + public void GetMediaIdAndType(out int mediaId, out EMediaTypes mediaType) + { + mediaId = this._id; + mediaType = this._type; + } + } +} diff --git a/ZuneUI/MediaType.cs b/ZuneUI/MediaType.cs new file mode 100644 index 0000000..824f375 --- /dev/null +++ b/ZuneUI/MediaType.cs @@ -0,0 +1,40 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MediaType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum MediaType + { + Undefined = -1, // 0xFFFFFFFF + Track = 3, + Video = 4, + Photo = 5, + Playlist = 9, + Album = 11, // 0x0000000B + PodcastEpisode = 17, // 0x00000011 + Podcast = 18, // 0x00000012 + MediaFolder = 20, // 0x00000014 + Genre = 21, // 0x00000015 + AudioMP4 = 32, // 0x00000020 + AudioMP3 = 33, // 0x00000021 + AudioWMA = 34, // 0x00000022 + AudioWAV = 35, // 0x00000023 + ImageJPEG = 36, // 0x00000024 + VideoMP4 = 37, // 0x00000025 + VideoMPG = 38, // 0x00000026 + VideoWMV = 39, // 0x00000027 + VideoQT = 40, // 0x00000028 + AudioQT = 41, // 0x00000029 + VideoDVRMS = 42, // 0x0000002A + VideoMBR = 43, // 0x0000002B + VideoAVI = 44, // 0x0000002C + PlaylistChannel = 50, // 0x00000032 + PlaylistContentItem = 56, // 0x00000038 + Artist = 65, // 0x00000041 + UserCard = 96, // 0x00000060 + Application = 110, // 0x0000006E + } +} diff --git a/ZuneUI/MediaTypeCommand.cs b/ZuneUI/MediaTypeCommand.cs new file mode 100644 index 0000000..a73fc6e --- /dev/null +++ b/ZuneUI/MediaTypeCommand.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MediaTypeCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class MediaTypeCommand : Command + { + private MediaType _type; + + public MediaType Type + { + get => this._type; + set + { + if (this._type == value) + return; + this._type = value; + this.FirePropertyChanged(nameof(Type)); + } + } + } +} diff --git a/ZuneUI/MenuItemCommand.cs b/ZuneUI/MenuItemCommand.cs new file mode 100644 index 0000000..4c187da --- /dev/null +++ b/ZuneUI/MenuItemCommand.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MenuItemCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class MenuItemCommand : UIXControls.MenuItemCommand + { + public MenuItemCommand() + { + } + + public MenuItemCommand(string description) + : base(description) + { + } + } +} diff --git a/ZuneUI/MergeHelper.cs b/ZuneUI/MergeHelper.cs new file mode 100644 index 0000000..0f6c50d --- /dev/null +++ b/ZuneUI/MergeHelper.cs @@ -0,0 +1,92 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MergeHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using MicrosoftZuneLibrary; +using System.Collections; + +namespace ZuneUI +{ + public class MergeHelper + { + public static void MergeArtistsToArtist(string targetArtist, IList sourceArtists) + { + IList artistIds = (IList)new ArrayList(sourceArtists.Count); + foreach (LibraryDataProviderListItem sourceArtist in (IEnumerable)sourceArtists) + artistIds.Add((object)(int)sourceArtist.GetProperty("LibraryId")); + ZuneQueryList albumsByArtists = ZuneApplication.ZuneLibrary.GetAlbumsByArtists(artistIds, (string)null); + int num1 = (int)albumsByArtists.AddRef(); + uint count = (uint)albumsByArtists.Count; + for (uint index = 0; index < count; ++index) + albumsByArtists.SetFieldValue(index, 380U, (object)targetArtist); + int num2 = (int)albumsByArtists.Release(); + albumsByArtists.Dispose(); + } + + public static void MergeAlbumsToArtist(string targetArtist, IList sourceAlbums) + { + foreach (DataProviderObject sourceAlbum in (IEnumerable)sourceAlbums) + sourceAlbum.SetProperty("ArtistName", (object)targetArtist); + } + + public static void MergeTracksToArtist(string targetArtist, IList sourceTracks) + { + foreach (DataProviderObject sourceTrack in (IEnumerable)sourceTracks) + sourceTrack.SetProperty("AlbumArtistName", (object)targetArtist); + } + + public static void MergeAlbumsToAlbum( + string targetAlbumTitle, + string targetAlbumArtistName, + IList sourceAlbums) + { + foreach (LibraryDataProviderListItem sourceAlbum in (IEnumerable)sourceAlbums) + { + sourceAlbum.SetProperty("ArtistName", (object)targetAlbumArtistName); + sourceAlbum.SetProperty("Title", (object)targetAlbumTitle); + } + } + + public static void MergeTracksToAlbum( + string targetAlbumTitle, + string targetAlbumArtistName, + IList sourceTracks) + { + foreach (LibraryDataProviderListItem sourceTrack in (IEnumerable)sourceTracks) + { + sourceTrack.SetProperty("AlbumArtistName", (object)targetAlbumArtistName); + sourceTrack.SetProperty("AlbumName", (object)targetAlbumTitle); + } + } + + public static void MergeTracksToGenre(string targetGenre, IList sourceTracks) + { + foreach (DataProviderObject sourceTrack in (IEnumerable)sourceTracks) + sourceTrack.SetProperty("Genre", (object)targetGenre); + } + + public static void MergeAlbumsToGenre(string targetGenre, IList sourceAlbums) + { + IList albumIds = (IList)new ArrayList(sourceAlbums.Count); + foreach (LibraryDataProviderListItem sourceAlbum in (IEnumerable)sourceAlbums) + albumIds.Add((object)(int)sourceAlbum.GetProperty("LibraryId")); + ZuneQueryList tracksByAlbums = ZuneApplication.ZuneLibrary.GetTracksByAlbums(albumIds, (string)null); + int num1 = (int)tracksByAlbums.AddRef(); + uint count = (uint)tracksByAlbums.Count; + for (uint index = 0; index < count; ++index) + tracksByAlbums.SetFieldValue(index, 398U, (object)targetGenre); + int num2 = (int)tracksByAlbums.Release(); + tracksByAlbums.Dispose(); + } + + public static void MergeGenresToGenre(string targetGenre, IList sourceGenres) + { + foreach (DataProviderObject sourceGenre in (IEnumerable)sourceGenres) + sourceGenre.SetProperty("Title", (object)targetGenre); + } + } +} diff --git a/ZuneUI/MessageDetailsPanel.cs b/ZuneUI/MessageDetailsPanel.cs new file mode 100644 index 0000000..3bef957 --- /dev/null +++ b/ZuneUI/MessageDetailsPanel.cs @@ -0,0 +1,46 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MessageDetailsPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class MessageDetailsPanel : LibraryPanel + { + private DataProviderObject _selectedItem; + private string _title; + + internal MessageDetailsPanel(LibraryPage page, bool showHeaderAndFooter) + : base((IModelItemOwner)page) + { + } + + public DataProviderObject SelectedItem + { + get => this._selectedItem; + set + { + if (this._selectedItem == value) + return; + this._selectedItem = value; + this.FirePropertyChanged(nameof(SelectedItem)); + this.Title = (string)null; + } + } + + public string Title + { + get => this._title; + set + { + if (!(this._title != value)) + return; + this._title = value; + this.FirePropertyChanged(nameof(Title)); + } + } + } +} diff --git a/ZuneUI/MessageListFilter.cs b/ZuneUI/MessageListFilter.cs new file mode 100644 index 0000000..b62ffe0 --- /dev/null +++ b/ZuneUI/MessageListFilter.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MessageListFilter +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using ZuneXml; + +namespace ZuneUI +{ + public class MessageListFilter : FilterList + { + private bool _wishlistItems; + + public MessageListFilter(bool wishlistItems) => this._wishlistItems = wishlistItems; + + protected override bool ShouldIncludeItem(int sourceIndex, int targetIndex, object item) + { + bool flag = false; + if (item is MessageRoot messageRoot && messageRoot.Wishlist == this._wishlistItems) + flag = messageRoot.IsSupported; + return flag; + } + } +} diff --git a/ZuneUI/MessageNotification.cs b/ZuneUI/MessageNotification.cs new file mode 100644 index 0000000..7d8f2e4 --- /dev/null +++ b/ZuneUI/MessageNotification.cs @@ -0,0 +1,89 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MessageNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class MessageNotification : Notification + { + private string _message; + private string _subMessage; + + public MessageNotification(NotificationTask taskType, NotificationState notificationType) + : this((string)null, (string)null, taskType, notificationType, 0) + { + } + + public MessageNotification( + NotificationTask taskType, + NotificationState notificationType, + int displayTime) + : this((string)null, (string)null, taskType, notificationType, displayTime) + { + } + + public MessageNotification( + string message, + NotificationTask taskType, + NotificationState notificationType) + : this(message, (string)null, taskType, notificationType, 0) + { + } + + public MessageNotification( + string message, + NotificationTask taskType, + NotificationState notificationType, + int displayTime) + : this(message, (string)null, taskType, notificationType, displayTime) + { + } + + public MessageNotification( + string message, + string subMessage, + NotificationTask taskType, + NotificationState notificationType) + : this(message, subMessage, taskType, notificationType, 0) + { + } + + public MessageNotification( + string message, + string subMessage, + NotificationTask taskType, + NotificationState notificationType, + int displayTime) + : base(taskType, notificationType, displayTime) + { + this._message = message; + this._subMessage = subMessage; + } + + public string Message + { + set + { + if (!(this._message != value)) + return; + this._message = value; + this.FirePropertyChanged(nameof(Message)); + } + get => this._message; + } + + public string SubMessage + { + set + { + if (!(this._subMessage != value)) + return; + this._subMessage = value; + this.FirePropertyChanged(nameof(SubMessage)); + } + get => this._subMessage; + } + } +} diff --git a/ZuneUI/MessageRootHelper.cs b/ZuneUI/MessageRootHelper.cs new file mode 100644 index 0000000..3d3358b --- /dev/null +++ b/ZuneUI/MessageRootHelper.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MessageRootHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using ZuneXml; + +namespace ZuneUI +{ + public class MessageRootHelper + { + public static bool IsUnread(DataProviderObject message) => string.Compare(((MessageRoot)message).Status, "unread") == 0; + + public static void SetRead(DataProviderObject message, bool read) => ((MessageRoot)message).Status = read ? nameof(read) : "unread"; + + public static string UiType(DataProviderObject message) => MessageRootHelper.GetTypeInfo(message).UIText; + + public static string DetailsTemplate(DataProviderObject message) => MessageRootHelper.GetTypeInfo(message).DetailsTemplate; + + private static MessageTypeInfo GetTypeInfo(DataProviderObject message) => MessageTypeInfo.GetMessageType(((MessageRoot)message).Type); + } +} diff --git a/ZuneUI/MessageTypeInfo.cs b/ZuneUI/MessageTypeInfo.cs new file mode 100644 index 0000000..bfe2444 --- /dev/null +++ b/ZuneUI/MessageTypeInfo.cs @@ -0,0 +1,51 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MessageTypeInfo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + internal class MessageTypeInfo + { + private string _UIText; + private string _detailsTemplate; + private static Hashtable s_MessageTypes; + + public MessageTypeInfo(StringId uiText, string detailsTemplate) + { + this._UIText = Shell.LoadString(uiText); + this._detailsTemplate = detailsTemplate; + } + + public string UIText => this._UIText; + + public string DetailsTemplate => this._detailsTemplate; + + public static MessageTypeInfo GetMessageType(string serviceType) + { + if (MessageTypeInfo.s_MessageTypes == null) + { + MessageTypeInfo.s_MessageTypes = new Hashtable(17); + MessageTypeInfo.s_MessageTypes.Add((object)"album", (object)new MessageTypeInfo(StringId.IDS_TYPE_ALBUM, "res://ZuneShellResources!InboxTrackDetails.uix#AlbumDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"card", (object)new MessageTypeInfo(StringId.IDS_TYPE_CARD, "res://ZuneShellResources!InboxProfileDetails.uix#CardDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"forums", (object)new MessageTypeInfo(StringId.IDS_TYPE_FORUM, "res://ZuneShellResources!InboxTextDetails.uix#ForumDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"friendrequest", (object)new MessageTypeInfo(StringId.IDS_TYPE_FRIENDREQUEST, "res://ZuneShellResources!InboxProfileDetails.uix#FriendRequestUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"message", (object)new MessageTypeInfo(StringId.IDS_TYPE_TEXT, "res://ZuneShellResources!InboxTextDetails.uix#TextDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"musicvideo", (object)new MessageTypeInfo(StringId.IDS_TYPE_MUSICVIDEO, "res://ZuneShellResources!InboxTextDetails.uix#UnknownDetails")); + MessageTypeInfo.s_MessageTypes.Add((object)"notification", (object)new MessageTypeInfo(StringId.IDS_TYPE_NOTIFICATION, "res://ZuneShellResources!InboxTextDetails.uix#NotificationDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"photos", (object)new MessageTypeInfo(StringId.IDS_TYPE_PHOTOS, "res://ZuneShellResources!InboxPhotoDetails.uix#PhotoDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"playlist", (object)new MessageTypeInfo(StringId.IDS_TYPE_PLAYLIST, "res://ZuneShellResources!InboxTrackDetails.uix#PlaylistDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"podcast", (object)new MessageTypeInfo(StringId.IDS_TYPE_PODCASTSERIES, "res://ZuneShellResources!InboxPodcastDetails.uix#PodcastDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"song", (object)new MessageTypeInfo(StringId.IDS_TYPE_SONG, "res://ZuneShellResources!InboxTrackDetails.uix#TrackDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"video", (object)new MessageTypeInfo(StringId.IDS_TYPE_VIDEO, "res://ZuneShellResources!InboxVideoDetails.uix#EpisodeMessageDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"movie", (object)new MessageTypeInfo(StringId.IDS_TYPE_VIDEO, "res://ZuneShellResources!InboxVideoDetails.uix#MovieDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"movietrailer", (object)new MessageTypeInfo(StringId.IDS_TYPE_VIDEO, "res://ZuneShellResources!InboxVideoDetails.uix#TrailerDetailsUI")); + MessageTypeInfo.s_MessageTypes.Add((object)"", (object)new MessageTypeInfo(StringId.IDS_TYPE_UNKNOWN, "res://ZuneShellResources!InboxTextDetails.uix#UnknownDetails")); + } + return (MessageTypeInfo)(MessageTypeInfo.s_MessageTypes[(object)serviceType] ?? MessageTypeInfo.s_MessageTypes[(object)""]); + } + } +} diff --git a/ZuneUI/MetadataEditAlbum.cs b/ZuneUI/MetadataEditAlbum.cs new file mode 100644 index 0000000..23392f4 --- /dev/null +++ b/ZuneUI/MetadataEditAlbum.cs @@ -0,0 +1,168 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MetadataEditAlbum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using UIXControls; + +namespace ZuneUI +{ + public class MetadataEditAlbum : MetadataEditMedia + { + private static PropertyDescriptor[] s_properties = new PropertyDescriptor[9] + { + (PropertyDescriptor) MetadataEditMedia.s_Title, + MetadataEditMedia.s_AlbumTitleYomi, + (PropertyDescriptor) MetadataEditMedia.s_Artist, + MetadataEditMedia.s_AlbumArtistYomi, + MetadataEditMedia.s_Genre, + MetadataEditMedia.s_Conductor, + MetadataEditMedia.s_Composer, + (PropertyDescriptor) MetadataEditMedia.s_ReleaseYear, + MetadataEditMedia.s_CoverUrl + }; + private List _linkedProperties = new List((IEnumerable)new PropertyDescriptor[3] + { + MetadataEditMedia.s_Genre, + MetadataEditMedia.s_Conductor, + MetadataEditMedia.s_Composer + }); + private List _trackList = new List(); + + public MetadataEditAlbum(AlbumMetadata albumMetadata) => this.InitializeFromMetadataList(new List((IEnumerable)new AlbumMetadata[1] + { + albumMetadata + })); + + public MetadataEditAlbum(IList albumList) + { + List albumMetadataList = new List(albumList.Count); + try + { + foreach (DataProviderObject album in (IEnumerable)albumList) + { + AlbumMetadata albumMetadata = ZuneApplication.ZuneLibrary.GetAlbumMetadata((int)album.GetProperty("LibraryId")); + albumMetadataList.Add(albumMetadata); + } + } + catch (Exception ex) + { + this._creationFailed = true; + albumMetadataList.Clear(); + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_EMI_UPDATEFAILED_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_EMI_UPDATEFAILED), (EventHandler)null); + } + this.InitializeFromMetadataList(albumMetadataList); + } + + private void InitializeFromMetadataList(List albumMetadataList) + { + this._source = AlbumMetadataPropertySource.Instance; + this.Initialize((IList)albumMetadataList, MetadataEditAlbum.s_properties); + foreach (AlbumMetadata albumMetadata in albumMetadataList) + { + for (uint index = 0; index < albumMetadata.TrackCount; ++index) + this._trackList.Add(new MetadataEditTrack(albumMetadata.GetTrack(index))); + foreach (PropertyDescriptor linkedProperty in this._linkedProperties) + { + this.GetProperty(linkedProperty).OriginalValue = this.GetPropertyStringFromTracks(linkedProperty); + this.GetProperty(linkedProperty).PropertyChanged += new PropertyChangedEventHandler(this.LinkedAlbumPropertyChanged); + foreach (MetadataEditMedia track in this._trackList) + track.GetProperty(linkedProperty).PropertyChanged += new PropertyChangedEventHandler(this.LinkedTrackPropertyChanged); + } + } + } + + public override void Commit() + { + foreach (MetadataEditMedia track in this._trackList) + track.Commit(); + base.Commit(); + } + + public override bool IsValid() + { + foreach (MetadataEditMedia track in this._trackList) + { + if (!track.IsValid()) + return false; + } + return base.IsValid(); + } + + public override bool IsModified() + { + foreach (MetadataEditMedia track in this._trackList) + { + if (track.IsModified()) + return true; + } + return base.IsModified(); + } + + private void LinkedTrackPropertyChanged(object sender, PropertyChangedEventArgs ebase) + { + MetadataPropertyChangedEventArgs changedEventArgs = ebase as MetadataPropertyChangedEventArgs; + PropertyDescriptor descriptor = ((MetadataEditProperty)sender).Descriptor; + if (!(changedEventArgs.PropertyName == "Value") || !this._linkedProperties.Contains(descriptor) || !changedEventArgs.Propagate) + return; + this.GetProperty(descriptor).SetValue(this.GetPropertyStringFromTracks(descriptor), false); + } + + private void LinkedAlbumPropertyChanged(object sender, PropertyChangedEventArgs ebase) + { + MetadataPropertyChangedEventArgs changedEventArgs = ebase as MetadataPropertyChangedEventArgs; + PropertyDescriptor descriptor = ((MetadataEditProperty)sender).Descriptor; + if (!(changedEventArgs.PropertyName == "Value") || !this._linkedProperties.Contains(descriptor) || !changedEventArgs.Propagate) + return; + foreach (MetadataEditMedia track in this._trackList) + track.GetProperty(descriptor).SetValue(this.GetProperty(descriptor).Value, false); + } + + private string GetPropertyStringFromTracks(PropertyDescriptor descriptor) + { + string oldString = descriptor.UnknownString; + foreach (MetadataEditMedia track in this._trackList) + { + string newString = track.GetProperty(descriptor).Value; + oldString = this.AggregateString(oldString, newString, descriptor); + } + return oldString; + } + + public IList GetTracks() => this.GetTracks(false); + + public IList GetTracks(bool filterAndSort) + { + if (!filterAndSort) + return (IList)this._trackList; + List metadataEditTrackList = new List(); + foreach (MetadataEditTrack track in this._trackList) + { + if (track.GetProperty((PropertyDescriptor)MetadataEditMedia.s_MediaId).Value != "-1") + metadataEditTrackList.Add(track); + } + metadataEditTrackList.Sort((IComparer)new TrackComparer()); + return (IList)metadataEditTrackList; + } + + public int GetFirstInvalidTrackIndex() + { + int num = 0; + foreach (MetadataEditMedia track in this._trackList) + { + if (!track.IsValid()) + return num; + ++num; + } + return -1; + } + } +} diff --git a/ZuneUI/MetadataEditMedia.cs b/ZuneUI/MetadataEditMedia.cs new file mode 100644 index 0000000..bc51515 --- /dev/null +++ b/ZuneUI/MetadataEditMedia.cs @@ -0,0 +1,215 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MetadataEditMedia +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class MetadataEditMedia + { + public static PropertyDescriptor s_TrackArtist = new PropertyDescriptor("ArtistName", Shell.LoadString(StringId.IDS_EMI_MULTIPLEARTISTS), ""); + public static PropertyDescriptor s_TrackArtistList = (PropertyDescriptor)new StringListPropertyDescriptor("ContributingArtistNames", Shell.LoadString(StringId.IDS_EMI_MULTIPLEARTISTS), ""); + public static NonBlankPropertyDescriptor s_Artist = new NonBlankPropertyDescriptor("ArtistName", Shell.LoadString(StringId.IDS_EMI_MULTIPLEARTISTS), ""); + public static PropertyDescriptor s_ArtistYomi = new PropertyDescriptor("ArtistNameYomi", "", ""); + public static NonBlankPropertyDescriptor s_Title = new NonBlankPropertyDescriptor("Title", Shell.LoadString(StringId.IDS_EMI_MULTIPLETITLES), ""); + public static PropertyDescriptor s_TitleYomi = new PropertyDescriptor("TitleYomi", "", ""); + public static IntYearPropertyDescriptor s_ReleaseYear = new IntYearPropertyDescriptor("ReleaseDate", Shell.LoadString(StringId.IDS_EMI_MULTIPLEYEARS), Shell.LoadString(StringId.IDS_UNKNOWN_YEAR), 4); + public static YearPropertyDescriptor s_TrackReleaseYear = new YearPropertyDescriptor("ReleaseDate", Shell.LoadString(StringId.IDS_EMI_MULTIPLEYEARS), Shell.LoadString(StringId.IDS_UNKNOWN_YEAR), 4); + public static DatePropertyDescriptor s_ReleaseDate = new DatePropertyDescriptor("ReleaseDate", Shell.LoadString(StringId.IDS_EMI_MULTIPLEDATES), Shell.LoadString(StringId.IDS_RELEASE_DATE_UNKNOWN), DateTimeKind.Utc); + public static IntPropertyDescriptor s_DiscNumber = new IntPropertyDescriptor("DiscNumber", Shell.LoadString(StringId.IDS_EMI_MULTIPLEDISCS), "", 3); + public static IntPropertyDescriptor s_TrackNumber = new IntPropertyDescriptor("TrackNumber", "0", "", 3); + public static PropertyDescriptor s_SeriesTitle = new PropertyDescriptor("SeriesTitle", Shell.LoadString(StringId.IDS_EMI_MULTIPLETITLES), ""); + public static IntPropertyDescriptor s_SeasonNumber = new IntPropertyDescriptor("SeasonNumber", "", "", 6); + public static IntPropertyDescriptor s_EpisodeNumber = new IntPropertyDescriptor("EpisodeNumber", "", "", 6); + public static NonBlankPropertyDescriptor s_AlbumTitle = new NonBlankPropertyDescriptor("AlbumName", Shell.LoadString(StringId.IDS_EMI_MULTIPLETITLES), ""); + public static PropertyDescriptor s_AlbumTitleYomi = new PropertyDescriptor("AlbumTitleYomi", "", ""); + public static NonBlankPropertyDescriptor s_AlbumArtist = new NonBlankPropertyDescriptor("AlbumArtistName", Shell.LoadString(StringId.IDS_EMI_MULTIPLEARTISTS), ""); + public static PropertyDescriptor s_AlbumArtistYomi = new PropertyDescriptor("AlbumArtistYomi", "", ""); + public static PropertyDescriptor s_Composer = new PropertyDescriptor("ComposerName", Shell.LoadString(StringId.IDS_EMI_MULTIPLECOMPOSERS), ""); + public static PropertyDescriptor s_Conductor = new PropertyDescriptor("ConductorName", Shell.LoadString(StringId.IDS_EMI_MULTIPLECONDUCTORS), ""); + public static PropertyDescriptor s_Genre = new PropertyDescriptor("Genre", Shell.LoadString(StringId.IDS_EMI_MULTIPLEGENRES), Shell.LoadString(StringId.IDS_GENRE_UNKNOWN)); + public static TypePropertyDescriptor s_Category = new TypePropertyDescriptor("CategoryId", "", ""); + public static PropertyDescriptor s_Description = new PropertyDescriptor("Description", Shell.LoadString(StringId.IDS_EMI_MULTIPLEDESCRIPTIONS), ""); + public static PropertyDescriptor s_CoverUrl = new PropertyDescriptor("CoverUrl", "", ""); + public static IntPropertyDescriptor s_TrackCount = new IntPropertyDescriptor("TrackCount", "0", ""); + public static IntPropertyDescriptor s_MediaId = new IntPropertyDescriptor("MediaId", "-1", "-1"); + private IList _properties; + private IList _mediaList; + private Dictionary _propertyMap = new Dictionary(); + protected PropertySource _source = DataProviderObjectPropertySource.Instance; + protected bool _creationFailed; + + protected void Initialize(IList mediaList, PropertyDescriptor[] properties) + { + this._mediaList = mediaList; + this._properties = (IList)properties; + foreach (PropertyDescriptor property in (IEnumerable)this._properties) + this._propertyMap[property] = this.CreatePropertyFromMedia(this._mediaList, property); + } + + public MetadataEditProperty GetProperty(PropertyDescriptor descriptor) => this._propertyMap[descriptor]; + + public MetadataEditProperty GetProperty(string descriptorName) + { + MetadataEditProperty metadataEditProperty1 = (MetadataEditProperty)null; + foreach (MetadataEditProperty metadataEditProperty2 in this._propertyMap.Values) + { + if (metadataEditProperty2.Descriptor.DescriptorName.Equals(descriptorName, StringComparison.InvariantCultureIgnoreCase)) + { + metadataEditProperty1 = metadataEditProperty2; + break; + } + } + return metadataEditProperty1; + } + + public object GetPropertyData(PropertyDescriptor descriptor) + { + object obj = (object)null; + MetadataEditProperty property = this.GetProperty(descriptor); + if (property != null) + obj = property.ConvertToData(); + return obj; + } + + public void SetPropertyData(PropertyDescriptor descriptor, object value) => this.GetProperty(descriptor)?.ConvertFromData(value); + + public void SetPropertyState(PropertyDescriptor descriptor, object state) + { + MetadataEditProperty property = this.GetProperty(descriptor); + if (property == null) + return; + property.State = state; + } + + public void ResetExternalErrors() + { + foreach (MetadataEditProperty metadataEditProperty in this._propertyMap.Values) + metadataEditProperty.ExternalError = HRESULT._S_OK; + } + + public virtual void Commit() + { + foreach (PropertyDescriptor property1 in (IEnumerable)this._properties) + { + MetadataEditProperty property2 = this._propertyMap[property1]; + if (property2.Modified) + this.SetPropertyToMedia(property2); + } + if (!this._source.NeedsCommit) + return; + foreach (object media in (IEnumerable)this._mediaList) + this._source.Commit(media); + } + + public virtual bool IsValid() + { + foreach (MetadataEditProperty metadataEditProperty in this._propertyMap.Values) + { + if ((metadataEditProperty.Modified || metadataEditProperty.Required) && !metadataEditProperty.Valid) + return false; + } + return true; + } + + public virtual bool IsModified() + { + foreach (MetadataEditProperty metadataEditProperty in this._propertyMap.Values) + { + if (metadataEditProperty.Modified) + return true; + } + return false; + } + + public bool CreationFailed => this._creationFailed; + + private MetadataEditProperty CreatePropertyFromMedia( + IList mediaList, + PropertyDescriptor descriptor) + { + string str = descriptor.UnknownString; + foreach (object media in (IEnumerable)this._mediaList) + { + object obj = this._source.Get(media, descriptor); + string newString = descriptor.ConvertToString(obj) ?? descriptor.UnknownString; + str = this.AggregateString(str, newString, descriptor); + } + return new MetadataEditProperty(descriptor, str); + } + + private void SetPropertyToMedia(MetadataEditProperty property) + { + foreach (object media in (IEnumerable)this._mediaList) + this._source.Set(media, property.Descriptor, property.Descriptor.ConvertFromString(property.Value, property.State)); + } + + protected string AggregateString( + string oldString, + string newString, + PropertyDescriptor descriptor) + { + string str = oldString; + if (str != newString) + str = !(str == descriptor.UnknownString) ? descriptor.MultiValueString : newString; + return str; + } + + public static PropertyDescriptor TrackArtistDescriptor => MetadataEditMedia.s_TrackArtist; + + public static PropertyDescriptor TrackArtistListDescriptor => MetadataEditMedia.s_TrackArtistList; + + public static PropertyDescriptor ArtistDescriptor => (PropertyDescriptor)MetadataEditMedia.s_Artist; + + public static PropertyDescriptor ArtistYomiDescriptor => MetadataEditMedia.s_ArtistYomi; + + public static PropertyDescriptor TitleDescriptor => (PropertyDescriptor)MetadataEditMedia.s_Title; + + public static PropertyDescriptor TitleYomiDescriptor => MetadataEditMedia.s_TitleYomi; + + public static PropertyDescriptor ReleaseYearDescriptor => (PropertyDescriptor)MetadataEditMedia.s_ReleaseYear; + + public static PropertyDescriptor TrackReleaseYearDescriptor => (PropertyDescriptor)MetadataEditMedia.s_TrackReleaseYear; + + public static PropertyDescriptor DiscNumberDescriptor => (PropertyDescriptor)MetadataEditMedia.s_DiscNumber; + + public static PropertyDescriptor TrackNumberDescriptor => (PropertyDescriptor)MetadataEditMedia.s_TrackNumber; + + public static PropertyDescriptor SeriesTitleDescriptor => MetadataEditMedia.s_SeriesTitle; + + public static PropertyDescriptor SeasonNumberDescriptor => (PropertyDescriptor)MetadataEditMedia.s_SeasonNumber; + + public static PropertyDescriptor EpisodeNumberDescriptor => (PropertyDescriptor)MetadataEditMedia.s_EpisodeNumber; + + public static PropertyDescriptor AlbumTitleDescriptor => (PropertyDescriptor)MetadataEditMedia.s_AlbumTitle; + + public static PropertyDescriptor AlbumTitleYomiDescriptor => MetadataEditMedia.s_AlbumTitleYomi; + + public static PropertyDescriptor AlbumArtistDescriptor => (PropertyDescriptor)MetadataEditMedia.s_AlbumArtist; + + public static PropertyDescriptor AlbumArtistYomiDescriptor => MetadataEditMedia.s_AlbumArtistYomi; + + public static PropertyDescriptor ComposerDescriptor => MetadataEditMedia.s_Composer; + + public static PropertyDescriptor ConductorDescriptor => MetadataEditMedia.s_Conductor; + + public static PropertyDescriptor GenreDescriptor => MetadataEditMedia.s_Genre; + + public static PropertyDescriptor CategoryDescriptor => (PropertyDescriptor)MetadataEditMedia.s_Category; + + public static PropertyDescriptor ReleaseDateDescriptor => (PropertyDescriptor)MetadataEditMedia.s_ReleaseDate; + + public static PropertyDescriptor DescriptionDescriptor => MetadataEditMedia.s_Description; + + public static PropertyDescriptor CoverUrlDescriptor => MetadataEditMedia.s_CoverUrl; + + public static PropertyDescriptor TrackCountDescriptor => (PropertyDescriptor)MetadataEditMedia.s_TrackCount; + + public static PropertyDescriptor MediaIdDescriptor => (PropertyDescriptor)MetadataEditMedia.s_MediaId; + } +} diff --git a/ZuneUI/MetadataEditProperty.cs b/ZuneUI/MetadataEditProperty.cs new file mode 100644 index 0000000..50a1126 --- /dev/null +++ b/ZuneUI/MetadataEditProperty.cs @@ -0,0 +1,155 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MetadataEditProperty +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.ErrorMapperApi; + +namespace ZuneUI +{ + public class MetadataEditProperty : INotifyPropertyChangedImpl + { + private PropertyDescriptor _descriptor; + private string _originalValue; + private string _currentValue; + private bool _modified; + private bool _valid = true; + private object _state; + private HRESULT _externalError = HRESULT._S_OK; + + internal MetadataEditProperty(PropertyDescriptor descriptor, string originalValue) + { + this._descriptor = descriptor; + this._originalValue = originalValue; + this._currentValue = originalValue; + this.UpdateValidAndModified(); + } + + internal void SetValue(string value, bool propagate) + { + if (!(this._currentValue != value)) + return; + this._currentValue = value; + this.NotifyPropertyChanged("Value", propagate); + this.UpdateValidAndModified(); + } + + public string OriginalValue + { + get => this._originalValue; + set + { + if (this._originalValue != value) + { + this._originalValue = value; + this.NotifyPropertyChanged(nameof(OriginalValue), true); + } + this.Value = this._originalValue; + } + } + + public string Value + { + get => this._currentValue; + set => this.SetValue(value, true); + } + + public bool Valid + { + get => this._valid; + internal set + { + if (this._valid == value) + return; + this._valid = value; + this.NotifyPropertyChanged(nameof(Valid), true); + this.NotifyPropertyChanged("ErrorMessage", true); + } + } + + public bool Required => this._descriptor.IsRequired(this._state); + + public bool Modified + { + get => this._modified; + internal set + { + if (this._modified == value) + return; + this._modified = value; + this.NotifyPropertyChanged(nameof(Modified), true); + } + } + + public PropertyDescriptor Descriptor => this._descriptor; + + public HRESULT ExternalError + { + get => this._externalError; + set + { + if (this._externalError.Int == value.Int) + return; + this._externalError = value; + this.NotifyPropertyChanged(nameof(ExternalError), true); + this.UpdateValid(); + } + } + + public string ErrorMessage + { + get + { + string str = (string)null; + if (this._externalError.IsError) + { + ErrorMapperResult descriptionAndUrl = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(this._externalError.Int); + if (descriptionAndUrl != null) + str = descriptionAndUrl.Description; + } + else if (!this.Valid) + str = this._descriptor.DefaultError; + return str; + } + } + + public object State + { + get => this._state; + set + { + if (this._state == value) + return; + this._state = value; + this.NotifyPropertyChanged(nameof(State), true); + this.OnStateChanged(); + } + } + + public string OverlayContent => this._descriptor.GetOverlayString(this._state); + + public string LabelContent => this._descriptor.GetLabelString(this._state); + + public object ConvertToData() => this._descriptor.ConvertFromString(this._currentValue, this._state); + + public void ConvertFromData(object data) => this.OriginalValue = this._descriptor.ConvertToString(data, this._state); + + private void OnStateChanged() + { + this.UpdateValid(); + this.NotifyPropertyChanged("OverlayContent", true); + this.NotifyPropertyChanged("LabelContent", true); + } + + private void UpdateValidAndModified() + { + this.Modified = this._currentValue != this._originalValue; + if (this.Modified && this._externalError.IsError) + this._externalError = HRESULT._S_OK; + this.UpdateValid(); + } + + private void UpdateValid() => this.Valid = this._descriptor.IsValid(this._currentValue, this._state) && this._externalError.IsSuccess; + } +} diff --git a/ZuneUI/MetadataEditTrack.cs b/ZuneUI/MetadataEditTrack.cs new file mode 100644 index 0000000..06dee91 --- /dev/null +++ b/ZuneUI/MetadataEditTrack.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MetadataEditTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; +using System.Collections; + +namespace ZuneUI +{ + public class MetadataEditTrack : MetadataEditMedia + { + private static PropertyDescriptor[] s_dataProviderProperties = new PropertyDescriptor[14] + { + (PropertyDescriptor) MetadataEditMedia.s_Title, + MetadataEditMedia.s_TrackArtist, + MetadataEditMedia.s_TrackArtistList, + MetadataEditMedia.s_Genre, + MetadataEditMedia.s_Conductor, + MetadataEditMedia.s_Composer, + (PropertyDescriptor) MetadataEditMedia.s_TrackReleaseYear, + (PropertyDescriptor) MetadataEditMedia.s_AlbumTitle, + (PropertyDescriptor) MetadataEditMedia.s_AlbumArtist, + (PropertyDescriptor) MetadataEditMedia.s_TrackNumber, + (PropertyDescriptor) MetadataEditMedia.s_DiscNumber, + (PropertyDescriptor) MetadataEditMedia.s_MediaId, + MetadataEditMedia.s_TitleYomi, + MetadataEditMedia.s_ArtistYomi + }; + private static PropertyDescriptor[] s_trackMetadataProperties = new PropertyDescriptor[14] + { + (PropertyDescriptor) MetadataEditMedia.s_Title, + MetadataEditMedia.s_TrackArtist, + MetadataEditMedia.s_TrackArtistList, + MetadataEditMedia.s_Genre, + MetadataEditMedia.s_Conductor, + MetadataEditMedia.s_Composer, + (PropertyDescriptor) MetadataEditMedia.s_ReleaseYear, + (PropertyDescriptor) MetadataEditMedia.s_AlbumTitle, + (PropertyDescriptor) MetadataEditMedia.s_AlbumArtist, + (PropertyDescriptor) MetadataEditMedia.s_TrackNumber, + (PropertyDescriptor) MetadataEditMedia.s_DiscNumber, + (PropertyDescriptor) MetadataEditMedia.s_MediaId, + MetadataEditMedia.s_TitleYomi, + MetadataEditMedia.s_ArtistYomi + }; + + public MetadataEditTrack(TrackMetadata trackMetadata) + { + this._source = TrackMetadataPropertySource.Instance; + this.Initialize((IList)new object[1] + { + (object) trackMetadata + }, MetadataEditTrack.s_trackMetadataProperties); + } + + public MetadataEditTrack(IList trackList) => this.Initialize(trackList, MetadataEditTrack.s_dataProviderProperties); + } +} diff --git a/ZuneUI/MetadataEditVideo.cs b/ZuneUI/MetadataEditVideo.cs new file mode 100644 index 0000000..5b54aa0 --- /dev/null +++ b/ZuneUI/MetadataEditVideo.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MetadataEditVideo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class MetadataEditVideo : MetadataEditMedia + { + private static PropertyDescriptor[] s_properties = new PropertyDescriptor[12] + { + (PropertyDescriptor) MetadataEditMedia.s_Title, + MetadataEditMedia.s_TitleYomi, + (PropertyDescriptor) MetadataEditMedia.s_Artist, + MetadataEditMedia.s_Genre, + MetadataEditMedia.s_Conductor, + MetadataEditMedia.s_Composer, + (PropertyDescriptor) MetadataEditMedia.s_Category, + MetadataEditMedia.s_SeriesTitle, + (PropertyDescriptor) MetadataEditMedia.s_SeasonNumber, + (PropertyDescriptor) MetadataEditMedia.s_EpisodeNumber, + (PropertyDescriptor) MetadataEditMedia.s_ReleaseDate, + MetadataEditMedia.s_Description + }; + + public MetadataEditVideo(IList videoList) => this.Initialize(videoList, MetadataEditVideo.s_properties); + } +} diff --git a/ZuneUI/MetadataNotifications.cs b/ZuneUI/MetadataNotifications.cs new file mode 100644 index 0000000..b0f0b88 --- /dev/null +++ b/ZuneUI/MetadataNotifications.cs @@ -0,0 +1,193 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MetadataNotifications +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; +using System.Runtime.InteropServices; + +namespace ZuneUI +{ + public class MetadataNotifications : ModelItem + { + private static MetadataNotifications _singletonInstance; + private MetadataMgrNotifications _metadataMgr; + private MessageNotification _libraryNotification; + private MessageNotification _updateMetadataNotification; + private bool _updatingMetadata; + private Timer _timerOnEndUpdates; + private object _lock = new object(); + private bool _deferredUpdatePending; + private int _addCount; + private static string _libraryActiveImportMessage = Shell.LoadString(StringId.IDS_LIBRARY_IMPORTING_MEDIA); + private static string _libraryAddFileMessage = Shell.LoadString(StringId.IDS_LIBRARY_ADD_FILE); + private static string _libraryScanCompleteMessage = Shell.LoadString(StringId.IDS_LIBRARY_SCAN_COMPLETE); + private static string _metadataUpdateMessage = Shell.LoadString(StringId.IDS_LIBRARY_METADATA_UPDATE); + private static string _metadataUpdateInfoMessage = Shell.LoadString(StringId.IDS_LIBRARY_METADATA_UPDATE_INFO); + private static string _libraryFileChangeCompleteMessage = Shell.LoadString(StringId.IDS_LIBRARY_FILE_CHANGE_COMPLETE); + private static string _libraryFileDeleteFailedMessage = Shell.LoadString(StringId.IDS_LIBRARY_FILE_DELETE_FAILED); + + private MetadataNotifications(IModelItemOwner owner) + : base(owner) + { + this._timerOnEndUpdates = new Timer(); + this._timerOnEndUpdates.Interval = 15000; + this._timerOnEndUpdates.AutoRepeat = false; + this._timerOnEndUpdates.Tick += new EventHandler(this.OnEndUpdatesTick); + } + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + if (!fDisposing) + return; + if (this._metadataMgr != null) + { + this._metadataMgr.FileAdded -= new OnFileAddedHandler(this.OnFileAdded); + this._metadataMgr.Dispose(); + this._metadataMgr = (MetadataMgrNotifications)null; + } + if (this._timerOnEndUpdates == null) + return; + this._timerOnEndUpdates.Tick -= new EventHandler(this.OnEndUpdatesTick); + this._timerOnEndUpdates.Dispose(); + this._timerOnEndUpdates = (Timer)null; + } + + public static MetadataNotifications Instance + { + get + { + if (MetadataNotifications._singletonInstance == null) + MetadataNotifications._singletonInstance = new MetadataNotifications((IModelItemOwner)ZuneShell.DefaultInstance); + return MetadataNotifications._singletonInstance; + } + } + + public bool Importing => this._libraryNotification != null; + + public void Phase2Init() + { + this._metadataMgr = new MetadataMgrNotifications(); + if (this._metadataMgr == null) + return; + this._metadataMgr.FileAdded += new OnFileAddedHandler(this.OnFileAdded); + } + + private void OnFileAdded(IntPtr pszPath, EMediaTypes MediaType) => this.NotifyFileAddedStatus(); + + private void NotifyFileAddedStatus() + { + bool flag = false; + int milliseconds = 250; + lock (this._lock) + { + if (this._addCount == 0) + milliseconds = 0; + ++this._addCount; + if (!this._deferredUpdatePending) + { + this._deferredUpdatePending = true; + flag = true; + } + } + if (!flag) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredFileAddedStatus), (object)null, new TimeSpan(0, 0, 0, 0, milliseconds)); + } + + private void DeferredFileAddedStatus(object obj) + { + if (this.IsDisposed) + return; + int addCount; + lock (this._lock) + { + this._deferredUpdatePending = false; + addCount = this._addCount; + } + this._timerOnEndUpdates.Stop(); + this._timerOnEndUpdates.Start(); + if (Download.Instance.Notification != null) + return; + if (this._libraryNotification == null) + { + this._libraryNotification = new MessageNotification(MetadataNotifications._libraryActiveImportMessage, NotificationTask.Library, NotificationState.Normal); + NotificationArea.Instance.RemoveAll(NotificationTask.Library, NotificationState.Completed); + NotificationArea.Instance.Add((Notification)this._libraryNotification); + this.FirePropertyChanged("Importing"); + } + this._libraryNotification.SubMessage = string.Format(MetadataNotifications._libraryAddFileMessage, (object)addCount); + } + + private void OnEndUpdatesTick(object sender, EventArgs args) + { + int addCount; + lock (this._lock) + { + addCount = this._addCount; + this._addCount = 0; + } + NotificationArea.Instance.Replace((Notification)this._libraryNotification, (Notification)new MessageNotification(MetadataNotifications._libraryFileChangeCompleteMessage, string.Format(MetadataNotifications._libraryAddFileMessage, (object)addCount), NotificationTask.Library, NotificationState.Completed)); + this._libraryNotification = (MessageNotification)null; + this.FirePropertyChanged("Importing"); + } + + private void OnBeginMetadataLifecycle() => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this._updatingMetadata = true; + }, (object)null); + + private void OnEndMetadataLifecycle() => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + if (this._updateMetadataNotification != null && this._updateMetadataNotification.Type != NotificationState.Completed) + { + NotificationArea.Instance.Replace((Notification)this._updateMetadataNotification, (Notification)new MessageNotification("Metadata update completed", NotificationTask.Library, NotificationState.Completed)); + this._updateMetadataNotification = (MessageNotification)null; + } + this._updatingMetadata = false; + }, (object)null); + + private void OnMetadataUpdate(IntPtr artistPtr, IntPtr albumPtr) + { + string artist = Marshal.PtrToStringUni(artistPtr); + string album = Marshal.PtrToStringUni(albumPtr); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed || !this._updatingMetadata) + return; + if (this._updateMetadataNotification == null) + { + this._updateMetadataNotification = new MessageNotification(MetadataNotifications._metadataUpdateMessage, NotificationTask.Library, NotificationState.Normal); + NotificationArea.Instance.RemoveAll(NotificationTask.Library, NotificationState.Completed); + NotificationArea.Instance.Add((Notification)this._updateMetadataNotification); + } + this._updateMetadataNotification.SubMessage = string.Format(MetadataNotifications._metadataUpdateInfoMessage, (object)artist, (object)album); + }, (object)null); + } + + private void OnFileDeleteFailed(IntPtr fileUrlPtr) + { + string strFileUrl = Marshal.PtrToStringUni(fileUrlPtr); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed || !this._updatingMetadata) + return; + if (this._updateMetadataNotification == null) + { + this._updateMetadataNotification = new MessageNotification(MetadataNotifications._metadataUpdateMessage, NotificationTask.Library, NotificationState.Normal); + NotificationArea.Instance.RemoveAll(NotificationTask.Library, NotificationState.Completed); + NotificationArea.Instance.Add((Notification)this._updateMetadataNotification); + } + this._updateMetadataNotification.SubMessage = string.Format(MetadataNotifications._libraryFileDeleteFailedMessage, (object)strFileUrl); + }, (object)null); + } + } +} diff --git a/ZuneUI/MetadataPropertyChangedEventArgs.cs b/ZuneUI/MetadataPropertyChangedEventArgs.cs new file mode 100644 index 0000000..d2be183 --- /dev/null +++ b/ZuneUI/MetadataPropertyChangedEventArgs.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MetadataPropertyChangedEventArgs +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.ComponentModel; + +namespace ZuneUI +{ + public class MetadataPropertyChangedEventArgs : PropertyChangedEventArgs + { + public bool Propagate; + + public MetadataPropertyChangedEventArgs(string propertyName, bool propagate) + : base(propertyName) + => this.Propagate = propagate; + } +} diff --git a/ZuneUI/MixAlbumPriorityList.cs b/ZuneUI/MixAlbumPriorityList.cs new file mode 100644 index 0000000..ced59ac --- /dev/null +++ b/ZuneUI/MixAlbumPriorityList.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixAlbumPriorityList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class MixAlbumPriorityList : MixPriorityList + { + public MixAlbumPriorityList(MixResult mixResultSeed) + : base(mixResultSeed) + { + } + + public override void AddList(IList sourceList, string reason, int maxItems) => this.AddList(sourceList, reason, maxItems, new MixPriorityList.GetItemPriorityDelegate(MixResultAlbum.GetItemPriority), new MixPriorityList.CreateItemInstanceDelegate(MixResultAlbum.CreateInstance)); + } +} diff --git a/ZuneUI/MixArtistPriorityList.cs b/ZuneUI/MixArtistPriorityList.cs new file mode 100644 index 0000000..95e785b --- /dev/null +++ b/ZuneUI/MixArtistPriorityList.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixArtistPriorityList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class MixArtistPriorityList : MixPriorityList + { + public MixArtistPriorityList(MixResult mixResultSeed) + : base(mixResultSeed) + { + } + + public override void AddList(IList sourceList, string reason, int maxItems) => this.AddList(sourceList, reason, maxItems, new MixPriorityList.GetItemPriorityDelegate(MixResultArtist.GetItemPriority), new MixPriorityList.CreateItemInstanceDelegate(MixResultArtist.CreateInstance)); + } +} diff --git a/ZuneUI/MixHelper.cs b/ZuneUI/MixHelper.cs new file mode 100644 index 0000000..135162a --- /dev/null +++ b/ZuneUI/MixHelper.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class MixHelper + { + public static bool MixAvailable => InternetConnection.Instance.IsConnected && FeatureEnablement.IsFeatureEnabled(Features.eMixview); + } +} diff --git a/ZuneUI/MixPriorityList.cs b/ZuneUI/MixPriorityList.cs new file mode 100644 index 0000000..7878105 --- /dev/null +++ b/ZuneUI/MixPriorityList.cs @@ -0,0 +1,110 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixPriorityList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneUI +{ + public abstract class MixPriorityList + { + private MixResult _mixResultSeed; + private System.Collections.Generic.List _list; + private System.Collections.Generic.List _sortedList; + + protected MixPriorityList(MixResult mixResultSeed) + { + this._list = new System.Collections.Generic.List(); + this._mixResultSeed = mixResultSeed; + } + + public void Add(DataProviderObject item, string reason) => this.AddList((IList)new System.Collections.Generic.List() + { + item + }, reason, 1); + + public abstract void AddList(IList sourceList, string reason, int maxItems); + + public IList List + { + get + { + if (this._sortedList == null) + { + this._sortedList = new System.Collections.Generic.List(this._list.Count); + this._list.Sort(); + foreach (MixPriorityList.PriorityResult priorityResult in this._list) + this._sortedList.Add(priorityResult.Result); + } + return (IList)this._sortedList; + } + } + + protected void AddList( + IList sourceList, + string reason, + int maxItems, + MixPriorityList.GetItemPriorityDelegate getItemPriorityDelegate, + MixPriorityList.CreateItemInstanceDelegate createItemInstanceDelegate) + { + int startPriority = 0; + foreach (DataProviderObject source in (IEnumerable)sourceList) + { + if (this.Add(createItemInstanceDelegate(source, reason), getItemPriorityDelegate(source, startPriority))) + ++startPriority; + if (startPriority >= maxItems) + break; + } + } + + protected bool Add(MixResult newResult, int priority) + { + bool flag = false; + if (newResult.IsDuplicate(this._mixResultSeed)) + flag = true; + if (!flag && newResult.ResultType == MixResultType.Profile) + flag = SignIn.Instance.IsSignedInUser(newResult.Id); + if (!flag) + { + foreach (MixPriorityList.PriorityResult priorityResult in this._list) + { + if (newResult.IsDuplicate(priorityResult.Result)) + { + flag = true; + break; + } + } + } + if (!flag) + { + this._list.Add(new MixPriorityList.PriorityResult(priority, newResult)); + this._sortedList = (System.Collections.Generic.List)null; + } + return !flag; + } + + protected class PriorityResult : IComparable + { + public int Priority; + public MixResult Result; + + public PriorityResult(int priority, MixResult result) + { + this.Priority = priority; + this.Result = result; + } + + public int CompareTo(object obj) => this.Priority - (obj as MixPriorityList.PriorityResult).Priority; + } + + protected delegate int GetItemPriorityDelegate(DataProviderObject item, int startPriority); + + protected delegate MixResult CreateItemInstanceDelegate( + DataProviderObject item, + string reason); + } +} diff --git a/ZuneUI/MixProfilePriorityList.cs b/ZuneUI/MixProfilePriorityList.cs new file mode 100644 index 0000000..8765922 --- /dev/null +++ b/ZuneUI/MixProfilePriorityList.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixProfilePriorityList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class MixProfilePriorityList : MixPriorityList + { + public MixProfilePriorityList(MixResult mixResultSeed) + : base(mixResultSeed) + { + } + + public override void AddList(IList sourceList, string reason, int maxItems) => this.AddList(sourceList, reason, maxItems, new MixPriorityList.GetItemPriorityDelegate(MixResultProfile.GetItemPriority), new MixPriorityList.CreateItemInstanceDelegate(MixResultProfile.CreateInstance)); + } +} diff --git a/ZuneUI/MixResult.cs b/ZuneUI/MixResult.cs new file mode 100644 index 0000000..f9238e2 --- /dev/null +++ b/ZuneUI/MixResult.cs @@ -0,0 +1,117 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixResult +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public class MixResult : INotifyPropertyChanged + { + private MixResultType _resultType; + private string _reason; + private string _primaryText; + private string _secondaryText; + private string _id; + private Guid _imageId; + private IList _tracks; + private DataProviderQueryStatus _tracksQueryStatus; + private string _imageUri; + private DataProviderObject _baseObject; + + protected MixResult() + { + } + + protected void Initialize( + MixResultType resultType, + string reason, + string primaryText, + string secondaryText, + string id, + string imageUri, + Guid imageId, + DataProviderObject baseObject) + { + this._resultType = resultType; + this._reason = reason; + this._primaryText = primaryText; + this._secondaryText = secondaryText; + this._id = id; + this._imageId = imageId; + this._imageUri = imageUri; + this._baseObject = baseObject; + } + + public static MixResult CreateInstance( + MixResultType resultType, + string reason, + string primaryText, + string secondaryText, + string id, + string imageUri, + Guid imageId, + DataProviderObject baseObject) + { + MixResult mixResult = new MixResult(); + mixResult.Initialize(resultType, reason, primaryText, secondaryText, id, imageUri, imageId, baseObject); + return mixResult; + } + + public string Reason => this._reason; + + public string PrimaryText => this._primaryText; + + public string SecondaryText => this._secondaryText; + + public string Id => this._id; + + public MixResultType ResultType => this._resultType; + + public Guid ImageId => this._imageId; + + public string ImageUri => this._imageUri; + + public DataProviderObject BaseObject => this._baseObject; + + internal virtual bool IsDuplicate(MixResult compareTo) => this.ResultType == compareTo.ResultType && this.Id == compareTo.Id; + + public IList Tracks + { + get => this._tracks; + set + { + if (value == this._tracks) + return; + this._tracks = value; + this.NotifyPropertyChanged(nameof(Tracks)); + } + } + + public DataProviderQueryStatus TracksQueryStatus + { + get => this._tracksQueryStatus; + set + { + if (value == this._tracksQueryStatus) + return; + this._tracksQueryStatus = value; + this.NotifyPropertyChanged(nameof(TracksQueryStatus)); + } + } + + protected void NotifyPropertyChanged(string propertyName) + { + if (this.PropertyChanged == null) + return; + this.PropertyChanged((object)this, new PropertyChangedEventArgs(propertyName)); + } + + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/ZuneUI/MixResultAlbum.cs b/ZuneUI/MixResultAlbum.cs new file mode 100644 index 0000000..b8bb1da --- /dev/null +++ b/ZuneUI/MixResultAlbum.cs @@ -0,0 +1,65 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixResultAlbum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using ZuneXml; + +namespace ZuneUI +{ + public class MixResultAlbum : MixResult + { + protected MixResultAlbum() + { + } + + public static MixResultAlbum CreateInstance( + DataProviderObject dataProviderObject, + string reason) + { + MixResultAlbum mixResultAlbum = new MixResultAlbum(); + Album album = (Album)dataProviderObject; + MiniArtist primaryArtist = album.PrimaryArtist; + string secondaryText = primaryArtist != null ? primaryArtist.Title : string.Empty; + mixResultAlbum.Initialize(MixResultType.Album, reason, album.Title ?? string.Empty, secondaryText, album.Id.ToString(), string.Empty, album.ImageId, (DataProviderObject)null); + return mixResultAlbum; + } + + public static MixResultAlbum CreateInstance(LibraryAlbumInfo libraryAlbumInfo) + { + MixResultAlbum mixResultAlbum = new MixResultAlbum(); + mixResultAlbum.Initialize(MixResultType.Album, string.Empty, libraryAlbumInfo.AlbumTitle, libraryAlbumInfo.ArtistName, libraryAlbumInfo.ZuneMediaId.ToString(), libraryAlbumInfo.AlbumArtUrl, Guid.Empty, (DataProviderObject)null); + return mixResultAlbum; + } + + internal static int GetItemPriority(DataProviderObject item, int startPriority) + { + int num = startPriority; + Album album = (Album)item; + if (!album.Actionable) + num += MixResultAlbum.NonActionablePriorityBump; + if ((album.Title ?? string.Empty).ToLowerInvariant().Contains("karaoke")) + num += MixResultAlbum.KaraokePriorityBump; + return num; + } + + internal override bool IsDuplicate(MixResult compareTo) => base.IsDuplicate(compareTo) || string.Compare(this.SecondaryText, compareTo.SecondaryText, StringComparison.InvariantCultureIgnoreCase) == 0 && string.Compare(MixResultAlbum.GetComparableAlbumName(this.PrimaryText), MixResultAlbum.GetComparableAlbumName(compareTo.PrimaryText), StringComparison.InvariantCultureIgnoreCase) == 0; + + public static string GetComparableAlbumName(string albumName) + { + string str = albumName.Trim(); + int length = str.IndexOf('('); + if (length > 3) + str = str.Substring(0, length).Trim(); + str.ToLowerInvariant(); + return str; + } + + public static int KaraokePriorityBump => 100; + + public static int NonActionablePriorityBump => 200; + } +} diff --git a/ZuneUI/MixResultArtist.cs b/ZuneUI/MixResultArtist.cs new file mode 100644 index 0000000..35b73da --- /dev/null +++ b/ZuneUI/MixResultArtist.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixResultArtist +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using ZuneXml; + +namespace ZuneUI +{ + public class MixResultArtist : MixResult + { + protected MixResultArtist() + { + } + + public static MixResultArtist CreateInstance( + DataProviderObject dataProviderObject, + string reason) + { + MixResultArtist mixResultArtist = new MixResultArtist(); + if (dataProviderObject.TypeName == "ArtistData") + dataProviderObject = (DataProviderObject)dataProviderObject.GetProperty("Item"); + Artist artist = (Artist)dataProviderObject; + mixResultArtist.Initialize(MixResultType.Artist, reason, artist.Title ?? string.Empty, string.Empty, artist.Id.ToString(), string.Empty, artist.ImageId, (DataProviderObject)null); + return mixResultArtist; + } + + internal static int GetItemPriority(DataProviderObject item, int startPriority) => startPriority; + } +} diff --git a/ZuneUI/MixResultProfile.cs b/ZuneUI/MixResultProfile.cs new file mode 100644 index 0000000..1d3a21d --- /dev/null +++ b/ZuneUI/MixResultProfile.cs @@ -0,0 +1,30 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixResultProfile +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class MixResultProfile : MixResult + { + protected MixResultProfile() + { + } + + public static MixResultProfile CreateInstance( + DataProviderObject dataProviderObject, + string reason) + { + MixResultProfile mixResultProfile = new MixResultProfile(); + Guid? property = (Guid?)dataProviderObject.GetProperty("UserGuid"); + mixResultProfile.Initialize(MixResultType.Profile, reason, (string)(dataProviderObject.GetProperty("ZuneTag") ?? (object)""), "", property.HasValue ? property.Value.ToString() : "", (string)(dataProviderObject.GetProperty("TileUrl") ?? (object)""), Guid.Empty, dataProviderObject); + return mixResultProfile; + } + + internal static int GetItemPriority(DataProviderObject item, int startPriority) => startPriority; + } +} diff --git a/ZuneUI/MixResultType.cs b/ZuneUI/MixResultType.cs new file mode 100644 index 0000000..b474de5 --- /dev/null +++ b/ZuneUI/MixResultType.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixResultType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum MixResultType + { + Album, + Artist, + Profile, + } +} diff --git a/ZuneUI/MixStack.cs b/ZuneUI/MixStack.cs new file mode 100644 index 0000000..3d40788 --- /dev/null +++ b/ZuneUI/MixStack.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixStack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class MixStack : Stack + { + public void Push(MixResult seedResult, object layout, IList dataList) => this.Push(new MixStackEntry(seedResult, layout, dataList)); + + public static bool IsNullOrEmpty(MixStack mixStack) => mixStack == null || mixStack.Count == 0; + } +} diff --git a/ZuneUI/MixStackEntry.cs b/ZuneUI/MixStackEntry.cs new file mode 100644 index 0000000..8ee8e84 --- /dev/null +++ b/ZuneUI/MixStackEntry.cs @@ -0,0 +1,30 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixStackEntry +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class MixStackEntry + { + private MixResult _result; + private object _layout; + private IList _dataList; + + public MixStackEntry(MixResult result, object layout, IList dataList) + { + this._result = result; + this._layout = layout; + this._dataList = dataList; + } + + public MixResult Result => this._result; + + public object Layout => this._layout; + + public IList DataList => this._dataList; + } +} diff --git a/ZuneUI/MixTileSaveData.cs b/ZuneUI/MixTileSaveData.cs new file mode 100644 index 0000000..3a186c0 --- /dev/null +++ b/ZuneUI/MixTileSaveData.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MixTileSaveData +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class MixTileSaveData + { + private MixResult _result; + private object _size; + private object _position; + private object _seedSize; + + public MixTileSaveData(MixResult result, object size, object position, object seedSize) + { + this._result = result; + this._size = size; + this._position = position; + this._seedSize = seedSize; + } + + public MixResult Result => this._result; + + public object Size => this._size; + + public object Position => this._position; + + public object SeedSize => this._seedSize; + } +} diff --git a/ZuneUI/MobileWirelessSync.cs b/ZuneUI/MobileWirelessSync.cs new file mode 100644 index 0000000..07df1c5 --- /dev/null +++ b/ZuneUI/MobileWirelessSync.cs @@ -0,0 +1,177 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MobileWirelessSync +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class MobileWirelessSync : ModelItem + { + private UIDevice _mobileDevice; + private string _mediaSyncSSID; + private string _connectedSSID; + private int _errorCode = HRESULT._S_OK.Int; + + public MobileWirelessSync(UIDevice endpoint) + : base((IModelItemOwner)ZuneShell.DefaultInstance.Management.DeviceManagement) + => this._mobileDevice = endpoint; + + public string MediaSyncSSID + { + get + { + if (string.IsNullOrEmpty(this._mediaSyncSSID)) + { + string empty = string.Empty; + this._mediaSyncSSID = this._mobileDevice.GetWifiMediaSyncSSID(ref empty) == HRESULT._S_OK ? empty : string.Empty; + } + return this._mediaSyncSSID ?? string.Empty; + } + set + { + if (!(value != this._mediaSyncSSID)) + return; + HRESULT hresult = this._mobileDevice.SetWifiMediaSyncSSID(value); + if (hresult == HRESULT._S_OK) + { + this._mediaSyncSSID = value; + } + else + { + this._mediaSyncSSID = string.Empty; + this.ErrorCode = hresult.Int; + } + this.FirePropertyChanged(nameof(MediaSyncSSID)); + } + } + + public string ConnectedSSID + { + get + { + if (string.IsNullOrEmpty(this._connectedSSID)) + { + string empty = string.Empty; + HRESULT wifiConnectedSsid = this._mobileDevice.GetWifiConnectedSSID(ref empty); + if (wifiConnectedSsid == HRESULT._S_OK) + { + this._connectedSSID = empty; + } + else + { + this._connectedSSID = string.Empty; + this.ErrorCode = wifiConnectedSsid.Int; + } + } + return this._connectedSSID ?? string.Empty; + } + } + + public bool IsWlanDeviceDisabled + { + get + { + bool disabled = false; + HRESULT hresult = this._mobileDevice.IsWlanDeviceDisabled(ref disabled); + if (hresult != HRESULT._S_OK) + this.ErrorCode = hresult.Int; + return disabled; + } + } + + public int ErrorCode + { + get => this._errorCode; + private set + { + ShipAssert.Assert(value != HRESULT._S_OK.Int); + if (this._errorCode == value) + return; + this._errorCode = value; + this.FirePropertyChanged(nameof(ErrorCode)); + } + } + + public bool WiFiSetupSuccess => true; + + private void ResetErrorCode() => this._errorCode = HRESULT._S_OK.Int; + + public void TestMediaSyncConnection() + { + this.ResetErrorCode(); + this._mobileDevice.WiFiTestCompletedEvent += new FallibleEventHandler(this.WiFiTestCompleted); + HRESULT hresult = this._mobileDevice.TestWiFi(); + if (!hresult.IsError) + return; + this._mobileDevice.WiFiTestCompletedEvent -= new FallibleEventHandler(this.WiFiTestCompleted); + this.ErrorCode = hresult.Int; + } + + public void RefreshConnectedNetwork() + { + this._connectedSSID = string.Empty; + this.FirePropertyChanged("ConnectedSSID"); + } + + public void RefreshSyncNetwork() + { + this._mediaSyncSSID = string.Empty; + this.FirePropertyChanged("MediaSyncSSID"); + } + + public void UnassociateNetwork() + { + this.ResetErrorCode(); + this._mobileDevice.WiFiRemovalCompletedEvent += new FallibleEventHandler(this.WiFiRemovalCompleted); + HRESULT hresult = this._mobileDevice.RemoveWiFiAssociation(); + if (!hresult.IsError) + return; + this._mobileDevice.WiFiRemovalCompletedEvent -= new FallibleEventHandler(this.WiFiRemovalCompleted); + this.ErrorCode = hresult.Int; + } + + private void WiFiTestCompleted(object sender, FallibleEventArgs args) + { + this.ResetErrorCode(); + this._mobileDevice.WiFiTestCompletedEvent -= new FallibleEventHandler(this.WiFiTestCompleted); + if (args.HR.IsSuccess) + { + this._mobileDevice.WiFiAssociationCompletedEvent += new FallibleEventHandler(this.WiFiAssociationCompleted); + HRESULT hresult = this._mobileDevice.AssociateWiFi(); + if (!(hresult != HRESULT._S_OK)) + return; + this._mobileDevice.WiFiAssociationCompletedEvent -= new FallibleEventHandler(this.WiFiAssociationCompleted); + this.ErrorCode = hresult.Int; + } + else + this.ErrorCode = args.HR.Int; + } + + private void WiFiAssociationCompleted(object sender, FallibleEventArgs args) + { + this.ResetErrorCode(); + this._mobileDevice.WiFiAssociationCompletedEvent -= new FallibleEventHandler(this.WiFiAssociationCompleted); + if (args.HR.IsSuccess) + { + this.MediaSyncSSID = this.ConnectedSSID; + this.FirePropertyChanged("WiFiSetupSuccess"); + } + else + this.ErrorCode = args.HR.Int; + } + + private void WiFiRemovalCompleted(object sender, FallibleEventArgs args) + { + this.ResetErrorCode(); + this._mobileDevice.WiFiRemovalCompletedEvent -= new FallibleEventHandler(this.WiFiRemovalCompleted); + if (args.HR.IsSuccess) + this.MediaSyncSSID = string.Empty; + else + this.ErrorCode = args.HR.Int; + } + } +} diff --git a/ZuneUI/MobileWirelessSyncConfirmPage.cs b/ZuneUI/MobileWirelessSyncConfirmPage.cs new file mode 100644 index 0000000..d31ba00 --- /dev/null +++ b/ZuneUI/MobileWirelessSyncConfirmPage.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MobileWirelessSyncConfirmPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class MobileWirelessSyncConfirmPage : MobileWirelessSyncWizardPage + { + public MobileWirelessSyncConfirmPage(Wizard owner) + : base(owner) + => this.Description = Shell.LoadString(StringId.IDS_WIRELESS_MOBILE_WIZARD_CONFIRM_TITLE); + + public override string UI => "res://ZuneShellResources!MobileWirelessSync.uix#MobileWirelessSyncConfirmPage"; + + public override void OnCancel() => SQMLog.Log(SQMDataId.WirelessSyncWizardCancel, 1); + } +} diff --git a/ZuneUI/MobileWirelessSyncErrorPage.cs b/ZuneUI/MobileWirelessSyncErrorPage.cs new file mode 100644 index 0000000..db76a3a --- /dev/null +++ b/ZuneUI/MobileWirelessSyncErrorPage.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MobileWirelessSyncErrorPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class MobileWirelessSyncErrorPage : WizardErrorPage + { + public MobileWirelessSyncErrorPage(Wizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_WIRELESS_MOBILE_WIZARD_TROUBLESHOOT); + + public override string UI => "res://ZuneShellResources!MobileWirelessSync.uix#MobileWirelessSyncErrorPage"; + + public void OnCancel() => SQMLog.Log(SQMDataId.WirelessSyncWizardCancelFail, 1); + } +} diff --git a/ZuneUI/MobileWirelessSyncSummaryPage.cs b/ZuneUI/MobileWirelessSyncSummaryPage.cs new file mode 100644 index 0000000..e43717a --- /dev/null +++ b/ZuneUI/MobileWirelessSyncSummaryPage.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MobileWirelessSyncSummaryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class MobileWirelessSyncSummaryPage : MobileWirelessSyncWizardPage + { + public MobileWirelessSyncSummaryPage(Wizard owner) + : base(owner) + => this.Description = Shell.LoadString(StringId.IDS_WIRELESS_MOBILE_WIZARD_CONFIRM_TITLE); + + public override string UI => "res://ZuneShellResources!MobileWirelessSync.uix#MobileWirelessSyncSummaryPage"; + + public override void OnCancel() => SQMLog.Log(SQMDataId.WirelessSyncWizardComplete, 1); + } +} diff --git a/ZuneUI/MobileWirelessSyncWizard.cs b/ZuneUI/MobileWirelessSyncWizard.cs new file mode 100644 index 0000000..723db25 --- /dev/null +++ b/ZuneUI/MobileWirelessSyncWizard.cs @@ -0,0 +1,48 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MobileWirelessSyncWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class MobileWirelessSyncWizard : Wizard + { + private MobileWirelessSync _mobileWirelessSync; + + public MobileWirelessSyncWizard() + { + this.AddPage((WizardPage)new MobileWirelessSyncConfirmPage((Wizard)this)); + this.AddPage((WizardPage)new MobileWirelessSyncSummaryPage((Wizard)this)); + this.AddPage((WizardPage)new MobileWirelessSyncErrorPage((Wizard)this)); + } + + protected override void OnSetError(HRESULT hr, object state) + { + if (hr == HRESULT._S_OK) + this.ErrorPageIsEnabled = false; + base.OnSetError(hr, state); + } + + public MobileWirelessSync MobileWirelessSync + { + get => this._mobileWirelessSync; + set + { + if (this._mobileWirelessSync == value) + return; + this._mobileWirelessSync = value; + this.FirePropertyChanged(nameof(MobileWirelessSync)); + } + } + + public override void Cancel() + { + if (this.CurrentPage is MobileWirelessSyncWizardPage currentPage) + currentPage.OnCancel(); + if (this.CurrentPage is MobileWirelessSyncErrorPage currentPage) + currentPage.OnCancel(); + base.Cancel(); + } + } +} diff --git a/ZuneUI/MobileWirelessSyncWizardPage.cs b/ZuneUI/MobileWirelessSyncWizardPage.cs new file mode 100644 index 0000000..005119a --- /dev/null +++ b/ZuneUI/MobileWirelessSyncWizardPage.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MobileWirelessSyncWizardPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class MobileWirelessSyncWizardPage : WizardPage + { + public MobileWirelessSyncWizardPage(Wizard owner) + : base(owner) + { + } + + public abstract void OnCancel(); + } +} diff --git a/ZuneUI/MonitorDetector.cs b/ZuneUI/MonitorDetector.cs new file mode 100644 index 0000000..bcd5de6 --- /dev/null +++ b/ZuneUI/MonitorDetector.cs @@ -0,0 +1,69 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MonitorDetector +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace ZuneUI +{ + internal class MonitorDetector + { + private List _listInProgress; + + public List DetectMonitors() + { + List monitorSizeList = new List(); + this._listInProgress = monitorSizeList; + MonitorDetector.EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, new MonitorDetector.MonitorEnumProc(this.MonitorEnumerated), IntPtr.Zero); + this._listInProgress = (List)null; + return monitorSizeList; + } + + private bool MonitorEnumerated( + IntPtr hMonitor, + IntPtr hdcMonitor, + [In] ref RECT lprcMonitor, + IntPtr dwData) + { + MonitorDetector.MONITORINFO lpmi = new MonitorDetector.MONITORINFO(); + lpmi.cbSize = Marshal.SizeOf((object)lpmi); + if (MonitorDetector.GetMonitorInfo(hMonitor, ref lpmi)) + { + --lpmi.rcMonitor.Right; + --lpmi.rcMonitor.Bottom; + --lpmi.rcWorkArea.Right; + --lpmi.rcWorkArea.Bottom; + this._listInProgress.Add(new MonitorSize(lpmi.rcMonitor, lpmi.rcWorkArea)); + } + return true; + } + + [DllImport("user32.dll")] + private static extern bool EnumDisplayMonitors( + IntPtr hdc, + IntPtr lprcClip, + MonitorDetector.MonitorEnumProc lpfnEnum, + IntPtr dwData); + + [DllImport("user32.dll")] + private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MonitorDetector.MONITORINFO lpmi); + + private delegate bool MonitorEnumProc( + IntPtr hMonitor, + IntPtr hdcMonitor, + [In] ref RECT lprcMonitor, + IntPtr dwData); + + private struct MONITORINFO + { + public int cbSize; + public RECT rcMonitor; + public RECT rcWorkArea; + public int dwFlags; + } + } +} diff --git a/ZuneUI/MonitorSize.cs b/ZuneUI/MonitorSize.cs new file mode 100644 index 0000000..11ad151 --- /dev/null +++ b/ZuneUI/MonitorSize.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MonitorSize +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal struct MonitorSize + { + public readonly RECT TotalArea; + public readonly RECT WorkArea; + + public MonitorSize(RECT rcTotal, RECT rcWork) + { + this.TotalArea = rcTotal; + this.WorkArea = rcWork; + } + } +} diff --git a/ZuneUI/MousePosition.cs b/ZuneUI/MousePosition.cs new file mode 100644 index 0000000..989adac --- /dev/null +++ b/ZuneUI/MousePosition.cs @@ -0,0 +1,113 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MousePosition +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using System; +using System.Runtime.InteropServices; +using System.Threading; + +namespace ZuneUI +{ + public class MousePosition : ModelItem + { + private int _x; + private int _y; + private System.Threading.Timer _checkPostion; + private bool _invokeOutstanding; + + public MousePosition() + { + this._invokeOutstanding = false; + this._checkPostion = new System.Threading.Timer(new TimerCallback(this.CheckPosition), (object)null, 0, 16); + } + + private void CheckPosition(object state) + { + if (this._invokeOutstanding) + return; + this._invokeOutstanding = true; + int x; + int y; + MousePosition.GetCursorScreenPosition(out x, out y); + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredUpdatePosition), (object)new object[2] + { + (object) x, + (object) y + }); + } + + private void DeferredUpdatePosition(object arg) + { + object[] objArray = (object[])arg; + int num1 = (int)objArray[0]; + int num2 = (int)objArray[1]; + RECT lpRect; + if (!MousePosition.GetWindowRect(ZuneApplication.GetRenderWindow(), out lpRect)) + { + lpRect.Left = 0; + lpRect.Top = 0; + lpRect.Right = 1; + lpRect.Bottom = 1; + } + int num3 = num1 < lpRect.Left ? lpRect.Left : num1; + int num4 = num3 >= lpRect.Right ? lpRect.Right - 1 : num3; + int num5 = num2 < lpRect.Top ? lpRect.Top : num2; + int num6 = num5 >= lpRect.Bottom ? lpRect.Bottom - 1 : num5; + this.X = num4 - lpRect.Left; + this.Y = num6 - lpRect.Top; + this._invokeOutstanding = false; + } + + public int X + { + get => this._x; + private set + { + if (value == this._x) + return; + this._x = value; + this.FirePropertyChanged(nameof(X)); + } + } + + public int Y + { + get => this._y; + private set + { + if (value == this._y) + return; + this._y = value; + this.FirePropertyChanged(nameof(Y)); + } + } + + public static void GetCursorScreenPosition(out int x, out int y) + { + MousePosition.POINT lpPoint; + if (MousePosition.GetCursorPos(out lpPoint)) + { + x = lpPoint.X; + y = lpPoint.Y; + } + else + x = y = 0; + } + + [DllImport("User32.dll")] + private static extern bool GetCursorPos(out MousePosition.POINT lpPoint); + + [DllImport("User32.dll")] + private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); + + private struct POINT + { + public int X; + public int Y; + } + } +} diff --git a/ZuneUI/MovieAttachment.cs b/ZuneUI/MovieAttachment.cs new file mode 100644 index 0000000..912413c --- /dev/null +++ b/ZuneUI/MovieAttachment.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MovieAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class MovieAttachment : VideoAttachment + { + public const string RequestTypeString = "movie"; + + public MovieAttachment(Guid id, string title, string imageUri) + : base(id, title, string.Empty, imageUri) + { + this.AttachmentUI = "res://ZuneShellResources!SocialComposer.uix#MovieAttachmentUI"; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_MOVIE_ATTACHMENT); + } + + public override string RequestType => "movie"; + } +} diff --git a/ZuneUI/MovieType.cs b/ZuneUI/MovieType.cs new file mode 100644 index 0000000..525bac9 --- /dev/null +++ b/ZuneUI/MovieType.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MovieType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum MovieType + { + Full, + Trailer, + Other, + } +} diff --git a/ZuneUI/MoviesAvailableFor.cs b/ZuneUI/MoviesAvailableFor.cs new file mode 100644 index 0000000..5fd8e20 --- /dev/null +++ b/ZuneUI/MoviesAvailableFor.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MoviesAvailableFor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum MoviesAvailableFor + { + PurchaseAndRental, + Purchase, + Rental, + } +} diff --git a/ZuneUI/MultiFeatureMenuItemCommand.cs b/ZuneUI/MultiFeatureMenuItemCommand.cs new file mode 100644 index 0000000..dea304e --- /dev/null +++ b/ZuneUI/MultiFeatureMenuItemCommand.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MultiFeatureMenuItemCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System.Collections; + +namespace ZuneUI +{ + public class MultiFeatureMenuItemCommand : MenuItemCommand + { + private IList _features; + private int _hidden = -1; + + public IList Features + { + get => this._features; + set + { + if (this._features != value) + this._hidden = -1; + this._features = value; + } + } + + public override bool ShouldHide() + { + if (this._hidden == -1) + { + this._hidden = 0; + foreach (object feature in (IEnumerable)this._features) + { + if (feature is global::Features eFeature && !FeatureEnablement.IsFeatureEnabled(eFeature)) + { + this._hidden = 1; + break; + } + } + } + return this._hidden == 1 || base.ShouldHide(); + } + } +} diff --git a/ZuneUI/MusicLibraryListPanelBase.cs b/ZuneUI/MusicLibraryListPanelBase.cs new file mode 100644 index 0000000..6993495 --- /dev/null +++ b/ZuneUI/MusicLibraryListPanelBase.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MusicLibraryListPanelBase +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class MusicLibraryListPanelBase : ListPanel + { + internal MusicLibraryListPanelBase(MusicLibraryPage libraryPage) + : base((IModelItemOwner)libraryPage) + { + } + + protected MusicLibraryPage LibraryPage => base.LibraryPage as MusicLibraryPage; + } +} diff --git a/ZuneUI/MusicLibraryPage.cs b/ZuneUI/MusicLibraryPage.cs new file mode 100644 index 0000000..9088e48 --- /dev/null +++ b/ZuneUI/MusicLibraryPage.cs @@ -0,0 +1,870 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MusicLibraryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.PerfTrace; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class MusicLibraryPage : LibraryPage + { + private ArtistsPanel _artistsPanel; + private GenresPanel _genresPanel; + private AlbumsPanel _albumsPanel; + private TracksPanel _tracksPanel; + private PlaylistsPanel _playlistsPanel; + private PlaylistContentsPanel _playlistContentsPanel; + private Guid _selectedArtistZuneMediaId; + private string _selectedArtistTitle; + private IList _selectedArtistIds; + private IList _selectedGenreIds; + private IList _selectedAlbumIds; + private IList _selectedTrackIds; + private object _selectedPlaylist; + private string _trackListSort; + private string _trackListSortAllTracksArtistView; + private string _trackListSortAllTracksAlbumView; + private string _trackListSortAllTracksGenreView; + private string _trackListSortSelectedArtists; + private string _trackListSortSelectedGenres; + private string _trackListSortSelectedAlbums; + private bool _allArtistsSelected; + private bool _allGenresSelected; + private bool _allAlbumsSelected; + private int _artistsCount; + private int _genresCount; + private int _albumsCount; + private Command _albumsChanged; + private Command _albumEdited; + private int _albumArtistCount; + private MusicLibraryView _view; + private Command _leftItemClicked; + private Command _albumClicked; + private Command _createPlaylistCommand; + private Command _createAutoPlaylistCommand; + private bool _updatePreferredView; + private static Command _preferredContentType; + private static bool _hasContentTypesPersonal; + private static bool _hasContentTypesProtected; + private static bool _hasContentTypesZunePass; + private static Command _showContentTypesAll; + private static Command _showContentTypesPersonal; + private static Command _showContentTypesProtected; + private static Command _showContentTypesZunePass; + + public MusicLibraryPage(bool showDevice) + : this(showDevice, MusicLibraryView.Invalid) + { + } + + public MusicLibraryPage(bool showDevice, MusicLibraryView desiredView) + : base(showDevice, MediaType.Track) + { + this.UI = MusicLibraryPage.LibraryTemplate; + this.UIPath = "Collection\\Music"; + this._updatePreferredView = true; + if (showDevice) + { + this.PivotPreference = ZuneUI.Shell.MainFrame.Device.Music; + Deviceland.InitDevicePage((ZunePage)this); + } + else + this.PivotPreference = ZuneUI.Shell.MainFrame.Collection.Music; + this.IsRootPage = true; + this.Views = (Choice)new NotifyChoice((IModelItemOwner)this); + if (!this.ShowDeviceContents) + this.Views.Options = (IList)new MusicLibraryPage.ViewCommand[5] + { + new MusicLibraryPage.ViewCommand((IModelItemOwner) this.Views, ZuneUI.Shell.LoadString(StringId.IDS_COLLECTION_BROWSE), new EventHandler(this.ShowArtistPivot), MusicLibraryView.Artist), + new MusicLibraryPage.ViewCommand((IModelItemOwner) this.Views, ZuneUI.Shell.LoadString(StringId.IDS_COLLECTION_GENRE), new EventHandler(this.ShowGenrePivot), MusicLibraryView.Genre), + new MusicLibraryPage.ViewCommand((IModelItemOwner) this.Views, ZuneUI.Shell.LoadString(StringId.IDS_COLLECTION_ALBUM), new EventHandler(this.ShowAlbumPivot), MusicLibraryView.Album), + new MusicLibraryPage.ViewCommand((IModelItemOwner) this.Views, ZuneUI.Shell.LoadString(StringId.IDS_COLLECTION_LIST), new EventHandler(this.ShowSongPivot), MusicLibraryView.Song), + new MusicLibraryPage.ViewCommand((IModelItemOwner) this.Views, ZuneUI.Shell.LoadString(StringId.IDS_PLAYLISTS_PIVOT), new EventHandler(this.ShowPlaylistPivot), MusicLibraryView.Playlist) + }; + else + this.Views.Options = (IList)new MusicLibraryPage.ViewCommand[2] + { + new MusicLibraryPage.ViewCommand((IModelItemOwner) this.Views, ZuneUI.Shell.LoadString(StringId.IDS_COLLECTION_BROWSE), new EventHandler(this.ShowArtistPivot), MusicLibraryView.Artist), + new MusicLibraryPage.ViewCommand((IModelItemOwner) this.Views, ZuneUI.Shell.LoadString(StringId.IDS_PLAYLISTS_PIVOT), new EventHandler(this.ShowPlaylistPivot), MusicLibraryView.Playlist) + }; + int num = -1; + if (desiredView != MusicLibraryView.Invalid) + { + for (int index = 0; index < this.Views.Options.Count; ++index) + { + if (desiredView == ((MusicLibraryPage.ViewCommand)this.Views.Options[index]).View) + { + num = index; + break; + } + } + } + if (num == -1) + num = !this.ShowDeviceContents ? ClientConfiguration.Shell.MusicCollectionView : ClientConfiguration.Shell.MusicDeviceView; + this.Views.ChosenChanged += new EventHandler(this.ViewChanged); + if (num >= 0 && num < this.Views.Options.Count) + this.Views.ChosenIndex = num; + this.ContentTypes = (Choice)new NotifyChoice((IModelItemOwner)this); + this.ContentTypes.Options = (IList)new ArrayListDataSet((IModelItemOwner)this.ContentTypes); + this.ShowContentTypes.Value = ClientConfiguration.Shell.ShowContentTypes; + this.ShowContentTypes.ChosenChanged += new EventHandler(this.ShowContentTypesChanged); + this.TransportControlStyle = TransportControlStyle.Music; + this.PlaybackContext = PlaybackContext.Music; + this._createPlaylistCommand = new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_PLAYLIST_DIALOG_CREATEPLAYLIST), (EventHandler)null); + this._createAutoPlaylistCommand = new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_CREATEAUTOPLAYLIST_BUTTON), (EventHandler)null); + this._albumsChanged = new Command((IModelItemOwner)this); + this._albumEdited = new Command((IModelItemOwner)this); + this._leftItemClicked = new Command((IModelItemOwner)this); + this._albumClicked = new Command((IModelItemOwner)this); + } + + public MusicLibraryView View + { + get => this._view; + private set + { + if (this._view == value) + return; + this._view = value; + this.FirePropertyChanged(nameof(View)); + } + } + + public IList SelectedArtistIds + { + get => this._selectedArtistIds; + set + { + if (this._selectedArtistIds == value) + return; + this._selectedArtistIds = value; + this.FirePropertyChanged(nameof(SelectedArtistIds)); + this.FirePropertyChanged("SelectedArtistsCount"); + } + } + + public int SelectedArtistsCount + { + get + { + if (this.AllArtistsSelected) + return this.ArtistsCount; + return this.SelectedArtistIds == null ? 0 : this.SelectedArtistIds.Count; + } + } + + public IList SelectedGenreIds + { + get => this._selectedGenreIds; + set + { + if (this._selectedGenreIds == value) + return; + this._selectedGenreIds = value; + this.FirePropertyChanged(nameof(SelectedGenreIds)); + this.FirePropertyChanged("SelectedGenresCount"); + } + } + + public int SelectedGenresCount + { + get + { + if (this.AllGenresSelected) + return this.GenresCount; + return this.SelectedGenreIds == null ? 0 : this.SelectedGenreIds.Count; + } + } + + public Guid SelectedArtistZuneMediaId + { + get => this._selectedArtistZuneMediaId; + set + { + if (!(this._selectedArtistZuneMediaId != value)) + return; + this._selectedArtistZuneMediaId = value; + this.FirePropertyChanged(nameof(SelectedArtistZuneMediaId)); + } + } + + public string SelectedArtistTitle + { + get => this._selectedArtistTitle; + set + { + if (!(this._selectedArtistTitle != value)) + return; + this._selectedArtistTitle = value; + this.FirePropertyChanged(nameof(SelectedArtistTitle)); + } + } + + public Command LeftItemClicked => this._leftItemClicked; + + public Command AlbumsChanged => this._albumsChanged; + + public Command AlbumEdited => this._albumEdited; + + public bool AllArtistsSelected + { + get => this._allArtistsSelected; + set + { + if (this._allArtistsSelected == value) + return; + this._allArtistsSelected = value; + this.FirePropertyChanged(nameof(AllArtistsSelected)); + this.FirePropertyChanged("SelectedArtistsCount"); + } + } + + public bool AllGenresSelected + { + get => this._allGenresSelected; + set + { + if (this._allGenresSelected == value) + return; + this._allGenresSelected = value; + this.FirePropertyChanged(nameof(AllGenresSelected)); + this.FirePropertyChanged("SelectedGenresCount"); + } + } + + public bool AllAlbumsSelected + { + get => this._allAlbumsSelected; + set + { + if (this._allAlbumsSelected == value) + return; + this._allAlbumsSelected = value; + this.FirePropertyChanged(nameof(AllAlbumsSelected)); + this.FirePropertyChanged("SelectedAlbumsCount"); + } + } + + public int ArtistsCount + { + get => this._artistsCount; + set + { + if (this._artistsCount == value) + return; + this._artistsCount = value; + this.FirePropertyChanged(nameof(ArtistsCount)); + if (!this.AllArtistsSelected) + return; + this.FirePropertyChanged("SelectedArtistsCount"); + } + } + + public int GenresCount + { + get => this._genresCount; + set + { + if (this._genresCount == value) + return; + this._genresCount = value; + this.FirePropertyChanged(nameof(GenresCount)); + if (!this.AllGenresSelected) + return; + this.FirePropertyChanged("SelectedGenresCount"); + } + } + + public int AlbumsCount + { + get => this._albumsCount; + set + { + if (this._albumsCount == value) + return; + this._albumsCount = value; + this.FirePropertyChanged(nameof(AlbumsCount)); + if (!this.AllAlbumsSelected) + return; + this.FirePropertyChanged("SelectedAlbumsCount"); + } + } + + public int AlbumArtistCount + { + get => this._albumArtistCount; + set + { + if (this._albumArtistCount == value) + return; + this._albumArtistCount = value; + this.FirePropertyChanged(nameof(AlbumArtistCount)); + } + } + + public IList SelectedAlbumIds + { + get => this._selectedAlbumIds; + set + { + if (this._selectedAlbumIds == value) + return; + this._selectedAlbumIds = value; + this.FirePropertyChanged(nameof(SelectedAlbumIds)); + this.FirePropertyChanged("SelectedAlbumsCount"); + } + } + + public int SelectedAlbumsCount + { + get + { + if (this.AllAlbumsSelected) + return this.AlbumsCount; + return this.SelectedAlbumIds == null ? 0 : this.SelectedAlbumIds.Count; + } + } + + public string TrackListSort + { + get => this._trackListSort; + set + { + if (!(this._trackListSort != value)) + return; + this._trackListSort = value; + this.FirePropertyChanged(nameof(TrackListSort)); + } + } + + public string TrackListSortAllTracksArtistView + { + get => this._trackListSortAllTracksArtistView; + set + { + if (!(this._trackListSortAllTracksArtistView != value)) + return; + this._trackListSortAllTracksArtistView = value; + this.FirePropertyChanged(nameof(TrackListSortAllTracksArtistView)); + } + } + + public string TrackListSortAllTracksAlbumView + { + get => this._trackListSortAllTracksAlbumView; + set + { + if (!(this._trackListSortAllTracksAlbumView != value)) + return; + this._trackListSortAllTracksAlbumView = value; + this.FirePropertyChanged(nameof(TrackListSortAllTracksAlbumView)); + } + } + + public string TrackListSortAllTracksGenreView + { + get => this._trackListSortAllTracksGenreView; + set + { + if (!(this._trackListSortAllTracksGenreView != value)) + return; + this._trackListSortAllTracksGenreView = value; + this.FirePropertyChanged(nameof(TrackListSortAllTracksGenreView)); + } + } + + public string TrackListSortSelectedArtists + { + get => this._trackListSortSelectedArtists; + set + { + if (!(this._trackListSortSelectedArtists != value)) + return; + this._trackListSortSelectedArtists = value; + this.FirePropertyChanged(nameof(TrackListSortSelectedArtists)); + } + } + + public string TrackListSortSelectedGenres + { + get => this._trackListSortSelectedGenres; + set + { + if (!(this._trackListSortSelectedGenres != value)) + return; + this._trackListSortSelectedGenres = value; + this.FirePropertyChanged(nameof(TrackListSortSelectedGenres)); + } + } + + public string TrackListSortSelectedAlbums + { + get => this._trackListSortSelectedAlbums; + set + { + if (!(this._trackListSortSelectedAlbums != value)) + return; + this._trackListSortSelectedAlbums = value; + this.FirePropertyChanged(nameof(TrackListSortSelectedAlbums)); + } + } + + public string GetSort(bool singleAlbum, MediaType mediaType) + { + if (this.View != MusicLibraryView.Artist && this.View != MusicLibraryView.Genre && this.View != MusicLibraryView.Album) + return this.TrackListSort; + bool flag = (this.SelectedAlbumIds == null || this.SelectedAlbumIds.Count == 0 || this.AllAlbumsSelected) && (this.SelectedGenreIds == null || this.SelectedGenreIds.Count == 0 || this.AllGenresSelected) && (this.SelectedArtistIds == null || this.SelectedArtistIds.Count == 0 || this.AllArtistsSelected); + if (mediaType == MediaType.Album && !flag) + return this.TrackListSortSelectedAlbums; + if (mediaType == MediaType.Artist && !flag) + return this.TrackListSortSelectedArtists; + if (mediaType == MediaType.Genre && !flag) + return this.TrackListSortSelectedGenres; + if (this.View == MusicLibraryView.Artist) + return this.TrackListSortAllTracksArtistView; + return this.View == MusicLibraryView.Album ? this.TrackListSortAllTracksAlbumView : this.TrackListSortAllTracksGenreView; + } + + public Command AlbumClicked => this._albumClicked; + + public IList SelectedTrackIds + { + get => this._selectedTrackIds; + set + { + if (this._selectedTrackIds == value) + return; + this._selectedTrackIds = value; + this.FirePropertyChanged(nameof(SelectedTrackIds)); + } + } + + public Command CreatePlaylistCommand => this._createPlaylistCommand; + + public Command CreateAutoPlaylistCommand => this._createAutoPlaylistCommand; + + public object SelectedPlaylist + { + get => this._selectedPlaylist; + set + { + if (this._selectedPlaylist == value) + return; + this._selectedPlaylist = value; + this.FirePropertyChanged(nameof(SelectedPlaylist)); + } + } + + private void ViewChanged(object sender, EventArgs e) + { + if (this._updatePreferredView) + { + if (this.ShowDeviceContents) + ClientConfiguration.Shell.MusicDeviceView = this.Views.ChosenIndex; + else + ClientConfiguration.Shell.MusicCollectionView = this.Views.ChosenIndex; + } + this._selectedArtistIds = (IList)null; + this._selectedGenreIds = (IList)null; + this._selectedAlbumIds = (IList)null; + this._selectedPlaylist = (object)null; + this.ShowPlaylistIcon = !this.ShowDeviceContents && ((MusicLibraryPage.ViewCommand)this.Views.ChosenValue).View != MusicLibraryView.Playlist; + } + + public ArtistsPanel ArtistsPanel + { + get + { + if (this._artistsPanel == null) + this._artistsPanel = new ArtistsPanel(this); + return this._artistsPanel; + } + } + + public GenresPanel GenresPanel + { + get + { + if (this._genresPanel == null) + this._genresPanel = new GenresPanel(this); + return this._genresPanel; + } + } + + public AlbumsPanel AlbumsPanel + { + get + { + if (this._albumsPanel == null) + this._albumsPanel = new AlbumsPanel(this); + return this._albumsPanel; + } + } + + public TracksPanel TracksPanel + { + get + { + if (this._tracksPanel == null) + this._tracksPanel = new TracksPanel(this); + return this._tracksPanel; + } + } + + public PlaylistsPanel PlaylistsPanel + { + get + { + if (this._playlistsPanel == null) + { + this._playlistsPanel = new PlaylistsPanel(this); + if (!this.ShowDeviceContents) + this._playlistsPanel.SelectedLibraryIds = (IList)new int[1] + { + PlaylistManager.Instance.DefaultPlaylistId + }; + } + return this._playlistsPanel; + } + } + + public PlaylistContentsPanel PlaylistContentsPanel + { + get + { + if (this._playlistContentsPanel == null) + this._playlistContentsPanel = new PlaylistContentsPanel((LibraryPage)this); + return this._playlistContentsPanel; + } + } + + private void ShowContentTypesChanged(object sender, EventArgs e) + { + if (!this.ShowContentTypes.Value) + this.DrmStateMask = DrmStateMask.All(); + ClientConfiguration.Shell.ShowContentTypes = this.ShowContentTypes.Value; + } + + private void ContentTypesChanged(object sender, EventArgs e) => MusicLibraryPage._preferredContentType = (Command)this.ContentTypes.ChosenValue; + + public bool HasContentTypesPersonal + { + get => MusicLibraryPage._hasContentTypesPersonal; + set + { + if (MusicLibraryPage._hasContentTypesPersonal == value) + return; + MusicLibraryPage._hasContentTypesPersonal = value; + this.FirePropertyChanged(nameof(HasContentTypesPersonal)); + this.UpdateContentTypesPivots(); + } + } + + public bool HasContentTypesProtected + { + get => MusicLibraryPage._hasContentTypesProtected; + set + { + if (MusicLibraryPage._hasContentTypesProtected == value) + return; + MusicLibraryPage._hasContentTypesProtected = value; + this.FirePropertyChanged(nameof(HasContentTypesProtected)); + this.UpdateContentTypesPivots(); + } + } + + public bool HasContentTypesZunePass + { + get => MusicLibraryPage._hasContentTypesZunePass; + set + { + if (MusicLibraryPage._hasContentTypesZunePass == value) + return; + MusicLibraryPage._hasContentTypesZunePass = value; + this.FirePropertyChanged(nameof(HasContentTypesZunePass)); + this.UpdateContentTypesPivots(); + } + } + + private void UpdateContentTypesPivots() + { + if (this.ShowDeviceContents) + return; + int num = 0; + if (MusicLibraryPage._hasContentTypesPersonal) + ++num; + if (MusicLibraryPage._hasContentTypesProtected) + ++num; + if (MusicLibraryPage._hasContentTypesZunePass) + ++num; + this.ContentTypes.Options.Clear(); + if (num > 1) + { + if (MusicLibraryPage._showContentTypesAll == null) + MusicLibraryPage._showContentTypesAll = new Command((IModelItemOwner)null, ZuneUI.Shell.LoadString(StringId.IDS_COLLECTION_CONTENT_TYPES_ALL), new EventHandler(MusicLibraryPage.ShowContentTypesAll)); + this.ContentTypes.Options.Add((object)MusicLibraryPage._showContentTypesAll); + if (MusicLibraryPage._hasContentTypesPersonal) + { + if (MusicLibraryPage._showContentTypesPersonal == null) + MusicLibraryPage._showContentTypesPersonal = new Command((IModelItemOwner)null, ZuneUI.Shell.LoadString(StringId.IDS_COLLECTION_CONTENT_TYPES_PERSONAL), new EventHandler(MusicLibraryPage.ShowContentTypesPersonal)); + this.ContentTypes.Options.Add((object)MusicLibraryPage._showContentTypesPersonal); + } + if (MusicLibraryPage._hasContentTypesProtected) + { + if (MusicLibraryPage._showContentTypesProtected == null) + MusicLibraryPage._showContentTypesProtected = new Command((IModelItemOwner)null, ZuneUI.Shell.LoadString(StringId.IDS_COLLECTION_CONTENT_TYPES_PROTECTED), new EventHandler(MusicLibraryPage.ShowContentTypesProtected)); + this.ContentTypes.Options.Add((object)MusicLibraryPage._showContentTypesProtected); + } + if (MusicLibraryPage._hasContentTypesZunePass) + { + if (MusicLibraryPage._showContentTypesZunePass == null) + MusicLibraryPage._showContentTypesZunePass = new Command((IModelItemOwner)null, ZuneUI.Shell.LoadString(StringId.IDS_COLLECTION_CONTENT_TYPES_ZUNEPASS), new EventHandler(MusicLibraryPage.ShowContentTypesZunePass)); + this.ContentTypes.Options.Add((object)MusicLibraryPage._showContentTypesZunePass); + } + if (!this.ContentTypes.Options.Contains((object)MusicLibraryPage._preferredContentType)) + MusicLibraryPage._preferredContentType = MusicLibraryPage._showContentTypesAll; + this.ContentTypes.ChosenValue = (object)MusicLibraryPage._preferredContentType; + } + this.ShowContentTypes.Value = num > 1; + } + + private static void ShowContentTypesAll(object sender, EventArgs args) + { + if (!(ZuneShell.DefaultInstance.CurrentPage is LibraryPage currentPage)) + return; + currentPage.DrmStateMask = DrmStateMask.All(); + SQMLog.Log(SQMDataId.LibraryContentTypeAllClicks, 1); + } + + private static void ShowContentTypesPersonal(object sender, EventArgs args) + { + if (!(ZuneShell.DefaultInstance.CurrentPage is LibraryPage currentPage)) + return; + currentPage.DrmStateMask = DrmStateMask.Personal(); + SQMLog.Log(SQMDataId.LibraryContentTypePersonalClicks, 1); + } + + private static void ShowContentTypesProtected(object sender, EventArgs args) + { + if (!(ZuneShell.DefaultInstance.CurrentPage is LibraryPage currentPage)) + return; + currentPage.DrmStateMask = DrmStateMask.Protected(); + SQMLog.Log(SQMDataId.LibraryContentTypeProtectedClicks, 1); + } + + private static void ShowContentTypesZunePass(object sender, EventArgs args) + { + if (!(ZuneShell.DefaultInstance.CurrentPage is LibraryPage currentPage)) + return; + currentPage.DrmStateMask = DrmStateMask.ZunePass(); + SQMLog.Log(SQMDataId.LibraryContentTypeZunePassClicks, 1); + } + + private void ShowArtistPivot(object sender, EventArgs args) + { + this.View = MusicLibraryView.Artist; + SQMLog.Log(SQMDataId.ArtistViewClicks, 1); + ViewTimeLogger.Instance.ViewChanged(SQMDataId.ArtistViewTime); + } + + private void ShowGenrePivot(object sender, EventArgs args) + { + this.View = MusicLibraryView.Genre; + SQMLog.Log(SQMDataId.GenreViewClicks, 1); + ViewTimeLogger.Instance.ViewChanged(SQMDataId.GenreViewTime); + } + + private void ShowAlbumPivot(object sender, EventArgs args) + { + this.View = MusicLibraryView.Album; + SQMLog.Log(SQMDataId.AlbumViewClicks, 1); + ViewTimeLogger.Instance.ViewChanged(SQMDataId.AlbumViewTime); + } + + private void ShowSongPivot(object sender, EventArgs args) + { + this.View = MusicLibraryView.Song; + SQMLog.Log(SQMDataId.SongViewClicks, 1); + ViewTimeLogger.Instance.ViewChanged(SQMDataId.SongViewTime); + } + + private void ShowPlaylistPivot(object sender, EventArgs args) + { + this.View = MusicLibraryView.Playlist; + SQMLog.Log(SQMDataId.PlaylistViewClicks, 1); + ViewTimeLogger.Instance.ViewChanged(SQMDataId.PlaylistViewTime); + } + + protected override void OnNavigatedToWorker() + { + if (!this.ShowDeviceContents) + this.ContentTypes.ChosenChanged += new EventHandler(this.ContentTypesChanged); + if (this.NavigationArguments != null) + { + MusicLibraryPage._preferredContentType = MusicLibraryPage._showContentTypesAll; + this.DrmStateMask = DrmStateMask.All(); + if (this.NavigationArguments.Contains((object)"ViewOverrideId")) + { + MusicLibraryView navigationArgument = (MusicLibraryView)this.NavigationArguments[(object)"ViewOverrideId"]; + for (int index = 0; index < this.Views.Options.Count; ++index) + { + if (((MusicLibraryPage.ViewCommand)this.Views.Options[index]).View == navigationArgument) + { + bool updatePreferredView = this._updatePreferredView; + this._updatePreferredView = false; + this.Views.ChosenIndex = index; + this._updatePreferredView = updatePreferredView; + break; + } + } + } + this._selectedArtistIds = (IList)null; + if (this.NavigationArguments.Contains((object)"ArtistLibraryId")) + this._selectedArtistIds = (IList)new int[1] + { + (int) this.NavigationArguments[(object) "ArtistLibraryId"] + }; + this._selectedGenreIds = (IList)null; + if (this.NavigationArguments.Contains((object)"GenreLibraryId")) + this._selectedGenreIds = (IList)new int[1] + { + (int) this.NavigationArguments[(object) "GenreLibraryId"] + }; + this._selectedAlbumIds = (IList)null; + if (this.NavigationArguments.Contains((object)"AlbumLibraryId")) + this._selectedAlbumIds = (IList)new int[1] + { + (int) this.NavigationArguments[(object) "AlbumLibraryId"] + }; + this._selectedTrackIds = (IList)null; + if (this.NavigationArguments.Contains((object)"TrackLibraryId")) + this._selectedTrackIds = (IList)new int[1] + { + (int) this.NavigationArguments[(object) "TrackLibraryId"] + }; + if (this.NavigationArguments.Contains((object)"PlaylistLibraryId")) + { + this.PlaylistsPanel.SelectedLibraryIds = (IList)new int[1] + { + (int) this.NavigationArguments[(object) "PlaylistLibraryId"] + }; + this.PlaylistContentsPanel.SelectedLibraryIds = this._selectedTrackIds; + } + this.NavigationArguments = (IDictionary)null; + } + this.UpdateContentTypesPivots(); + base.OnNavigatedToWorker(); + } + + protected override void OnNavigatedAwayWorker(IPage destination) + { + ViewTimeLogger.Instance.ViewChanged(SQMDataId.Invalid); + base.OnNavigatedAwayWorker(destination); + this.SelectedPlaylist = (object)null; + if (!this.ShowDeviceContents) + this.ContentTypes.ChosenChanged -= new EventHandler(this.ContentTypesChanged); + PlaylistManager.Instance.ValidateDefaultPlaylist(); + } + + public override IPageState SaveAndRelease() + { + if (this._artistsPanel != null) + this._artistsPanel.Release(); + if (this._genresPanel != null) + this._genresPanel.Release(); + if (this._albumsPanel != null) + this._albumsPanel.Release(); + if (this._tracksPanel != null) + this._tracksPanel.Release(); + if (this._playlistsPanel != null) + this._playlistsPanel.Release(); + if (this._playlistContentsPanel != null) + this._playlistContentsPanel.Release(); + return base.SaveAndRelease(); + } + + public static void FindInCollection(int artistId, int albumId, int trackId) => MusicLibraryPage.FindInCollection(artistId, albumId, trackId, true); + + public static void FindInCollection(int artistId, int albumId, int trackId, bool selectTrack) + { + if (trackId >= 0 && albumId < 0) + albumId = PlaylistManager.GetFieldValue(trackId, EListType.eTrackList, 11, -1); + if (albumId >= 0 && artistId < 0) + artistId = PlaylistManager.GetFieldValue(albumId, EListType.eAlbumList, 78, -1); + Hashtable hashtable = new Hashtable(); + hashtable.Add((object)"AlbumLibraryId", (object)albumId); + hashtable.Add((object)"ArtistLibraryId", (object)artistId); + if (selectTrack) + hashtable.Add((object)"TrackLibraryId", (object)trackId); + hashtable.Add((object)"ViewOverrideId", (object)MusicLibraryView.Artist); + ZuneShell.DefaultInstance.Execute("Collection\\Music\\Default", (IDictionary)hashtable); + } + + public static void FindPlaylistInCollection(int playlistId) => MusicLibraryPage.FindPlaylistInCollection(playlistId, -1, false); + + public static void FindPlaylistInCollection(int playlistId, int trackId, bool selectTrack) + { + Hashtable hashtable = new Hashtable(); + hashtable.Add((object)"PlaylistLibraryId", (object)playlistId); + hashtable.Add((object)"ViewOverrideId", (object)MusicLibraryView.Playlist); + if (selectTrack) + hashtable.Add((object)"TrackLibraryId", (object)trackId); + ZuneShell.DefaultInstance.Execute("Collection\\Music\\Default", (IDictionary)hashtable); + } + + public static Guid GetArtistZuneMediaId(int dbMediaId) => PlaylistManager.GetFieldValue(dbMediaId, EListType.eArtistList, 451, Guid.Empty); + + public static void NavigateToPlaylistLand() + { + if (!(ZuneShell.DefaultInstance.CurrentPage is MusicLibraryPage currentPage)) + { + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)new MusicLibraryPage(false, MusicLibraryView.Playlist)); + } + else + { + Choice views = currentPage.Views; + for (int index = 0; index < views.Options.Count; ++index) + { + if (((MusicLibraryPage.ViewCommand)views.Options[index]).View == MusicLibraryView.Playlist) + { + views.ChosenIndex = index; + break; + } + } + } + } + + private static string LibraryTemplate => "res://ZuneShellResources!MusicLibrary.uix#MusicLibrary"; + + private class ViewCommand : Command + { + private MusicLibraryView _view; + + public ViewCommand( + IModelItemOwner owner, + string description, + EventHandler invokeHandler, + MusicLibraryView view) + : base(owner, description, invokeHandler) + { + this._view = view; + } + + public MusicLibraryView View => this._view; + + protected override void OnInvoked() + { + Microsoft.Zune.PerfTrace.PerfTrace.TraceUICollectionEvent(UICollectionEvent.MusicLibraryViewCommandInvoked, this.Description); + base.OnInvoked(); + } + } + } +} diff --git a/ZuneUI/MusicLibraryView.cs b/ZuneUI/MusicLibraryView.cs new file mode 100644 index 0000000..1d42dc4 --- /dev/null +++ b/ZuneUI/MusicLibraryView.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MusicLibraryView +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum MusicLibraryView + { + Invalid, + Artist, + Genre, + Album, + Song, + Playlist, + } +} diff --git a/ZuneUI/MusicNavigationCommandHandler.cs b/ZuneUI/MusicNavigationCommandHandler.cs new file mode 100644 index 0000000..39c0cd8 --- /dev/null +++ b/ZuneUI/MusicNavigationCommandHandler.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MusicNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class MusicNavigationCommandHandler : DeviceAwareNavigationHandler + { + private MusicLibraryView _view; + + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new MusicLibraryPage(this.ShowDeviceContents, this._view); + + public MusicLibraryView View + { + get => this._view; + set => this._view = value; + } + } +} diff --git a/ZuneUI/MusicSyncRulesView.cs b/ZuneUI/MusicSyncRulesView.cs new file mode 100644 index 0000000..726836c --- /dev/null +++ b/ZuneUI/MusicSyncRulesView.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.MusicSyncRulesView +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal enum MusicSyncRulesView + { + Artist, + Album, + Track, + None, + } +} diff --git a/ZuneUI/NamedIntOption.cs b/ZuneUI/NamedIntOption.cs new file mode 100644 index 0000000..88c1859 --- /dev/null +++ b/ZuneUI/NamedIntOption.cs @@ -0,0 +1,111 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NamedIntOption +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + internal class NamedIntOption : Command + { + private static NamedIntOption[] _keepOptions; + private static NamedIntOption[] _playbackOptions; + private static NamedIntOption[] _syncOptions; + private static NamedIntOption[] _screenGraphicsOptions; + private int _value; + + public NamedIntOption(IModelItemOwner owner, string description, int value) + : base(owner, description, (EventHandler)null) + => this._value = value; + + public int Value => this._value; + + public static void SelectOptionByValue(Choice choice, int value) + { + for (int index = 0; index < choice.Options.Count; ++index) + { + if (((NamedIntOption)choice.Options[index]).Value == value) + { + choice.ChosenIndex = index; + break; + } + } + } + + public static NamedIntOption[] PodcastKeepOptions + { + get + { + if (NamedIntOption._keepOptions == null) + { + string format = Shell.LoadString(StringId.IDS_KEEP_N_OPTION); + NamedIntOption._keepOptions = new NamedIntOption[12] + { + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_KEEP_0_OPTION), 0), + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_KEEP_1_OPTION), 1), + new NamedIntOption((IModelItemOwner) null, string.Format(format, (object) 2), 2), + new NamedIntOption((IModelItemOwner) null, string.Format(format, (object) 3), 3), + new NamedIntOption((IModelItemOwner) null, string.Format(format, (object) 4), 4), + new NamedIntOption((IModelItemOwner) null, string.Format(format, (object) 5), 5), + new NamedIntOption((IModelItemOwner) null, string.Format(format, (object) 6), 6), + new NamedIntOption((IModelItemOwner) null, string.Format(format, (object) 7), 7), + new NamedIntOption((IModelItemOwner) null, string.Format(format, (object) 8), 8), + new NamedIntOption((IModelItemOwner) null, string.Format(format, (object) 9), 9), + new NamedIntOption((IModelItemOwner) null, string.Format(format, (object) 10), 10), + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_KEEP_ALL_OPTION), -1) + }; + } + return NamedIntOption._keepOptions; + } + } + + public static NamedIntOption[] PodcastPlaybackOptions + { + get + { + if (NamedIntOption._playbackOptions == null) + NamedIntOption._playbackOptions = new NamedIntOption[2] + { + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_NEWEST_FIRST_OPTION), 0), + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_OLDEST_FIRST_OPTION), 1) + }; + return NamedIntOption._playbackOptions; + } + } + + public static NamedIntOption[] PodcastSyncOptions + { + get + { + if (NamedIntOption._syncOptions == null) + NamedIntOption._syncOptions = new NamedIntOption[4] + { + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_SYNC_UNPLAYED_OPTION), 2), + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_SYNC_ALL_DOWNLOADED_OPTION), 0), + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_SYNC_FIRST_UNPLAYED_OPTION), 3), + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_SYNC_NONE_OPTION), 4) + }; + return NamedIntOption._syncOptions; + } + } + + public static NamedIntOption[] ScreenGraphicsOptions + { + get + { + if (NamedIntOption._screenGraphicsOptions == null) + NamedIntOption._screenGraphicsOptions = new NamedIntOption[4] + { + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_SCREEN_GRAPHICS_BASIC), 0), + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_SCREEN_GRAPHICS_ADVANCED), 1), + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_SCREEN_GRAPHICS_ADVANCED_ANIMATION), 2), + new NamedIntOption((IModelItemOwner) null, Shell.LoadString(StringId.IDS_SCREEN_GRAPHICS_PREMIUM), 3) + }; + return NamedIntOption._screenGraphicsOptions; + } + } + } +} diff --git a/ZuneUI/NamedStringOption.cs b/ZuneUI/NamedStringOption.cs new file mode 100644 index 0000000..2d07ba4 --- /dev/null +++ b/ZuneUI/NamedStringOption.cs @@ -0,0 +1,36 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NamedStringOption +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class NamedStringOption : Command + { + private string _value; + + public NamedStringOption() + { + } + + public NamedStringOption(string description, string value) + : base((IModelItemOwner)null, description, (EventHandler)null) + => this._value = value; + + public string Value + { + get => this._value; + set + { + if (!(this._value != value)) + return; + this._value = value; + this.FirePropertyChanged(nameof(Value)); + } + } + } +} diff --git a/ZuneUI/NavErrorData.cs b/ZuneUI/NavErrorData.cs new file mode 100644 index 0000000..6889d08 --- /dev/null +++ b/ZuneUI/NavErrorData.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NavErrorData +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class NavErrorData : IEquatable + { + public string FailureUrl { get; private set; } + + public int ErrorCode { get; private set; } + + public NavErrorData(string failureUrl, int errorCode) + { + this.FailureUrl = failureUrl; + this.ErrorCode = errorCode; + } + + public bool Equals(NavErrorData other) => this.ErrorCode == other.ErrorCode && string.Compare(this.FailureUrl, other.FailureUrl, false) == 0; + + private NavErrorData() + { + } + } +} diff --git a/ZuneUI/NavigateHandler.cs b/ZuneUI/NavigateHandler.cs new file mode 100644 index 0000000..993ed9e --- /dev/null +++ b/ZuneUI/NavigateHandler.cs @@ -0,0 +1,10 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NavigateHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public delegate void NavigateHandler(Shell shell); +} diff --git a/ZuneUI/NavigateToInstanceCommandHandler.cs b/ZuneUI/NavigateToInstanceCommandHandler.cs new file mode 100644 index 0000000..80f255d --- /dev/null +++ b/ZuneUI/NavigateToInstanceCommandHandler.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NavigateToInstanceCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class NavigateToInstanceCommandHandler : NavigationCommandHandlerBase + { + private ZunePage _page; + + public ZunePage Page + { + get => this._page; + set => this._page = value; + } + + protected override ZunePage GetPage(IDictionary args) => this._page; + } +} diff --git a/ZuneUI/NavigationCommandHandler.cs b/ZuneUI/NavigationCommandHandler.cs new file mode 100644 index 0000000..92d6642 --- /dev/null +++ b/ZuneUI/NavigationCommandHandler.cs @@ -0,0 +1,59 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class NavigationCommandHandler : NavigationCommandHandlerBase + { + private string _pageUI; + private string _backgroundUI; + private Node _pivotPreference; + private bool _isRootPage; + private PlaybackContext _playbackContext; + + public string UI + { + get => this._pageUI; + set => this._pageUI = value; + } + + public string BackgroundUI + { + get => this._backgroundUI; + set => this._backgroundUI = value; + } + + public Node PivotPreference + { + get => this._pivotPreference; + set => this._pivotPreference = value; + } + + public bool IsRootPage + { + get => this._isRootPage; + set => this._isRootPage = value; + } + + public PlaybackContext PlaybackContext + { + get => this._playbackContext; + set => this._playbackContext = value; + } + + protected override ZunePage GetPage(IDictionary args) => new ZunePage() + { + UI = this.UI, + UIPath = this.UIPath, + BackgroundUI = this.BackgroundUI, + PivotPreference = this.PivotPreference, + IsRootPage = this.IsRootPage, + PlaybackContext = this.PlaybackContext + }; + } +} diff --git a/ZuneUI/NavigationCommandHandlerBase.cs b/ZuneUI/NavigationCommandHandlerBase.cs new file mode 100644 index 0000000..bb86bf3 --- /dev/null +++ b/ZuneUI/NavigationCommandHandlerBase.cs @@ -0,0 +1,40 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NavigationCommandHandlerBase +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + public abstract class NavigationCommandHandlerBase : ICommandHandler + { + protected string _pageUIPath; + + public string UIPath + { + get => this._pageUIPath; + set => this._pageUIPath = value; + } + + protected abstract ZunePage GetPage(IDictionary args); + + public void Execute(string command, IDictionary commandArgs) + { + ZuneShell defaultInstance = ZuneShell.DefaultInstance; + if (defaultInstance == null) + throw new InvalidOperationException("No Shell instance has been registered. Unable to perform navigation."); + if (!Shell.IsUIPathEnabled(this.UIPath)) + return; + ZunePage page = this.GetPage(commandArgs); + if (commandArgs != null) + page.NavigationArguments = commandArgs; + page.NavigationCommand = command; + if (this.UIPath != null) + page.UIPath = this.UIPath; + defaultInstance.NavigateToPage(page); + } + } +} diff --git a/ZuneUI/NavigationDirection.cs b/ZuneUI/NavigationDirection.cs new file mode 100644 index 0000000..d5ebcb7 --- /dev/null +++ b/ZuneUI/NavigationDirection.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NavigationDirection +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum NavigationDirection + { + Forward, + Back, + } +} diff --git a/ZuneUI/NetworkSignInCredentials.cs b/ZuneUI/NetworkSignInCredentials.cs new file mode 100644 index 0000000..7f921e6 --- /dev/null +++ b/ZuneUI/NetworkSignInCredentials.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NetworkSignInCredentials +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Threading; + +namespace ZuneUI +{ + public abstract class NetworkSignInCredentials : IDisposable + { + protected EventWaitHandle _dialogClosed; + protected bool _completed; + protected uint _cancelCount; + protected uint _signInCount; + + protected NetworkSignInCredentials() => this._cancelCount = 0U; + + public virtual void Dispose() + { + if (this._dialogClosed == null) + return; + this._dialogClosed.Close(); + } + + public abstract void Phase2Init(); + + protected virtual void OnDialogSignIn(object sender, EventArgs args) + { + if (this._dialogClosed != null) + this._dialogClosed.Set(); + ++this._signInCount; + this._completed = true; + } + + protected virtual void OnDialogCanceled(object sender, EventArgs args) + { + if (this._dialogClosed != null) + this._dialogClosed.Set(); + ++this._cancelCount; + this._completed = false; + } + + protected uint CancelCount => this._cancelCount; + + protected uint SignInCount => this._signInCount; + } +} diff --git a/ZuneUI/NetworkSignInDialogHelper.cs b/ZuneUI/NetworkSignInDialogHelper.cs new file mode 100644 index 0000000..58ff59b --- /dev/null +++ b/ZuneUI/NetworkSignInDialogHelper.cs @@ -0,0 +1,106 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NetworkSignInDialogHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.ErrorMapperApi; +using System; +using System.Net; +using UIXControls; + +namespace ZuneUI +{ + public abstract class NetworkSignInDialogHelper : DialogHelper + { + private string _helpUrl; + protected string _error; + protected string _title; + protected string _warning; + protected string _hostName; + protected string _realmName; + protected Command _signInCommand; + protected BooleanChoice _rememberPassword; + + public NetworkSignInDialogHelper( + EventHandler signInHandler, + EventHandler cancelHandler, + string contentUI) + : base(contentUI) + { + this._signInCommand = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_DIALOG_OK), new EventHandler(this.OnInvoked)); + if (signInHandler != null) + this._signInCommand.Invoked += signInHandler; + if (cancelHandler != null) + this.Cancel.Invoked += cancelHandler; + this._rememberPassword = new BooleanChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_PODCAST_SIGN_IN_SAVE)); + } + + public string Title => this._title; + + public Command SignIn => this._signInCommand; + + public string Error => this._error; + + public string HelpUrl => this._helpUrl; + + public string Warning => this._warning; + + public string RealmName => this._realmName; + + public string HostName => this._hostName; + + public BooleanChoice RememberPassword => this._rememberPassword; + + public abstract string UserName { get; set; } + + public abstract string Password { get; set; } + + protected virtual void OnInvoked(object sender, EventArgs args) => this.Hide(); + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing) + return; + if (this._rememberPassword != null) + { + this._rememberPassword.Dispose(); + this._rememberPassword = (BooleanChoice)null; + } + if (this._signInCommand == null) + return; + this._signInCommand.Dispose(); + this._signInCommand = (Command)null; + } + + protected void SetError(HRESULT hrError) + { + if (!hrError.IsError) + return; + ErrorMapperResult descriptionAndUrl = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hrError.Int); + if (descriptionAndUrl == null) + return; + this._error = descriptionAndUrl.Description; + this._helpUrl = descriptionAndUrl.WebHelpUrl; + } + + protected string AuthSchemeToString(AuthenticationSchemes authScheme) + { + switch (authScheme) + { + case AuthenticationSchemes.Digest: + return Shell.LoadString(StringId.IDS_PODCAST_SIGN_IN_DIGEST_AUTH); + case AuthenticationSchemes.Negotiate: + return Shell.LoadString(StringId.IDS_PODCAST_SIGN_IN_NEGOTIATE_AUTH); + case AuthenticationSchemes.Ntlm: + return Shell.LoadString(StringId.IDS_PODCAST_SIGN_IN_NTLM_AUTH); + case AuthenticationSchemes.Basic: + return Shell.LoadString(StringId.IDS_PODCAST_SIGN_IN_BASIC_AUTH); + default: + return (string)null; + } + } + } +} diff --git a/ZuneUI/NewComplexSyncGroup.cs b/ZuneUI/NewComplexSyncGroup.cs new file mode 100644 index 0000000..e2f174f --- /dev/null +++ b/ZuneUI/NewComplexSyncGroup.cs @@ -0,0 +1,85 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NewComplexSyncGroup +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class NewComplexSyncGroup : SyncGroup + { + private string _title; + private int _id; + private bool _isActive; + private SyncCategory _type; + + public NewComplexSyncGroup(SyncGroupList parentList, int id) + : base(parentList) + { + this._id = id; + this._isActive = true; + this.UpdateInfo(); + } + + public override string Title => this._title; + + public override int ID => this._id; + + public override SyncCategory Type => this._type; + + public override long Size => -1; + + public override int Count => -1; + + public override SyncGroupState State => SyncGroupState.Pending; + + public override bool IsActive + { + get => this._isActive; + set + { + if (this._isActive == value) + return; + this._isActive = value; + this.FirePropertyChanged(nameof(IsActive)); + } + } + + public override bool IsVisible => true; + + public override bool IsComplex => true; + + public override void CommitChanges() + { + if (this.IsActive) + this.ParentList.Device.AddSyncRule((IList)new MediaIdAndType[1] + { + new MediaIdAndType(this.ID, MediaType.Playlist) + }); + else + this.CancelChanges(); + } + + public override void CancelChanges() => Shell.DeleteMedia((IList)new List(1) + { + new MediaIdAndType(this.ID, MediaType.Playlist) + }, false); + + public override void DataUpdated() + { + } + + public override void DataEdited() => this.UpdateInfo(); + + private void UpdateInfo() + { + this._title = PlaylistManager.GetPlaylistName(this.ID); + this.FirePropertyChanged("Title"); + this._type = UIDeviceList.MapMediaTypeToSyncCategory(PlaylistManager.GetAutoPlaylistSchema(this.ID)); + this.FirePropertyChanged("Type"); + } + } +} diff --git a/ZuneUI/NewReview.cs b/ZuneUI/NewReview.cs new file mode 100644 index 0000000..aae3e72 --- /dev/null +++ b/ZuneUI/NewReview.cs @@ -0,0 +1,79 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NewReview +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class NewReview : NotifyPropertyChangedImpl + { + private DateTime _date; + private string _userName; + private string _comment; + private string _title; + private float _rating; + + public DateTime Date + { + get => this._date; + set + { + if (!(this._date != value)) + return; + this._date = value; + this.FirePropertyChanged(nameof(Date)); + } + } + + public string UserName + { + get => this._userName; + set + { + if (!(this._userName != value)) + return; + this._userName = value; + this.FirePropertyChanged(nameof(UserName)); + } + } + + public string Comment + { + get => this._comment; + set + { + if (!(this._comment != value)) + return; + this._comment = value; + this.FirePropertyChanged(nameof(Comment)); + } + } + + public string Title + { + get => this._title; + set + { + if (!(this._title != value)) + return; + this._title = value; + this.FirePropertyChanged(nameof(Title)); + } + } + + public float Rating + { + get => this._rating; + set + { + if ((double)this._rating == (double)value) + return; + this._rating = value; + this.FirePropertyChanged(nameof(Rating)); + } + } + } +} diff --git a/ZuneUI/NewletterSettingsWizard.cs b/ZuneUI/NewletterSettingsWizard.cs new file mode 100644 index 0000000..9da8c1f --- /dev/null +++ b/ZuneUI/NewletterSettingsWizard.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NewletterSettingsWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class NewletterSettingsWizard : AccountManagementWizard + { + private AccountManagementFinishStep _finishStep; + private AccountManagementErrorPage _errorStep; + private EditPrivacyInfoStep _editPrivacyInfoStep; + + public NewletterSettingsWizard() + { + this._editPrivacyInfoStep = new EditPrivacyInfoStep((Wizard)this, this.State, false, PrivacyInfoSettings.AllowMicrosoftCommunications); + this._finishStep = new AccountManagementFinishStep((Wizard)this, this.State, Shell.LoadString(StringId.IDS_ACCOUNT_FINISHED_DESCRIPTION), this.State.PrivacyInfoStep.DetailDescription); + this._errorStep = new AccountManagementErrorPage((Wizard)this, Shell.LoadString(StringId.IDS_ACCOUNT_NEWSLTR_UPDATE_ERROR_TITLE), Shell.LoadString(StringId.IDS_ACCOUNT_NEWSLTR_UPDATE_ERROR_DESC)); + this.AddPage((WizardPage)this._editPrivacyInfoStep); + this.AddPage((WizardPage)this._finishStep); + this.AddPage((WizardPage)this._errorStep); + } + + protected override void OnAsyncCommitCompleted(bool success) + { + base.OnAsyncCommitCompleted(success); + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_ACCOUNT_NEWSLTR_UPDATE_SUCCESS_DESC); + } + } +} diff --git a/ZuneUI/NoStackPage.cs b/ZuneUI/NoStackPage.cs new file mode 100644 index 0000000..f38b217 --- /dev/null +++ b/ZuneUI/NoStackPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NoStackPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class NoStackPage : ZunePage + { + public override IPageState SaveAndRelease() + { + this.Release(); + return (IPageState)null; + } + } +} diff --git a/ZuneUI/Node.cs b/ZuneUI/Node.cs new file mode 100644 index 0000000..6435de0 --- /dev/null +++ b/ZuneUI/Node.cs @@ -0,0 +1,101 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Node +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public class Node : Command + { + private bool _isCurrent; + private bool _pendingNavigation; + private string _command; + private SQMDataId _sqmCountID; + + public Node(Experience owner, string command, SQMDataId sqmCountID) + : base((IModelItemOwner)owner, (string)null, (EventHandler)null) + { + this._command = command; + this._sqmCountID = sqmCountID; + } + + public Node(Experience owner, StringId id, string command, SQMDataId sqmCountID) + : base((IModelItemOwner)owner, Shell.LoadString(id), (EventHandler)null) + { + this._command = command; + this._sqmCountID = sqmCountID; + } + + public Node(Experience owner, string name, string command) + : base((IModelItemOwner)owner, name, (EventHandler)null) + { + this._command = command; + this._sqmCountID = SQMDataId.Invalid; + } + + public Experience Experience => (Experience)this.Owner; + + public bool IsCurrent + { + get => this._isCurrent; + set + { + if (this._isCurrent == value) + return; + this._isCurrent = value; + this.OnIsCurrentChanged(); + this.FirePropertyChanged(nameof(IsCurrent)); + } + } + + protected virtual void OnIsCurrentChanged() + { + } + + protected override void OnInvoked() + { + Shell defaultInstance = (Shell)ZuneShell.DefaultInstance; + if (defaultInstance.NavigationLocked) + { + defaultInstance.BlockedByNavigationLock = true; + defaultInstance.DeferredNavigateNode = this; + } + else + { + bool flag = defaultInstance.CurrentNode == this; + bool isRootPage = defaultInstance.CurrentPage.IsRootPage; + if (!this._pendingNavigation) + { + if (!flag || !isRootPage) + { + defaultInstance.PropertyChanged += new PropertyChangedEventHandler(this.ShellPropertyChanged); + this.Execute(defaultInstance); + this._pendingNavigation = true; + if (this._sqmCountID != SQMDataId.Invalid) + SQMLog.Log(this._sqmCountID, 1); + } + else + defaultInstance.CurrentPage.RefreshPage(); + } + base.OnInvoked(); + } + } + + protected virtual void Execute(Shell shell) => shell.Execute(this._command, (IDictionary)null); + + private void ShellPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "CurrentPage")) + return; + this._pendingNavigation = false; + ZuneShell.DefaultInstance.PropertyChanged -= new PropertyChangedEventHandler(this.ShellPropertyChanged); + } + } +} diff --git a/ZuneUI/NonBlankPropertyDescriptor.cs b/ZuneUI/NonBlankPropertyDescriptor.cs new file mode 100644 index 0000000..ca0417e --- /dev/null +++ b/ZuneUI/NonBlankPropertyDescriptor.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NonBlankPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class NonBlankPropertyDescriptor : PropertyDescriptor + { + private int _minLength = 1; + + public NonBlankPropertyDescriptor(string name, string multiValueString, string unknownString) + : this(name, multiValueString, unknownString, 1) + { + } + + public NonBlankPropertyDescriptor( + string name, + string multiValueString, + string unknownString, + int minLength) + : this(name, multiValueString, unknownString, minLength, false) + { + } + + public NonBlankPropertyDescriptor( + string name, + string multiValueString, + string unknownString, + int minLength, + bool required) + : base(name, multiValueString, unknownString, required) + { + this._minLength = minLength; + } + + public override bool IsValidInternal(string value) => value != null && value.Length >= this._minLength; + + public int MinLength + { + set => this._minLength = value; + } + } +} diff --git a/ZuneUI/Notification.cs b/ZuneUI/Notification.cs new file mode 100644 index 0000000..3b80670 --- /dev/null +++ b/ZuneUI/Notification.cs @@ -0,0 +1,75 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Notification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class Notification : ModelItem + { + private NotificationTask _task; + private NotificationState _type; + private uint _appearances; + private int _displayTime; + + public Notification(NotificationTask taskType, NotificationState notificationType) + : this(taskType, notificationType, 0) + { + } + + public Notification( + NotificationTask taskType, + NotificationState notificationType, + int displayTime) + : base((IModelItemOwner)null) + { + this._task = taskType; + this._type = notificationType; + this._appearances = 0U; + this._displayTime = displayTime <= 0 ? 5000 : displayTime; + } + + public NotificationTask Task + { + get => this._task; + set + { + if (this._task == value) + return; + this._task = value; + this.FirePropertyChanged(nameof(Task)); + } + } + + public NotificationState Type + { + get => this._type; + set + { + if (this._type == value) + return; + this._type = value; + this.FirePropertyChanged(nameof(Type)); + } + } + + public uint Appearances => this._appearances; + + public int DisplayTime => this._displayTime; + + public void IncrementDisplayCount() + { + if (this._type == NotificationState.OneShot) + NotificationArea.Instance.Remove(this); + if (this._type != NotificationState.Completed) + return; + ++this._appearances; + if (this._appearances < 5U) + return; + NotificationArea.Instance.Remove(this); + } + } +} diff --git a/ZuneUI/NotificationArea.cs b/ZuneUI/NotificationArea.cs new file mode 100644 index 0000000..6ff39d2 --- /dev/null +++ b/ZuneUI/NotificationArea.cs @@ -0,0 +1,248 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NotificationArea +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class NotificationArea : ModelItem + { + private bool _paused; + private List _notificationList; + private Notification _currentNotification; + private Notification _overrideNotification; + private Timer _timer; + private static NotificationArea _singletonInstance; + + private NotificationArea(IModelItemOwner owner) + : base(owner) + => this._notificationList = new List(); + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + if (this._timer != null) + this._timer.Tick -= new EventHandler(this.OnTick); + for (int index = 0; index < this._notificationList.Count; ++index) + { + if (this._notificationList[index] != null) + this._notificationList[index].Dispose(); + } + this._currentNotification = (Notification)null; + if (this._overrideNotification != null) + { + this._overrideNotification.Dispose(); + this._overrideNotification = (Notification)null; + } + } + base.OnDispose(disposing); + NotificationArea._singletonInstance = (NotificationArea)null; + } + + public static NotificationArea Instance + { + get + { + if (NotificationArea._singletonInstance == null) + NotificationArea._singletonInstance = new NotificationArea((IModelItemOwner)ZuneShell.DefaultInstance); + return NotificationArea._singletonInstance; + } + } + + public Notification CurrentNotification + { + private set + { + if (this._currentNotification == value) + return; + this._currentNotification = value; + if (this._currentNotification != null) + this.TickTimer.Interval = this._currentNotification.DisplayTime; + if (this._overrideNotification != null) + return; + this.FirePropertyChanged(nameof(CurrentNotification)); + } + get => this._overrideNotification != null ? this._overrideNotification : this._currentNotification; + } + + public bool NotificationsReady => this._notificationList.Count > 0; + + public int NotificationCount => this._notificationList.Count; + + private Timer TickTimer + { + get + { + if (this._timer == null) + { + this._timer = new Timer((IModelItemOwner)this, "Notification Area Change Timer"); + this._timer.Interval = 600000; + this._timer.AutoRepeat = true; + this._timer.Tick += new EventHandler(this.OnTick); + } + return this._timer; + } + } + + public void Add(Notification notification) + { + if (notification == null || this._notificationList.Contains(notification)) + return; + if (!this.NotificationsReady) + { + this._notificationList.Add(notification); + if (!this.Paused) + this.TickTimer.Start(); + } + else + { + int index = this._notificationList.IndexOf(this._currentNotification); + if (index >= 0 && index < this._notificationList.Count) + this._notificationList.Insert(index, notification); + else + this._notificationList.Add(notification); + } + this.FirePropertyChanged("NotificationCount"); + if (this.Paused && this.CurrentNotification != null) + return; + this.CurrentNotification = notification; + } + + public void Override(Notification notification) + { + if (this._overrideNotification == notification) + return; + if (this._overrideNotification != null) + this._overrideNotification.Dispose(); + this._overrideNotification = notification; + this.FirePropertyChanged("CurrentNotification"); + if (!this.TickTimer.Enabled) + return; + this.TickTimer.Stop(); + } + + public void EndOverride(Notification notification) + { + if (notification == null || this._overrideNotification != notification) + return; + this.Override((Notification)null); + if (!this.NotificationsReady) + return; + this.TickTimer.Start(); + } + + public void ClearAll() + { + this.TickTimer.Stop(); + this._notificationList.Clear(); + this.CurrentNotification = (Notification)null; + } + + public void RemoveAll(NotificationTask taskType, NotificationState notificationType) + { + for (int index = this._notificationList.Count - 1; index >= 0; --index) + { + if (this._notificationList[index].Task == taskType && this._notificationList[index].Type == notificationType) + { + if (this._notificationList[index] == this._currentNotification) + this.IncrementNotification(); + this._notificationList[index].Dispose(); + this._notificationList.RemoveAt(index); + if (!this.NotificationsReady) + { + this.CurrentNotification = (Notification)null; + this.TickTimer.Stop(); + } + } + } + } + + public void Remove(Notification notification) + { + if (notification == null || notification.IsDisposed) + return; + if (notification == this._currentNotification) + this.IncrementNotification(); + if (this._notificationList.Remove(notification)) + notification.Dispose(); + if (this.NotificationsReady) + return; + this.CurrentNotification = (Notification)null; + this.TickTimer.Stop(); + } + + public void Replace(Notification oldNotification, Notification newNotification) + { + if (oldNotification == null || newNotification == null || (oldNotification.IsDisposed || newNotification.IsDisposed)) + return; + int index = this._notificationList.IndexOf(oldNotification); + if (index < 0) + return; + this._notificationList.RemoveAt(index); + this._notificationList.Insert(index, newNotification); + if (oldNotification == this._currentNotification) + this.CurrentNotification = newNotification; + oldNotification.Dispose(); + } + + public void ForceToFront(Notification notification) + { + if (this._notificationList.IndexOf(notification) < 0) + return; + if (notification == this._currentNotification) + { + this.TickTimer.Stop(); + this.TickTimer.Interval = this._currentNotification.DisplayTime; + this.TickTimer.Start(); + } + else + this.CurrentNotification = notification; + } + + public bool Paused + { + get => this._paused; + set + { + if (this._paused == value) + return; + this._paused = value; + if (this._paused) + { + this.TickTimer.Enabled = false; + } + else + { + if (!this.NotificationsReady) + return; + this.TickTimer.Enabled = true; + } + } + } + + private void OnTick(object sender, EventArgs args) + { + if (this._currentNotification == null) + return; + Notification currentNotification = this._currentNotification; + this.IncrementNotification(); + currentNotification.IncrementDisplayCount(); + } + + public void IncrementNotification() + { + int index = this._notificationList.IndexOf(this._currentNotification) + 1; + if (index >= this._notificationList.Count) + index = 0; + if (index < 0 || index >= this._notificationList.Count) + return; + this.CurrentNotification = this._notificationList[index]; + } + } +} diff --git a/ZuneUI/NotificationState.cs b/ZuneUI/NotificationState.cs new file mode 100644 index 0000000..f1a896b --- /dev/null +++ b/ZuneUI/NotificationState.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NotificationState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum NotificationState + { + Normal, + Completed, + Error, + OneShot, + } +} diff --git a/ZuneUI/NotificationTask.cs b/ZuneUI/NotificationTask.cs new file mode 100644 index 0000000..ef44adb --- /dev/null +++ b/ZuneUI/NotificationTask.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NotificationTask +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum NotificationTask + { + Sync, + Burn, + Download, + Rip, + Library, + EditPlaylist, + Podcast, + NowPlaying, + Messaging, + QuickMix, + PreparingPlay, + } +} diff --git a/ZuneUI/NotifyChoice.cs b/ZuneUI/NotifyChoice.cs new file mode 100644 index 0000000..d612110 --- /dev/null +++ b/ZuneUI/NotifyChoice.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NotifyChoice +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class NotifyChoice : Choice + { + private InvokePolicy _invokePolicy; + + public NotifyChoice() + : this((IModelItemOwner)null) + { + } + + public NotifyChoice(IModelItemOwner owner) + : this(owner, InvokePolicy.Synchronous) + { + } + + public NotifyChoice(IModelItemOwner owner, InvokePolicy invokePolicy) + : base(owner) + => this._invokePolicy = invokePolicy; + + protected override void OnChosenChanged() + { + if (this.ChosenValue == null) + return; + ((Command)this.ChosenValue).Invoke(this._invokePolicy); + } + + protected override void ValidateOptionsListWorker(IList potentialOptions) + { + base.ValidateOptionsListWorker(potentialOptions); + if (potentialOptions == null) + return; + foreach (object potentialOption in (IEnumerable)potentialOptions) + { + if (!(potentialOption is Command)) + throw new ArgumentException("Contents must be of type Command"); + } + } + } +} diff --git a/ZuneUI/NotifyPropertyChangedImpl.cs b/ZuneUI/NotifyPropertyChangedImpl.cs new file mode 100644 index 0000000..d206cdc --- /dev/null +++ b/ZuneUI/NotifyPropertyChangedImpl.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NotifyPropertyChangedImpl +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.ComponentModel; + +namespace ZuneUI +{ + public class NotifyPropertyChangedImpl : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void FirePropertyChanged(string propertyName) + { + if (this.PropertyChanged == null) + return; + this.PropertyChanged((object)this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/ZuneUI/NotifyStack.cs b/ZuneUI/NotifyStack.cs new file mode 100644 index 0000000..daae183 --- /dev/null +++ b/ZuneUI/NotifyStack.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NotifyStack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class NotifyStack : ArrayListDataSet + { + public void Push(object value) => this.Insert(0, value); + + public object Pop() + { + object obj = this.Peek(); + this.RemoveAt(0); + return obj; + } + + public object Peek() => this[0]; + } +} diff --git a/ZuneUI/NowPlayingLand.cs b/ZuneUI/NowPlayingLand.cs new file mode 100644 index 0000000..9343087 --- /dev/null +++ b/ZuneUI/NowPlayingLand.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NowPlayingLand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class NowPlayingLand : PlaybackPage + { + public NowPlayingLand() + { + this.BackgroundUI = NowPlayingLand.LandBackgroundUI; + this.UIPath = "NowPlaying"; + } + + protected override void OnNavigatedAwayWorker(IPage destination) + { + this.ShouldHandleEscape = false; + base.OnNavigatedAwayWorker(destination); + } + + public static void NavigateToLand() + { + PlaybackTrack currentTrack = SingletonModelItem.Instance.CurrentTrack; + bool exitOnPlaybackStopped = false; + if (currentTrack != null && currentTrack.IsVideo) + exitOnPlaybackStopped = true; + NowPlayingLand.NavigateToLand(false, exitOnPlaybackStopped); + } + + public static void NavigateToLand(bool showMix, bool exitOnPlaybackStopped) + { + if (ZuneShell.DefaultInstance.CurrentPage is NowPlayingLand) + return; + NowPlayingLand nowPlayingLand = new NowPlayingLand(); + nowPlayingLand.ShowMixOnEntry = showMix; + nowPlayingLand.ExitOnPlaybackStopped = exitOnPlaybackStopped; + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)nowPlayingLand); + SQMLog.Log(SQMDataId.NowPlayingClicks, 1); + } + + private static string LandBackgroundUI => "res://ZuneShellResources!NowPlayingLand.uix#NowPlayingBackground"; + } +} diff --git a/ZuneUI/NowPlayingList.cs b/ZuneUI/NowPlayingList.cs new file mode 100644 index 0000000..1167dfc --- /dev/null +++ b/ZuneUI/NowPlayingList.cs @@ -0,0 +1,744 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NowPlayingList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Playlist; +using Microsoft.Zune.QuickMix; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.Serialization; +using UIXControls; +using ZuneXml; + +namespace ZuneUI +{ + [Serializable] + internal class NowPlayingList : IDisposable + { + private const int s_quickMixCreationTimeoutMilliseconds = 15000; + private const int s_nearingCompletionThreshold = 3; + [NonSerialized] + private ArrayListDataSet _tracks; + private List _savedTracks; + private int[] _shuffleOrder; + private bool _shuffling; + private bool _repeating; + private int _indexShuffleStart; + private PlaybackContext _playbackContext; + private int _currentRandomSeed; + private PlayNavigationOptions _playNavigationOptions; + private bool _dontPlayMarketplaceTracks; + private bool _playWhenReady; + private EQuickMixType _quickMixType = EQuickMixType.eQuickMixTypeInvalid; + private string _quickMixTitle; + [NonSerialized] + private int _transientTracksPlaylistId; + [NonSerialized] + private static int _transientPlaylistCount; + [NonSerialized] + private PlaybackTrack _trackCurrent; + [NonSerialized] + private PlaybackTrack _trackNext; + private int _indexCurrent; + [NonSerialized] + private QuickMixSession _quickMixSession; + [NonSerialized] + private QuickMixNotification _quickMixCreatingNotification; + [NonSerialized] + private StringId _quickMixNoResultsStringId; + private static Random s_random = new Random(); + + public NowPlayingList( + IList items, + int startIndex, + PlaybackContext context, + PlayNavigationOptions playNavigationOptions, + bool shuffling, + ContainerPlayMarker containerPlayMarker, + bool dontPlayMarketplaceTracks) + { + this._transientTracksPlaylistId = int.MinValue; + this._playbackContext = context; + this._playNavigationOptions = playNavigationOptions; + this._dontPlayMarketplaceTracks = dontPlayMarketplaceTracks; + if (this._playbackContext == PlaybackContext.QuickMix) + this.AddQuickMixItemsWorker(items); + else + this.AddItemsWorker(items, startIndex, shuffling, containerPlayMarker); + } + + public void Dispose() + { + if (this._quickMixSession != null) + { + this._quickMixSession.Dispose(); + this._quickMixSession = (QuickMixSession)null; + } + this.CleanupTransientTracks(); + } + + private void CleanupTransientTracks() + { + if (this._transientTracksPlaylistId == int.MinValue) + return; + ZuneApplication.ZuneLibrary.DeleteMedia(new int[1] + { + this._transientTracksPlaylistId + }, EMediaTypes.eMediaTypePlaylist, false); + this._transientTracksPlaylistId = int.MinValue; + } + + private void AddQuickMixItemsWorker(IList items) + { + Microsoft.Zune.QuickMix.QuickMix instance = Microsoft.Zune.QuickMix.QuickMix.Instance; + HRESULT hresult = HRESULT._S_OK; + EMediaTypes eMediaType = EMediaTypes.eMediaTypeInvalid; + this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_ITEM_CREATION_UNAVAILABLE_TEXT; + if (this._quickMixSession != null) + { + this._quickMixSession.Dispose(); + this._quickMixSession = (QuickMixSession)null; + } + NotificationArea.Instance.RemoveAll(NotificationTask.QuickMix, NotificationState.OneShot); + if (items[0] is Artist artist) + { + this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_ARTIST_CREATION_UNAVAILABLE_TEXT; + hresult = instance.CreateSession(EQuickMixMode.eQuickMixModeNowPlaying, artist.Id, EMediaTypes.eMediaTypePersonArtist, artist.Title, out this._quickMixSession); + if (hresult.IsSuccess) + { + string text = string.Format(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_ONE_PARAM_TEXT), (object)artist.Title); + this._quickMixCreatingNotification = new QuickMixNotification(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TITLE), text, NotificationState.OneShot, false, 15000); + SQMLog.Log(SQMDataId.QuickMixRadioPlays, 1); + } + } + if (hresult.IsSuccess && items[0] is LibraryDataProviderItemBase providerItemBase) + { + if (providerItemBase.TypeName == "Artist") + { + eMediaType = EMediaTypes.eMediaTypePersonArtist; + this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_ARTIST_CREATION_UNAVAILABLE_TEXT; + string property = (string)providerItemBase.GetProperty("Title"); + string text = string.Format(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_ONE_PARAM_TEXT), (object)property); + this._quickMixCreatingNotification = new QuickMixNotification(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TITLE), text, NotificationState.OneShot, false, 15000); + } + else if (providerItemBase.TypeName == "Album") + { + eMediaType = EMediaTypes.eMediaTypeAudioAlbum; + this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_ALBUM_CREATION_UNAVAILABLE_TEXT; + string property1 = (string)providerItemBase.GetProperty("ArtistName"); + string property2 = (string)providerItemBase.GetProperty("Title"); + string text = string.Format(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TWO_PARAM_TEXT), (object)property1, (object)property2); + this._quickMixCreatingNotification = new QuickMixNotification(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TITLE), text, NotificationState.OneShot, false, 15000); + } + else if (providerItemBase.TypeName == "Track") + { + eMediaType = EMediaTypes.eMediaTypeAudio; + this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_SONG_CREATION_UNAVAILABLE_TEXT; + string property1 = (string)providerItemBase.GetProperty("ArtistName"); + string property2 = (string)providerItemBase.GetProperty("Title"); + string text = string.Format(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TWO_PARAM_TEXT), (object)property1, (object)property2); + this._quickMixCreatingNotification = new QuickMixNotification(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TITLE), text, NotificationState.OneShot, false, 15000); + } + int[] seedMediaIds = new int[1] + { + (int) providerItemBase.GetProperty("LibraryId") + }; + hresult = instance.CreateSession(EQuickMixMode.eQuickMixModeNowPlaying, seedMediaIds, eMediaType, out this._quickMixSession); + SQMLog.Log(SQMDataId.QuickMixLocalPlays, 1); + } + if (hresult.IsSuccess) + { + if (this._quickMixSession != null) + { + hresult = this._quickMixSession.GetSimilarMedia((uint)ClientConfiguration.QuickMix.DefaultPlaylistLength, TimeSpan.FromMilliseconds(15000.0), new SimilarMediaBatchHandler(this.SimilarBatchHandler), new Microsoft.Zune.QuickMix.BatchEndHandler(this.BatchEndHandler)); + this._quickMixType = this._quickMixSession.GetQuickMixType(); + this._quickMixSession.GetPlaylistTitle(out this._quickMixTitle); + } + else + hresult = HRESULT._E_UNEXPECTED; + } + if (hresult.IsSuccess) + { + NotificationArea.Instance.Add((Notification)this._quickMixCreatingNotification); + } + else + { + if (this._quickMixSession != null) + { + this._quickMixSession.Dispose(); + this._quickMixSession = (QuickMixSession)null; + } + if ((HRESULT)hresult.Int == HRESULT._ZUNE_E_QUICKMIX_MEDIA_NOT_FOUND) + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE), ZuneUI.Shell.LoadString(this._quickMixNoResultsStringId), (EventHandler)null); + else + ErrorDialogInfo.Show(hresult.Int, ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE)); + } + } + + private void SimilarBatchHandler(IList itemList) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this._quickMixSession == null) + return; + this.AddItems(itemList, new ContainerPlayMarker() + { + LibraryId = -1, + MediaType = MediaType.Playlist, + PlaylistType = PlaylistType.QuickMix, + PlaylistSubType = (int)this._quickMixSession.GetQuickMixType() + }); + if (!this.PlayWhenReady) + return; + this.PlayWhenReady = false; + SingletonModelItem.Instance.PlayPendingList(); + }, (object)null); + + private void BatchEndHandler(HRESULT hrAsync) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + NotificationArea.Instance.Remove((Notification)this._quickMixCreatingNotification); + this._quickMixCreatingNotification = (QuickMixNotification)null; + if (this._quickMixSession == null || !hrAsync.IsError) + return; + if ((HRESULT)hrAsync.Int == HRESULT._ZUNE_E_QUICKMIX_MEDIA_NOT_FOUND) + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE), ZuneUI.Shell.LoadString(this._quickMixNoResultsStringId), (EventHandler)null); + else + ErrorDialogInfo.Show(hrAsync.Int, ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE)); + }, (object)null); + + public ArrayListDataSet TrackList => this._tracks; + + public int Count => this._tracks == null ? 0 : this._tracks.Count; + + public PlaybackContext PlaybackContext => this._playbackContext; + + public PlayNavigationOptions PlayNavigationOptions + { + get => this._playNavigationOptions; + set => this._playNavigationOptions = value; + } + + public string QuickMixTitle + { + get + { + string playlistTitle = this._quickMixTitle; + if (this._quickMixSession != null) + this._quickMixSession.GetPlaylistTitle(out playlistTitle); + return playlistTitle; + } + } + + public bool DontPlayMarketplaceTracks + { + get => this._dontPlayMarketplaceTracks; + set + { + if (value == this._dontPlayMarketplaceTracks) + return; + this._dontPlayMarketplaceTracks = value; + this.UpdateTracks(); + } + } + + public bool PlayWhenReady + { + get => this._playWhenReady; + set + { + if (value == this._playWhenReady) + return; + this._playWhenReady = value; + } + } + + public QuickMixSession QuickMixSession => this._quickMixSession; + + public EQuickMixType QuickMixType => this._quickMixType; + + public PlaybackTrack CurrentTrack => this._trackCurrent; + + public PlaybackTrack NextTrack => this._trackNext; + + public int ListIndexOfCurrentTrack + { + get + { + int indexCurrent = this._indexCurrent; + if (indexCurrent != -1 && this._shuffling) + indexCurrent = this._shuffleOrder[indexCurrent]; + return indexCurrent; + } + } + + public void SetShuffling(bool shuffling) + { + if (this._quickMixSession != null) + return; + if (this._tracks == null || this._tracks.Count == 0) + { + this._shuffling = shuffling; + } + else + { + if (shuffling == this._shuffling) + return; + int index = !this._shuffling ? this._indexCurrent : this._shuffleOrder[this._indexCurrent]; + if (shuffling) + this.RebuildShuffleOrder(); + else + this._shuffleOrder = (int[])null; + this._indexCurrent = !shuffling ? index : this.FindShuffleIndexFromListIndex(index); + this._shuffling = shuffling; + this.UpdateTracks(); + } + } + + public void SetRepeating(bool repeating) + { + if (this._repeating == repeating) + return; + this._repeating = repeating; + this.UpdateTracks(); + } + + public void SyncCurrentTrackTo(PlaybackTrack track) + { + if (track == this._trackCurrent) + return; + int num; + if (track == this._trackNext) + { + num = this.ComputeNextIndex(NowPlayingList.MovingMode.Advancing); + } + else + { + num = this._tracks.IndexOf((object)track); + if (num != -1 && this._shuffling) + num = this.FindShuffleIndexFromListIndex(num); + } + if (num == -1) + return; + this.MoveToWorker(num, NowPlayingList.MovingMode.Advancing); + } + + public void MoveToTrackIndex(int indexNew) + { + if (this._shuffling) + indexNew = this.FindShuffleIndexFromListIndex(indexNew); + this.MoveToWorker(indexNew, NowPlayingList.MovingMode.Jumping); + } + + public void Advance() => this.MoveToWorker(this.ComputeNextIndex(NowPlayingList.MovingMode.Advancing), NowPlayingList.MovingMode.Advancing); + + public bool CanAdvance => this._trackNext != null; + + public void Retreat() + { + if (this._shuffling && this._repeating && this._indexCurrent == this._indexShuffleStart) + this.RebuildShuffleOrder(new int?(this._currentRandomSeed - 1)); + this.MoveToWorker(this.ComputeNextIndex(NowPlayingList.MovingMode.Retreating), NowPlayingList.MovingMode.Retreating); + } + + public bool CanRetreat => this._repeating || (!this._shuffling ? this._indexCurrent > 0 : this._indexCurrent != this._indexShuffleStart); + + public int AddItems(IList items) => this.AddItems(items, (ContainerPlayMarker)null); + + public int AddItems(IList items, ContainerPlayMarker playMarker) => this.AddItemsWorker(items, -1, false, playMarker); + + public void ResetForReplay() + { + this._indexCurrent = !this._shuffling ? 0 : NowPlayingList.s_random.Next(this._tracks.Count); + if (this._shuffling) + this.RebuildShuffleOrder(); + this.UpdateTracks(); + } + + private void MoveToWorker(int indexNew, NowPlayingList.MovingMode mode) + { + this._indexCurrent = indexNew; + if (this._shuffling) + { + if (mode == NowPlayingList.MovingMode.Advancing && indexNew == this._indexShuffleStart) + this.RebuildShuffleOrder(new int?(this._currentRandomSeed + 1)); + else if (mode == NowPlayingList.MovingMode.Jumping) + this.RebuildShuffleOrder(); + } + this.UpdateTracks(); + if (!this.CanGetMoreQuickMixTracks() || !this.ListNearingCompletion()) + return; + HRESULT similarMedia = this._quickMixSession.GetSimilarMedia((uint)ClientConfiguration.QuickMix.DefaultPlaylistLength, TimeSpan.FromMilliseconds(15000.0), new SimilarMediaBatchHandler(this.SimilarBatchHandler), new Microsoft.Zune.QuickMix.BatchEndHandler(this.BatchEndHandler)); + if (!similarMedia.IsError || (HRESULT)similarMedia.Int == HRESULT._ZUNE_E_QUICKMIX_SESSION_IN_USE) + return; + ErrorDialogInfo.Show(similarMedia.Int, ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE)); + } + + private bool CanGetMoreQuickMixTracks() + { + bool flag = false; + if (this._quickMixSession != null) + flag = this._quickMixSession.GetQuickMixType() != EQuickMixType.eQuickMixTypeRadio || SignIn.Instance.SignedIn; + return flag; + } + + private int ComputeNextIndex(NowPlayingList.MovingMode mode) => this.ComputeNextIndex(mode, this._indexCurrent, true); + + private int ComputeNextIndex(NowPlayingList.MovingMode mode, int fromIndex, bool allowLooping) + { + if (mode != NowPlayingList.MovingMode.Advancing && mode != NowPlayingList.MovingMode.Retreating) + return fromIndex; + int index1; + if (!this._dontPlayMarketplaceTracks) + { + index1 = this.ComputeNextIndexUnfiltered(mode, fromIndex, allowLooping); + } + else + { + index1 = fromIndex; + bool flag = false; + for (int index2 = 0; index2 < this._tracks.Count; ++index2) + { + index1 = this.ComputeNextIndexUnfiltered(mode, index1, allowLooping); + if (index1 != -1) + { + PlaybackTrack playbackTrack = !this._shuffling ? this._tracks[index1] as PlaybackTrack : this._tracks[this._shuffleOrder[index1]] as PlaybackTrack; + if (playbackTrack != null && playbackTrack.IsInVisibleCollection) + { + flag = true; + break; + } + } + else + break; + } + if (!flag) + index1 = -1; + } + return index1; + } + + private int ComputeNextIndexUnfiltered( + NowPlayingList.MovingMode mode, + int indexCurrent, + bool allowLooping) + { + int num = mode != NowPlayingList.MovingMode.Advancing ? indexCurrent - 1 : indexCurrent + 1; + if (this._shuffling) + { + if (num == this._tracks.Count) + num = 0; + else if (num == -1) + num = this._tracks.Count - 1; + if ((mode == NowPlayingList.MovingMode.Advancing && num == this._indexShuffleStart || mode == NowPlayingList.MovingMode.Retreating && num == this._indexShuffleStart - 1) && (!this._repeating || !allowLooping)) + num = -1; + } + else if (num == this._tracks.Count) + num = !this._repeating || !allowLooping ? -1 : 0; + else if (num == -1) + num = !this._repeating || !allowLooping ? -1 : this._tracks.Count - 1; + return num; + } + + private bool ListNearingCompletion() + { + if (this._tracks.Count == 0) + return false; + int fromIndex = this._indexCurrent; + int count = this._tracks.Count; + bool flag = false; + for (int index = 0; index < 3; ++index) + { + fromIndex = this.ComputeNextIndex(NowPlayingList.MovingMode.Advancing, fromIndex, false); + if (fromIndex == -1) + { + flag = true; + break; + } + } + int num = flag ? 1 : 0; + return flag; + } + + internal void UpdateTracks() + { + object obj1 = (object)null; + object obj2 = (object)null; + if (this._tracks != null && this._indexCurrent != -1) + { + obj1 = this._tracks[this._shuffling ? this._shuffleOrder[this._indexCurrent] : this._indexCurrent]; + int nextIndex = this.ComputeNextIndex(NowPlayingList.MovingMode.Advancing); + if (nextIndex != -1) + { + if (this._shuffling) + nextIndex = this._shuffleOrder[nextIndex]; + obj2 = this._tracks[nextIndex]; + } + } + this._trackCurrent = (PlaybackTrack)obj1; + this._trackNext = (PlaybackTrack)obj2; + } + + private int FindShuffleIndexFromListIndex(int index) + { + int num = -1; + for (int index1 = 0; index1 < this._tracks.Count; ++index1) + { + if (this._shuffleOrder[index1] == index) + { + num = index1; + break; + } + } + return num; + } + + private void RebuildShuffleOrder(int? seed) + { + int index1 = !this._shuffling ? this._indexCurrent : this._shuffleOrder[this._indexCurrent]; + if (this._tracks == null) + { + this._shuffleOrder = (int[])null; + } + else + { + if (this._shuffleOrder == null || this._shuffleOrder.Length != this._tracks.Count) + this._shuffleOrder = new int[this._tracks.Count]; + for (int index2 = 0; index2 < this._tracks.Count; ++index2) + this._shuffleOrder[index2] = index2; + this._currentRandomSeed = !seed.HasValue ? (int)DateTime.Now.Ticks : seed.Value; + Random random = new Random(this._currentRandomSeed); + for (int index2 = this._tracks.Count - 1; index2 > 0; --index2) + { + int index3 = random.Next(index2 + 1); + int num = this._shuffleOrder[index3]; + this._shuffleOrder[index3] = this._shuffleOrder[index2]; + this._shuffleOrder[index2] = num; + } + } + this._indexShuffleStart = this.FindShuffleIndexFromListIndex(index1); + if (!this._shuffling) + return; + this._indexCurrent = this._indexShuffleStart; + } + + private void RebuildShuffleOrder() => this.RebuildShuffleOrder(new int?()); + + private int AddItemsWorker( + IList items, + int startIndex, + bool shuffling, + ContainerPlayMarker containerPlayMarker) + { + ArrayListDataSet arrayListDataSet = new ArrayListDataSet(); + if (containerPlayMarker != null && containerPlayMarker.MediaType == MediaType.Playlist && containerPlayMarker.PlaylistType == PlaylistType.QuickMix) + { + this._playbackContext = PlaybackContext.QuickMix; + this._quickMixType = (EQuickMixType)containerPlayMarker.PlaylistSubType; + this._quickMixTitle = PlaylistManager.GetPlaylistName(containerPlayMarker.LibraryId); + SQMLog.Log(SQMDataId.QuickMixPlaylistPlays, 1); + } + else if (items != null && items.Count == 1 && items[0] is LibraryDataProviderItemBase) + { + int mediaId = -1; + EMediaTypes mediaType = EMediaTypes.eMediaTypeInvalid; + (items[0] as LibraryDataProviderItemBase).GetMediaIdAndType(out mediaId, out mediaType); + if (mediaType == EMediaTypes.eMediaTypePlaylist && PlaylistManager.GetPlaylistType(mediaId) == 7) + { + this._playbackContext = PlaybackContext.QuickMix; + this._quickMixType = (EQuickMixType)PlaylistManager.GetSubType(mediaId); + this._quickMixTitle = PlaylistManager.GetPlaylistName(mediaId); + SQMLog.Log(SQMDataId.QuickMixPlaylistPlays, 1); + } + } + PlaylistManager.AddItemsToTrackList(items, (IList)arrayListDataSet, ref startIndex, true, false, false, containerPlayMarker); + if (arrayListDataSet.Count != 0) + { + bool flag1 = false; + if (this._tracks == null) + { + this._tracks = new ArrayListDataSet(); + if (startIndex == -1) + startIndex = !shuffling ? 0 : NowPlayingList.s_random.Next(arrayListDataSet.Count); + flag1 = true; + } + bool flag2 = false; + bool flag3 = false; + if (this._tracks.Count > 0) + { + if (((PlaybackTrack)this._tracks[0]).IsVideo) + flag2 = true; + else + flag3 = true; + } + for (int itemIndex = 0; itemIndex < arrayListDataSet.Count; ++itemIndex) + { + PlaybackTrack playbackTrack = (PlaybackTrack)arrayListDataSet[itemIndex]; + bool flag4 = true; + if (playbackTrack.IsVideo) + { + if (flag2) + flag4 = false; + else if (flag3) + flag4 = false; + else + flag2 = true; + } + else if (flag2) + flag4 = false; + else + flag3 = true; + if (flag4) + this._tracks.Add(arrayListDataSet[itemIndex]); + if (flag1 && itemIndex == startIndex) + this._indexCurrent = this._tracks.Count <= 0 ? 0 : this._tracks.Count - 1; + } + if (this._shuffling) + this.RebuildShuffleOrder(); + if (this._quickMixType != EQuickMixType.eQuickMixTypeInvalid) + this.AddReferencesToRemoteTracks((IList)arrayListDataSet); + } + this.UpdateTracks(); + return arrayListDataSet.Count; + } + + private void AddReferencesToRemoteTracks(IList tracks) + { + if (tracks == null) + return; + if (this._transientTracksPlaylistId == int.MinValue) + { + PlaylistResult playlist = PlaylistManager.Instance.CreatePlaylist("Now Playing Transient Tracks Playlist [" + (object)NowPlayingList._transientPlaylistCount + "]", true); + ++NowPlayingList._transientPlaylistCount; + this._transientTracksPlaylistId = playlist.PlaylistId; + } + List libraryPlaybackTrackList = new List(tracks.Count); + foreach (object track in (IEnumerable)tracks) + { + if (track is LibraryPlaybackTrack libraryPlaybackTrack && !libraryPlaybackTrack.IsInVisibleCollection) + libraryPlaybackTrackList.Add(libraryPlaybackTrack); + } + int playlist1 = (int)PlaylistManager.Instance.AddToPlaylist(this._transientTracksPlaylistId, (IList)libraryPlaybackTrackList, false, false); + } + + public void Reorder(IList indices, int targetIndex) + { + PlaybackTrack currentTrack = this.CurrentTrack; + this._tracks.Reorder(indices, targetIndex); + if (this._shuffling) + this.RebuildShuffleOrder(); + this._indexCurrent = this._tracks.IndexOf((object)currentTrack); + if (this._shuffling) + this._indexCurrent = this.FindShuffleIndexFromListIndex(this._indexCurrent); + this.UpdateTracks(); + } + + public bool Remove(IList indices) + { + bool shuffling = this._shuffling; + this.SetShuffling(false); + int num = this._indexCurrent; + bool flag = false; + for (int index1 = indices.Count - 1; index1 >= 0; --index1) + { + int index2 = (int)indices[index1]; + this._tracks.RemoveAt(index2); + if (num == index2) + flag = true; + else if (num > index2) + --num; + } + if (num >= this._tracks.Count) + num = this._tracks.Count - 1; + this._indexCurrent = num; + this.SetShuffling(shuffling); + this.UpdateTracks(); + return flag; + } + + public IList GetNextTracks(int count) + { + List playbackTrackList = (List)null; + if (this._tracks != null && this._tracks.Count > 0) + { + playbackTrackList = new List(count); + for (int index = 0; index < count; ++index) + { + int itemIndex = this._indexCurrent + index; + if (this._repeating || this._shuffling) + { + while (itemIndex >= this._tracks.Count) + itemIndex -= this._tracks.Count; + } + if (itemIndex >= 0 && (this._shuffling ? (itemIndex != this._indexShuffleStart ? 0 : (index != 0 ? 1 : 0)) : (itemIndex == this._tracks.Count ? 1 : 0)) == 0) + { + if (this._shuffling) + itemIndex = this._shuffleOrder[itemIndex]; + playbackTrackList.Add((PlaybackTrack)this._tracks[itemIndex]); + } + else + break; + } + } + return (IList)playbackTrackList; + } + + [OnSerializing] + internal void PrepareForSerialization(StreamingContext context) + { + if (this._tracks == null) + return; + int num1 = Math.Min(this._indexCurrent + 380, this._tracks.Count); + int num2 = Math.Max(this._indexCurrent - (400 - (num1 - this._indexCurrent)), 0); + this._savedTracks = new List(num1 - num2); + for (int index = num2; index < num1; ++index) + this._savedTracks.Add((PlaybackTrack)this._tracks[!this._shuffling ? index : this._shuffleOrder[index]]); + int num3 = this._indexCurrent - num2; + if (this._shuffling) + { + this._indexCurrent = 0; + this._shuffleOrder[0] = num3; + } + else + this._indexCurrent = num3; + } + + [OnDeserialized] + internal void HandleDeserialization(StreamingContext context) + { + this._transientTracksPlaylistId = int.MinValue; + if (this._savedTracks != null) + { + this._tracks = new ArrayListDataSet(); + foreach (object savedTrack in this._savedTracks) + this._tracks.Add(savedTrack); + this._savedTracks = (List)null; + if (this._shuffling) + this.RebuildShuffleOrder(); + this.UpdateTracks(); + } + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + SingletonModelItem.Instance.Shuffling.Value = this._shuffling; + }, (object)null); + } + + [Conditional("DEBUG_NOW_PLAYING_LIST")] + private static void _DEBUG_Trace(string message, params object[] args) + { + } + + private enum MovingMode + { + Advancing, + Retreating, + Jumping, + } + } +} diff --git a/ZuneUI/NowPlayingNotification.cs b/ZuneUI/NowPlayingNotification.cs new file mode 100644 index 0000000..bebf59d --- /dev/null +++ b/ZuneUI/NowPlayingNotification.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.NowPlayingNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class NowPlayingNotification : Notification + { + public NowPlayingNotification() + : base(NotificationTask.NowPlaying, NotificationState.Normal, 10000) + { + } + } +} diff --git a/ZuneUI/OSInfo.cs b/ZuneUI/OSInfo.cs new file mode 100644 index 0000000..ea4a585 --- /dev/null +++ b/ZuneUI/OSInfo.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.OSInfo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Runtime.InteropServices; + +namespace ZuneUI +{ + public static class OSInfo + { + private const uint SPI_GETKEYBOARDSPEED = 10; + private const uint SPI_GETKEYBOARDDELAY = 22; + private static int s_defaultKeyDelay = OSInfo.GetDefaultKeyDelay(); + private static int s_defaultKeyRepeat = OSInfo.GetDefaultKeyRepeat(); + + public static int DefaultKeyDelay => OSInfo.s_defaultKeyDelay; + + public static int DefaultKeyRepeat => OSInfo.s_defaultKeyRepeat; + + private static int GetDefaultKeyDelay() + { + int pParam; + if (!OSInfo.SystemParametersInfo(22U, 0U, out pParam, 0)) + pParam = 1; + return (pParam + 1) * 250; + } + + private static int GetDefaultKeyRepeat() + { + int pParam; + if (!OSInfo.SystemParametersInfo(10U, 0U, out pParam, 0)) + pParam = 1; + return 31000 / (62 + 28 * pParam); + } + + [DllImport("user32.dll", SetLastError = true)] + private static extern bool SystemParametersInfo( + uint uiAction, + uint uiParam, + out int pParam, + int nWinIni); + } +} diff --git a/ZuneUI/OSVersion.cs b/ZuneUI/OSVersion.cs new file mode 100644 index 0000000..4dd7d04 --- /dev/null +++ b/ZuneUI/OSVersion.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.OSVersion +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class OSVersion + { + public static bool IsXP() => Environment.OSVersion.Version.Major == 5; + + public static bool IsVista() => Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 0; + + public static bool IsWin7() + { + if (Environment.OSVersion.Version.Major > 6) + return true; + return Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 1; + } + } +} diff --git a/ZuneUI/OrderedGroupedList.cs b/ZuneUI/OrderedGroupedList.cs new file mode 100644 index 0000000..a3b4cf4 --- /dev/null +++ b/ZuneUI/OrderedGroupedList.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.OrderedGroupedList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class OrderedGroupedList : SearchableGroupedList + { + public OrderedGroupedList(IList source, IComparer comparer, int count) + : base((IList)null, comparer, count) + => this.Reorder(source, count); + + protected override void OnDispose(bool disposing) + { + if (disposing && this.Source is ArrayListDataSet) + ((ModelItem)this.Source).Dispose(); + base.OnDispose(disposing); + } + + public void Reorder(IList source, int count) + { + ArrayListDataSet arrayListDataSet = (ArrayListDataSet)null; + if (source != null) + { + arrayListDataSet = new ArrayListDataSet(); + arrayListDataSet.CopyFrom((IEnumerable)source); + int newIndex; + for (int itemIndex = 0; itemIndex < arrayListDataSet.Count; itemIndex = newIndex + 1) + { + newIndex = itemIndex; + for (int index = itemIndex + 1; index < arrayListDataSet.Count; ++index) + { + if (this.Comparer.Compare(arrayListDataSet[itemIndex], arrayListDataSet[index]) == 0) + { + ++newIndex; + if (newIndex != index) + arrayListDataSet.Move(index, newIndex); + } + } + } + } + if (this.Source is ArrayListDataSet) + ((ModelItem)this.Source).Dispose(); + this.SetSource((IList)arrayListDataSet, count); + } + } +} diff --git a/ZuneUI/Page.cs b/ZuneUI/Page.cs new file mode 100644 index 0000000..74755e2 --- /dev/null +++ b/ZuneUI/Page.cs @@ -0,0 +1,56 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Page +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class Page : ModelItem, IPage + { + private bool _isCurrentPage; + + public bool IsCurrentPage + { + get => this._isCurrentPage; + private set + { + if (this._isCurrentPage == value) + return; + this._isCurrentPage = value; + this.FirePropertyChanged(nameof(IsCurrentPage)); + } + } + + public void OnNavigatedTo() => this.OnNavigatedToWorker(); + + public void OnNavigatedAway(IPage destination) => this.OnNavigatedAwayWorker(destination); + + public event EventHandler NavigatedTo; + + public event EventHandler NavigatedAway; + + public virtual IPageState SaveAndRelease() => (IPageState)new InstancePageState((IPage)this); + + public virtual void Release() => this.Dispose(); + + protected virtual void OnNavigatedToWorker() + { + this.IsCurrentPage = true; + if (this.NavigatedTo == null) + return; + this.NavigatedTo((object)this, EventArgs.Empty); + } + + protected virtual void OnNavigatedAwayWorker(IPage destination) + { + this.IsCurrentPage = false; + if (this.NavigatedAway == null) + return; + this.NavigatedAway((object)this, EventArgs.Empty); + } + } +} diff --git a/ZuneUI/PageNode.cs b/ZuneUI/PageNode.cs new file mode 100644 index 0000000..646ff51 --- /dev/null +++ b/ZuneUI/PageNode.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PageNode +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class PageNode : Node + { + private GetPageCallback _handler; + + public PageNode(Experience owner, StringId id, GetPageCallback handler, SQMDataId sqmDataID) + : base(owner, id, (string)null, sqmDataID) + => this._handler = handler; + + protected override void Execute(Shell shell) => this.Invoke((IDictionary)null); + + public void Invoke(IDictionary commandArgs) + { + ZuneShell defaultInstance = ZuneShell.DefaultInstance; + if (defaultInstance == null) + throw new InvalidOperationException("No Shell instance has been registered. Unable to perform navigation."); + ZunePage page = this._handler(); + if (commandArgs != null) + page.NavigationArguments = commandArgs; + defaultInstance.NavigateToPage(page); + } + } +} diff --git a/ZuneUI/PageStack.cs b/ZuneUI/PageStack.cs new file mode 100644 index 0000000..3cc476d --- /dev/null +++ b/ZuneUI/PageStack.cs @@ -0,0 +1,153 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PageStack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class PageStack : ModelItem + { + private IPage _currentPage; + private ArrayList _pageStack; + private NavigationDirection _navDirection; + private uint _maxStackSize; + + public PageStack() + : this((IModelItemOwner)null) + { + } + + public PageStack(IModelItemOwner owner) + : base(owner) + => this._pageStack = new ArrayList(); + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + if (this._currentPage != null) + { + this._currentPage.OnNavigatedAway((IPage)null); + this._currentPage.Release(); + this._currentPage = (IPage)null; + } + if (this._pageStack != null) + { + foreach (IPageState page in this._pageStack) + page.Release(); + this._pageStack = (ArrayList)null; + } + } + base.OnDispose(disposing); + } + + public IPage CurrentPage => this._currentPage; + + public bool CanNavigateBack => this._pageStack.Count > 0; + + public uint MaximumStackSize + { + get => this._maxStackSize; + set + { + if ((int)this._maxStackSize == (int)value) + return; + this._maxStackSize = value; + this.FirePropertyChanged(nameof(MaximumStackSize)); + this.TrimStackSize(); + } + } + + public NavigationDirection LastNavigationDirection => this._navDirection; + + private void SetLastNavigationDirection(NavigationDirection value) + { + if (this._navDirection == value) + return; + this._navDirection = value; + this.FirePropertyChanged("LastNavigationDirection"); + } + + public void NavigateToPage(IPage page) + { + if (page == null) + throw new ArgumentNullException(nameof(page)); + if (this._currentPage != null) + { + this._currentPage.OnNavigatedAway(page); + this.PushToStack(this._currentPage); + } + this.SetCurrentPage(page); + this.SetLastNavigationDirection(NavigationDirection.Forward); + this.TrimStackSize(); + } + + public void NavigateBack() + { + IPage page1 = (IPage)null; + while (this.CanNavigateBack && page1 == null) + { + int index = this._pageStack.Count - 1; + IPageState page2 = (IPageState)this._pageStack[index]; + this._pageStack.RemoveAt(index); + if (page2 != null) + page1 = page2.RestoreAndRelease(); + if (page2 != null) + ; + } + if (!this.CanNavigateBack) + this.FirePropertyChanged("CanNavigateBack"); + if (page1 == null) + return; + this._currentPage.OnNavigatedAway(page1); + this._currentPage.Release(); + this.SetCurrentPage(page1); + this.SetLastNavigationDirection(NavigationDirection.Back); + } + + public void PushToStack(IPage page) + { + IPageState pageState = page != null ? page.SaveAndRelease() : throw new ArgumentNullException(nameof(page)); + if (pageState == null) + return; + this._pageStack.Add((object)pageState); + if (this._pageStack.Count != 1) + return; + this.FirePropertyChanged("CanNavigateBack"); + } + + private void SetCurrentPage(IPage page) + { + this._currentPage = page; + this.FirePropertyChanged("CurrentPage"); + this._currentPage.OnNavigatedTo(); + } + + private void TrimStackSize() + { + if (this._maxStackSize == 0U) + return; + int num = this._pageStack.Count - (int)this._maxStackSize; + if (num <= 0) + return; + int index = 0; + while (num > 0 && index < this._pageStack.Count) + { + IPageState page = (IPageState)this._pageStack[index]; + if (page.CanBeTrimmed) + { + this._pageStack.RemoveAt(index); + page.Release(); + --num; + } + else + ++index; + } + } + } +} diff --git a/ZuneUI/ParentPaymentIntrumentStep.cs b/ZuneUI/ParentPaymentIntrumentStep.cs new file mode 100644 index 0000000..623dd3e --- /dev/null +++ b/ZuneUI/ParentPaymentIntrumentStep.cs @@ -0,0 +1,102 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ParentPaymentIntrumentStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + public class ParentPaymentIntrumentStep : PaymentInstrumentStepBase + { + public ParentPaymentIntrumentStep(Wizard owner, AccountManagementWizardState state) + : base(owner, state, true) + { + } + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled; + if (flag) + flag = this.State.BasicAccountInfoStep.NewAccounType == AccountUserType.ChildWithoutSocial; + return flag; + } + } + + protected override void OnActivate() + { + this.SelectedCountry = this.State.BasicAccountInfoStep.SelectedCountry; + this.SetCommittedValue(PaymentInstrumentPropertyEditor.Country, (object)this.SelectedCountry); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.Language, (object)this.State.BasicAccountInfoStep.SelectedLanguage); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.Email, this.State.ContactInfoParentStep.GetCommittedValue(BaseContactInfoPropertyEditor.Email)); + base.OnActivate(); + this.ServiceDeactivationRequestsDone = false; + MetadataEditProperty property1 = this.WizardPropertyEditor.GetProperty(PaymentInstrumentPropertyEditor.AccountHolderName); + MetadataEditProperty property2 = this.WizardPropertyEditor.GetProperty(PaymentInstrumentPropertyEditor.PhoneNumber); + MetadataEditProperty property3 = this.WizardPropertyEditor.GetProperty(PaymentInstrumentPropertyEditor.PhoneExtension); + MetadataEditProperty property4 = this.WizardPropertyEditor.GetProperty(PaymentInstrumentPropertyEditor.PostalCode); + if (string.IsNullOrEmpty(property1.Value)) + { + string committedValue1 = this.State.ContactInfoParentStep.GetCommittedValue(BaseContactInfoPropertyEditor.FirstName) as string; + string committedValue2 = this.State.ContactInfoParentStep.GetCommittedValue(BaseContactInfoPropertyEditor.LastName) as string; + string format = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_NAME_FORMAT); + property1.Value = string.Format(format, (object)committedValue1, (object)committedValue2); + } + property4.State = (object)this.SelectedCountry; + if (string.IsNullOrEmpty(property4.Value)) + property4.Value = this.State.BasicAccountInfoStep.GetCommittedValue(BasicAccountInfoPropertyEditor.PostalCode) as string; + if (string.IsNullOrEmpty(property2.Value)) + property2.Value = this.State.ContactInfoParentStep.GetCommittedValue(BaseContactInfoPropertyEditor.PhoneNumber) as string; + if (!string.IsNullOrEmpty(property3.Value)) + return; + property3.Value = this.State.ContactInfoParentStep.GetCommittedValue(BaseContactInfoPropertyEditor.PhoneExtension) as string; + } + + internal override bool OnMovingNext() + { + if (this.ServiceDeactivationRequestsDone) + return base.OnMovingNext(); + ParentPaymentIntrumentStep.ServiceData serviceData; + serviceData.PassportIdentity = this.State.PassportPasswordParentStep.PassportIdentity; + serviceData.CreditCard = this.CreateCreditCard(); + serviceData.CreditCard.ContactFirstName = this.State.ContactInfoParentStep.GetCommittedValue(BaseContactInfoPropertyEditor.FirstName) as string; + serviceData.CreditCard.ContactLastName = this.State.ContactInfoParentStep.GetCommittedValue(BaseContactInfoPropertyEditor.LastName) as string; + this.StartDeactivationRequests((object)serviceData); + return false; + } + + protected override void OnStartDeactivationRequests(object state) + { + ParentPaymentIntrumentStep.ServiceData serviceData = (ParentPaymentIntrumentStep.ServiceData)state; + CreditCard creditCard = (CreditCard)null; + if (this.IsValidCreditCard(serviceData)) + creditCard = serviceData.CreditCard; + this.EndDeactivationRequests((object)creditCard); + } + + protected override void OnEndDeactivationRequests(object args) => this.CommittedCreditCard = (CreditCard)args; + + private bool IsValidCreditCard(ParentPaymentIntrumentStep.ServiceData serviceData) + { + bool flag = true; + if (serviceData.PassportIdentity != null) + { + ServiceError serviceError; + HRESULT hr = this.State.AccountManagement.ValidateCreditCard(serviceData.PassportIdentity, serviceData.CreditCard, out serviceError); + flag = hr.IsSuccess; + if (!flag) + this.SetError(hr, serviceError); + } + return flag; + } + + private struct ServiceData + { + public PassportIdentity PassportIdentity; + public CreditCard CreditCard; + } + } +} diff --git a/ZuneUI/PassportPasswordPropertyEditor.cs b/ZuneUI/PassportPasswordPropertyEditor.cs new file mode 100644 index 0000000..aa7b187 --- /dev/null +++ b/ZuneUI/PassportPasswordPropertyEditor.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PassportPasswordPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class PassportPasswordPropertyEditor : WizardPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static PropertyDescriptor s_Email = new PropertyDescriptor(nameof(Email), string.Empty, string.Empty, true); + public static PropertyDescriptor s_Password = new PropertyDescriptor(nameof(Password), string.Empty, string.Empty, true); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (PassportPasswordPropertyEditor.s_dataProviderProperties == null) + PassportPasswordPropertyEditor.s_dataProviderProperties = new PropertyDescriptor[2] + { + PassportPasswordPropertyEditor.s_Email, + PassportPasswordPropertyEditor.s_Password + }; + return PassportPasswordPropertyEditor.s_dataProviderProperties; + } + } + + public static PropertyDescriptor Password => PassportPasswordPropertyEditor.s_Password; + + public static PropertyDescriptor Email => PassportPasswordPropertyEditor.s_Email; + } +} diff --git a/ZuneUI/PassportPasswordStep.cs b/ZuneUI/PassportPasswordStep.cs new file mode 100644 index 0000000..d1e994c --- /dev/null +++ b/ZuneUI/PassportPasswordStep.cs @@ -0,0 +1,366 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PassportPasswordStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class PassportPasswordStep : AccountManagementStep + { + private bool _skipOnce; + private bool _forceEnable; + private bool _isUpgradeNeeded; + private bool _isZuneAccount; + private bool _isUnsupportedAccount; + private bool _isUnsupportedRegion; + private bool _lockEmail; + private PassportIdentity _passportIdentity; + private AccountUser _existingAccountUser; + private Dictionary _errorMappings; + + public PassportPasswordStep( + Wizard owner, + AccountManagementWizardState state, + bool parentAccount) + : base(owner, state, parentAccount) + { + if (parentAccount) + { + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_START_PARENT_HEADER); + this.DetailDescription = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_CREDENTIALS_PARENT); + } + else + { + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_PASSPORT_STEP); + this.DetailDescription = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_CREDENTIALS_HEADER); + } + this.DetailDescription = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_CREDENTIALS_HEADER); + this.Initialize((WizardPropertyEditor)new PassportPasswordPropertyEditor()); + } + + public override string UI => "res://ZuneShellResources!CreatePassport.uix#PassportPasswordStep"; + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled && !this.CreatePassportStep.CreatedPassport; + if (flag) + { + flag = this.ForceEnable; + if (!flag) + flag = SignIn.Instance.SignedIn && this.ParentAccount && SignIn.Instance.IsParentallyControlled; + if (!flag) + flag = ((this.EmailSelectionStep.IsEnabled || this.EmailSelectionStep.PageLocked ? (!this.EmailSelectionStep.NeedsPassportId ? 1 : 0) : (false ? 1 : 0)) & (this._owner.CurrentPage != this || this.ParentAccount ? 1 : (!SignIn.Instance.SigningIn ? 1 : 0))) != 0; + } + return flag; + } + } + + public bool ForceEnable + { + get => this._forceEnable; + set + { + if (this._forceEnable == value) + return; + this._forceEnable = value; + this.FirePropertyChanged(nameof(ForceEnable)); + } + } + + internal bool SkipOnce + { + get => this._skipOnce; + set + { + if (this._skipOnce == value) + return; + this._skipOnce = value; + this.FirePropertyChanged(nameof(SkipOnce)); + } + } + + public bool LockEmail + { + get => this._lockEmail; + internal set + { + if (this._lockEmail == value) + return; + this._lockEmail = value; + this.FirePropertyChanged(nameof(LockEmail)); + } + } + + public string CommittedEmail + { + get => this.GetCommittedValue(PassportPasswordPropertyEditor.Email) as string; + internal set + { + this.SetCommittedValue(PassportPasswordPropertyEditor.Email, (object)value); + this.FirePropertyChanged(nameof(CommittedEmail)); + } + } + + public string CommittedPassword + { + get => this.GetCommittedValue(PassportPasswordPropertyEditor.Password) as string; + internal set + { + this.SetCommittedValue(PassportPasswordPropertyEditor.Password, (object)value); + this.FirePropertyChanged(nameof(CommittedPassword)); + } + } + + internal string UncommittedEmail => this.GetUncommittedValue(PassportPasswordPropertyEditor.Email) as string; + + internal string UncommittedPassword => this.GetUncommittedValue(PassportPasswordPropertyEditor.Password) as string; + + public bool CanCreateAccount + { + get + { + bool flag = this.ParentAccount && (this.State.CreatePassportParentStep.IsEnabled || this.State.CreatePassportParentStep.CreatedPassport) || !this.ParentAccount && (this.State.CreatePassportStep.IsEnabled || this.State.CreatePassportStep.CreatedPassport); + if (!flag) + flag = !this.IsUnsupportedAccount && !this.IsUnsupportedRegion && !this.IsUpgradeNeeded && !this.IsZuneAccount; + return flag; + } + } + + public bool IsUpgradeNeeded + { + get => this._isUpgradeNeeded; + private set + { + if (this._isUpgradeNeeded == value) + return; + this._isUpgradeNeeded = value; + this.FirePropertyChanged(nameof(IsUpgradeNeeded)); + this.FirePropertyChanged("CanCreateAccount"); + } + } + + public bool IsZuneAccount + { + get => this._isZuneAccount; + private set + { + if (this._isZuneAccount == value) + return; + this._isZuneAccount = value; + this.FirePropertyChanged(nameof(IsZuneAccount)); + this.FirePropertyChanged("CanCreateAccount"); + } + } + + public bool IsUnsupportedAccount + { + get => this._isUnsupportedAccount; + private set + { + if (this._isUnsupportedAccount == value) + return; + this._isUnsupportedAccount = value; + this.FirePropertyChanged(nameof(IsUnsupportedAccount)); + this.FirePropertyChanged("CanCreateAccount"); + } + } + + public bool IsUnsupportedRegion + { + get => this._isUnsupportedRegion; + private set + { + if (this._isUnsupportedRegion == value) + return; + this._isUnsupportedRegion = value; + this.FirePropertyChanged(nameof(IsUnsupportedRegion)); + this.FirePropertyChanged("CanCreateAccount"); + } + } + + public bool IsParentAccountNeeded + { + get + { + bool flag = false; + if (this._existingAccountUser != null) + flag = this._existingAccountUser.AccountUserType != AccountUserType.Adult; + return flag; + } + } + + public AccountUser ExistingAccountUser + { + get => this._existingAccountUser; + private set + { + if (this._existingAccountUser == value) + return; + this._existingAccountUser = value; + this.FirePropertyChanged(nameof(ExistingAccountUser)); + this.FirePropertyChanged("IsParentAccountNeeded"); + } + } + + public PassportIdentity PassportIdentity + { + get => this._passportIdentity; + internal set + { + if (this._passportIdentity == value) + return; + this._passportIdentity = value; + this.FirePropertyChanged(nameof(PassportIdentity)); + } + } + + internal override Dictionary ErrorPropertyMappings + { + get + { + if (this._errorMappings == null) + { + this._errorMappings = new Dictionary(1); + this._errorMappings.Add(HRESULT._NS_E_PASSPORT_LOGIN_FAILED.Int, PassportPasswordPropertyEditor.Password); + } + return this._errorMappings; + } + } + + private EmailSelectionStep EmailSelectionStep => !this.ParentAccount ? this.State.EmailSelectionStep : this.State.EmailSelectionParentStep; + + private CreatePassportStep CreatePassportStep => !this.ParentAccount ? this.State.CreatePassportStep : this.State.CreatePassportParentStep; + + protected override void OnActivate() + { + this.ServiceDeactivationRequestsDone = false; + string committedValue = this.EmailSelectionStep.GetCommittedValue(EmailSelectionPropertyEditor.Email) as string; + string committedPassword = this.CommittedPassword; + string committedEmail = this.CommittedEmail; + if (committedValue != committedEmail || string.IsNullOrEmpty(committedPassword)) + { + this.PassportIdentity = (PassportIdentity)null; + this.CommittedEmail = committedValue; + this.CommittedPassword = string.Empty; + } + if (!this.SkipOnce) + return; + this.SkipOnce = false; + this._owner.MoveNext(); + } + + internal override bool OnMovingNext() + { + if (!this.ServiceDeactivationRequestsDone) + { + this.IsZuneAccount = false; + this.IsUnsupportedAccount = false; + this.IsUnsupportedRegion = false; + this.IsUpgradeNeeded = false; + this.StartDeactivationRequests((object)new PassportPasswordStep.ServiceData() + { + Password = this.UncommittedPassword, + Email = this.UncommittedEmail, + PassportIdentity = (this.UncommittedPassword != this.CommittedPassword || this.UncommittedEmail != this.CommittedEmail ? (PassportIdentity)null : this.PassportIdentity) + }); + this.LoadStatus = Shell.LoadString(StringId.IDS_ACCOUNT_SIGNING_INTO_WINDOWS_LIVE); + return false; + } + if (!SignIn.Instance.SigningIn || this.ParentAccount) + { + this.LoadStatus = (string)null; + return base.OnMovingNext(); + } + this.LoadStatus = Shell.LoadString(StringId.IDS_PLEASE_WAIT); + return false; + } + + protected override void OnStartDeactivationRequests(object state) + { + PassportPasswordStep.ServiceData serviceData = (PassportPasswordStep.ServiceData)state; + this.ValidatePassportAccount(ref serviceData); + this.EndDeactivationRequests((object)serviceData); + } + + protected override void OnEndDeactivationRequests(object args) + { + PassportPasswordStep.ServiceData serviceData = (PassportPasswordStep.ServiceData)args; + this.PassportIdentity = serviceData.PassportIdentity; + if (this.PassportIdentity == null || this.ParentAccount) + return; + SignIn.Instance.SignOut(); + SignIn.Instance.SignInStatusUpdatedEvent += new EventHandler(this.OnSignInStatusUpdatedEvent); + SignIn.Instance.SignInUser(serviceData.Email, serviceData.Password); + this.ExistingAccountUser = serviceData.ExistingAccountUser; + if (this.ExistingAccountUser == null) + return; + this.State.SetPrivacySettings(this.ExistingAccountUser.AccountUserType); + } + + private void ValidatePassportAccount(ref PassportPasswordStep.ServiceData serviceData) + { + HRESULT hr = HRESULT._S_OK; + if (serviceData.PassportIdentity == null) + hr = AccountManagementHelper.GetPassportIdentity(serviceData.Email, serviceData.Password, out serviceData.PassportIdentity); + if (hr.IsSuccess) + { + ServiceError serviceError = (ServiceError)null; + this.State.AccountManagement.GetAccount(serviceData.PassportIdentity, out serviceData.ExistingAccountUser, out serviceError); + } + if (!hr.IsError) + return; + this.SetError(hr, (ServiceError)null); + } + + private void OnSignInStatusUpdatedEvent(object sender, EventArgs e) + { + if (!SignIn.Instance.SigningIn && (SignIn.Instance.SignInError.IsError || SignIn.Instance.SignedIn)) + { + bool flag = false; + if (SignIn.Instance.SignInError.IsError) + { + if (SignIn.Instance.SignInError == HRESULT._NS_E_SIGNIN_TERMS_OF_SERVICE) + this.IsUpgradeNeeded = true; + else if (SignIn.Instance.SignInError == HRESULT._NS_E_SIGNIN_ACCOUNTS_NOT_XENON_USER) + { + flag = true; + this.IsUnsupportedAccount = true; + } + else if (SignIn.Instance.SignInError == HRESULT._NS_E_SIGNIN_WCMUSIC_ACCOUNT_NOT_ELIGIBLE) + { + flag = true; + this.IsUnsupportedRegion = true; + } + else if (SignIn.Instance.SignInError == HRESULT._NS_E_SIGNIN_INVALID_REGION) + this.IsZuneAccount = true; + } + else if (SignIn.Instance.SignedIn) + this.IsZuneAccount = true; + SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignInStatusUpdatedEvent); + if (flag) + { + this.SetError(SignIn.Instance.SignInError, (ServiceError)null); + this.NavigateToErrorHandler(); + } + else if (this._owner.CurrentPage == this) + this._owner.MoveNext(); + } + this.FirePropertyChanged("Enabled"); + } + + private struct ServiceData + { + public string Email; + public string Password; + public PassportIdentity PassportIdentity; + public AccountUser ExistingAccountUser; + } + } +} diff --git a/ZuneUI/PaymentInstrumentHelper.cs b/ZuneUI/PaymentInstrumentHelper.cs new file mode 100644 index 0000000..c7b2cce --- /dev/null +++ b/ZuneUI/PaymentInstrumentHelper.cs @@ -0,0 +1,155 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PaymentInstrumentHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class PaymentInstrumentHelper : ModelItem + { + private CreditCardCollection m_creditCards; + private CreditCard m_newCreditCard; + private PaymentInstrument m_defaultPaymentInstrument; + private HRESULT m_errorCode; + + public void GetPaymentInstruments() + { + this.m_defaultPaymentInstrument = (PaymentInstrument)null; + this.m_creditCards = (CreditCardCollection)null; + this.ErrorCode = HRESULT._S_OK; + ZuneApplication.Service.GetPaymentInstruments(new GetPaymentInstrumentsCompleteCallback(this.OnGetPaymentInstrumentsSuccess), new GetPaymentInstrumentsErrorCallback(this.OnGetPaymentInstrumnetsError)); + } + + public void AddPaymentInstrument(PaymentInstrument paymentInstrument) + { + this.ErrorCode = HRESULT._S_OK; + ZuneApplication.Service.AddPaymentInstrument(paymentInstrument, new AddPaymentInstrumentCompleteCallback(this.OnAddPaymentInstrumentSuccess), new AddPaymentInstrumentErrorCallback(this.OnAddPaymentInstrumnetError)); + } + + public IList CreditCards => this.m_creditCards == null ? (IList)null : this.m_creditCards.Items; + + public PaymentInstrument Default + { + get => this.m_defaultPaymentInstrument; + private set + { + if (this.m_defaultPaymentInstrument == value) + return; + this.m_defaultPaymentInstrument = value; + this.FirePropertyChanged(nameof(Default)); + } + } + + public CreditCard NewCreditCard + { + get => this.m_newCreditCard; + private set + { + if (this.m_newCreditCard == value) + return; + this.m_newCreditCard = value; + this.FirePropertyChanged(nameof(NewCreditCard)); + } + } + + public HRESULT ErrorCode + { + get => this.m_errorCode; + set + { + if (!(this.m_errorCode != value)) + return; + this.m_errorCode = value; + this.FirePropertyChanged(nameof(ErrorCode)); + } + } + + public event EventHandler GetPaymentInstrumentsCompleted; + + private void SetError(HRESULT hrError) => this.ErrorCode = hrError; + + private void SetCreditCards(CreditCardCollection creditCards) + { + if (this.IsDisposed) + { + creditCards?.Dispose(); + } + else + { + if (this.m_creditCards != null) + this.m_creditCards.Dispose(); + this.m_creditCards = creditCards; + this.FirePropertyChanged("CreditCards"); + this.CalculateDefault(); + } + } + + private void CalculateDefault() + { + CreditCard creditCard1 = (CreditCard)null; + if (this.NewCreditCard != null) + creditCard1 = this.NewCreditCard; + else if (this.CreditCards != null && this.CreditCards.Count > 0) + { + DateTime now = DateTime.Now; + foreach (CreditCard creditCard2 in (IEnumerable)this.CreditCards) + { + if (creditCard2.ExpirationDate.Year > now.Year || creditCard2.ExpirationDate.Year == now.Year && creditCard2.ExpirationDate.Month >= now.Month) + creditCard1 = creditCard2; + } + } + this.Default = (PaymentInstrument)creditCard1; + } + + private void OnGetPaymentInstrumentsSuccess(CreditCardCollection creditCards) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetPaymentInstrumentsSuccess), (object)creditCards); + + private void OnGetPaymentInstrumnetsError(HRESULT hrError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetPaymentInstrumentsError), (object)hrError); + + private void OnAddPaymentInstrumentSuccess(PaymentInstrument paymentInstrument) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredAddPaymentInstrumentSuccess), (object)paymentInstrument); + + private void OnAddPaymentInstrumnetError(HRESULT hrError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredAddPaymentInstrumentError), (object)hrError); + + private void DeferredGetPaymentInstrumentsSuccess(object args) + { + this.SetCreditCards((CreditCardCollection)args); + this.OnGetPaymentInstrumentsCompleted(); + } + + private void DeferredGetPaymentInstrumentsError(object args) + { + this.SetError((HRESULT)args); + this.OnGetPaymentInstrumentsCompleted(); + } + + private void DeferredAddPaymentInstrumentSuccess(object args) + { + this.NewCreditCard = (CreditCard)args; + this.CalculateDefault(); + } + + private void DeferredAddPaymentInstrumentError(object args) => this.SetError((HRESULT)args); + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing || this.m_creditCards == null) + return; + this.m_creditCards.Dispose(); + this.m_creditCards = (CreditCardCollection)null; + } + + private void OnGetPaymentInstrumentsCompleted() + { + if (this.GetPaymentInstrumentsCompleted != null) + this.GetPaymentInstrumentsCompleted((object)this, (EventArgs)null); + this.FirePropertyChanged("GetPaymentInstrumentsCompleted"); + } + } +} diff --git a/ZuneUI/PaymentInstrumentPropertyEditor.cs b/ZuneUI/PaymentInstrumentPropertyEditor.cs new file mode 100644 index 0000000..85575f6 --- /dev/null +++ b/ZuneUI/PaymentInstrumentPropertyEditor.cs @@ -0,0 +1,89 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PaymentInstrumentPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class PaymentInstrumentPropertyEditor : WizardPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static CountryFieldValidationPropertyDescriptor s_Street1 = new CountryFieldValidationPropertyDescriptor(nameof(Street1), CountryFieldValidatorType.Street1); + public static CountryFieldValidationPropertyDescriptor s_Street2 = new CountryFieldValidationPropertyDescriptor(nameof(Street2), CountryFieldValidatorType.Street2); + public static CountryFieldValidationPropertyDescriptor s_City = new CountryFieldValidationPropertyDescriptor(nameof(City), CountryFieldValidatorType.City); + public static CountryFieldValidationPropertyDescriptor s_District = new CountryFieldValidationPropertyDescriptor(nameof(District), CountryFieldValidatorType.District); + public static StateDescriptor s_State = new StateDescriptor(nameof(State)); + public static PostalCodeDescriptor s_PostalCode = new PostalCodeDescriptor(nameof(PostalCode)); + public static PhoneNumberDescriptors s_PhoneNumber = new PhoneNumberDescriptors(nameof(PhoneNumber), CountryFieldValidatorType.PhoneNumber); + public static CountryFieldValidationPropertyDescriptor s_PhoneExtension = new CountryFieldValidationPropertyDescriptor(nameof(PhoneExtension), CountryFieldValidatorType.PhoneExtension); + public static CardTypePropertyDescriptor s_CardType = new CardTypePropertyDescriptor(nameof(CardType), string.Empty, Shell.LoadString(StringId.IDS_BILLING_EDIT_CC_CCTYPE_EMPTY), true); + public static CountryFieldValidationPropertyDescriptor s_AccountHolderName = new CountryFieldValidationPropertyDescriptor(nameof(AccountHolderName), CountryFieldValidatorType.AccountHolderName); + public static CreditCardNumberDescriptor s_AccountNumber = new CreditCardNumberDescriptor(nameof(AccountNumber), string.Empty, string.Empty, true, true); + public static CreditCardNumberDescriptor s_CcvNumber = new CreditCardNumberDescriptor(nameof(CcvNumber), string.Empty, string.Empty, true, false); + public static CreditCardExpirationDateDescriptor s_ExpirationDate = new CreditCardExpirationDateDescriptor(nameof(ExpirationDate), string.Empty, string.Empty, true); + public static CountryPropertyDescriptor s_Country = new CountryPropertyDescriptor(nameof(Country), string.Empty, string.Empty, true); + public static LanguagePropertyDescriptor s_Language = new LanguagePropertyDescriptor(nameof(Language), string.Empty, string.Empty, false); + public static EmailPropertyDescriptor s_Email = new EmailPropertyDescriptor(nameof(Email), string.Empty, string.Empty, false); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (PaymentInstrumentPropertyEditor.s_dataProviderProperties == null) + PaymentInstrumentPropertyEditor.s_dataProviderProperties = new PropertyDescriptor[16] + { + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_Street1, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_Street2, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_City, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_District, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_State, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_PostalCode, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_PhoneNumber, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_PhoneExtension, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_CardType, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_AccountHolderName, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_AccountNumber, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_CcvNumber, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_ExpirationDate, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_Country, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_Language, + (PropertyDescriptor) PaymentInstrumentPropertyEditor.s_Email + }; + return PaymentInstrumentPropertyEditor.s_dataProviderProperties; + } + } + + public static PropertyDescriptor Street1 => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_Street1; + + public static PropertyDescriptor Street2 => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_Street2; + + public static PropertyDescriptor City => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_City; + + public static PropertyDescriptor District => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_District; + + public static PropertyDescriptor State => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_State; + + public static PropertyDescriptor PostalCode => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_PostalCode; + + public static PropertyDescriptor PhoneNumber => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_PhoneNumber; + + public static PropertyDescriptor PhoneExtension => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_PhoneExtension; + + public static PropertyDescriptor CardType => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_CardType; + + public static PropertyDescriptor AccountHolderName => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_AccountHolderName; + + public static PropertyDescriptor AccountNumber => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_AccountNumber; + + public static PropertyDescriptor CcvNumber => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_CcvNumber; + + public static PropertyDescriptor ExpirationDate => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_ExpirationDate; + + public static PropertyDescriptor Country => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_Country; + + public static PropertyDescriptor Language => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_Language; + + public static PropertyDescriptor Email => (PropertyDescriptor)PaymentInstrumentPropertyEditor.s_Email; + } +} diff --git a/ZuneUI/PaymentInstrumentStep.cs b/ZuneUI/PaymentInstrumentStep.cs new file mode 100644 index 0000000..db74931 --- /dev/null +++ b/ZuneUI/PaymentInstrumentStep.cs @@ -0,0 +1,95 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PaymentInstrumentStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + public class PaymentInstrumentStep : PaymentInstrumentStepBase + { + private bool _firstView; + + public PaymentInstrumentStep(Wizard owner, AccountManagementWizardState state, bool parent) + : base(owner, state, parent) + { + this._firstView = true; + this.RequireSignIn = true; + } + + public override bool IsEnabled => base.IsEnabled && this.State.SelectPaymentInstrumentStep.CommittedCreditCard == null; + + protected override bool OnCommitChanges() + { + bool flag = !this.IsEnabled; + if (!flag && this.CommittedCreditCard != null) + { + string paymentId = (string)null; + ServiceError serviceError; + HRESULT hr = (HRESULT)Microsoft.Zune.Service.Service.Instance.AddPaymentInstrument((PaymentInstrument)this.CommittedCreditCard, out paymentId, out serviceError); + if (hr.IsError) + { + this.SetError(hr, serviceError); + } + else + { + this.CommittedCreditCard.Id = paymentId; + flag = true; + } + } + return flag; + } + + protected override void OnActivate() + { + this.UpdateButtonText(); + if (this.State.ContactInfoStep.IsEnabled && this._firstView) + { + this._firstView = false; + string committedValue1 = this.State.ContactInfoStep.GetCommittedValue(BaseContactInfoPropertyEditor.FirstName) as string; + string committedValue2 = this.State.ContactInfoStep.GetCommittedValue(BaseContactInfoPropertyEditor.LastName) as string; + this.SetCommittedValue(PaymentInstrumentPropertyEditor.AccountHolderName, (object)string.Format(Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_NAME_FORMAT), (object)committedValue1, (object)committedValue2)); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.City, this.State.ContactInfoStep.GetCommittedValue(ContactInfoPropertyEditor.City)); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.Country, this.State.ContactInfoStep.GetCommittedValue(ContactInfoPropertyEditor.Country)); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.District, this.State.ContactInfoStep.GetCommittedValue(ContactInfoPropertyEditor.District)); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.PhoneExtension, this.State.ContactInfoStep.GetCommittedValue(BaseContactInfoPropertyEditor.PhoneExtension)); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.PhoneNumber, this.State.ContactInfoStep.GetCommittedValue(BaseContactInfoPropertyEditor.PhoneNumber)); + this.SetPropertyState(PaymentInstrumentPropertyEditor.PostalCode, this.State.ContactInfoStep.GetCommittedValue(ContactInfoPropertyEditor.Country)); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.PostalCode, this.State.ContactInfoStep.GetCommittedValue(ContactInfoPropertyEditor.PostalCode)); + this.SetPropertyState(PaymentInstrumentPropertyEditor.State, this.State.ContactInfoStep.GetCommittedValue(ContactInfoPropertyEditor.Country)); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.State, this.State.ContactInfoStep.GetCommittedValue(ContactInfoPropertyEditor.State)); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.Street1, this.State.ContactInfoStep.GetCommittedValue(ContactInfoPropertyEditor.Street1)); + this.SetCommittedValue(PaymentInstrumentPropertyEditor.Street2, this.State.ContactInfoStep.GetCommittedValue(ContactInfoPropertyEditor.Street2)); + } + base.OnActivate(); + } + + internal override bool OnMovingNext() + { + this.CommittedCreditCard = this.CreateCreditCard(); + if (this.State.ContactInfoStep.IsEnabled) + { + this.CommittedCreditCard.ContactFirstName = this.State.ContactInfoStep.GetCommittedValue(BaseContactInfoPropertyEditor.FirstName) as string; + this.CommittedCreditCard.ContactLastName = this.State.ContactInfoStep.GetCommittedValue(BaseContactInfoPropertyEditor.LastName) as string; + this.CommittedCreditCard.Email = this.State.ContactInfoStep.GetCommittedValue(BaseContactInfoPropertyEditor.Email) as string; + } + return base.OnMovingNext(); + } + + private void UpdateButtonText() + { + if (this.State.SelectBillingOfferStep.SubscriptionsOnly && !this.State.IsPurchaseConfirmationNeeded) + { + this.NextTextOverride = Shell.LoadString(StringId.IDS_BILLING_SIGN_UP); + } + else + { + if (!this.State.SelectBillingOfferStep.PointsOffersOnly) + return; + this.NextTextOverride = Shell.LoadString(StringId.IDS_BILLING_BUY_BTN); + } + } + } +} diff --git a/ZuneUI/PaymentInstrumentStepBase.cs b/ZuneUI/PaymentInstrumentStepBase.cs new file mode 100644 index 0000000..4dff735 --- /dev/null +++ b/ZuneUI/PaymentInstrumentStepBase.cs @@ -0,0 +1,116 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PaymentInstrumentStepBase +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class PaymentInstrumentStepBase : RegionInfoStep + { + private CreditCard _committedCreditCard; + private Dictionary _errorMappings; + + public PaymentInstrumentStepBase( + Wizard owner, + AccountManagementWizardState state, + bool parentAccount) + : base(owner, state, parentAccount) + { + this.LoadLanguages = false; + this.LoadStates = true; + if (parentAccount) + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_PARENT_AGE_HEADER); + else + this.Description = Shell.LoadString(StringId.IDS_BILLING_EDIT_CC_ADD_HEADER); + this.Initialize((WizardPropertyEditor)new PaymentInstrumentPropertyEditor()); + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#PaymentInstrumentStep"; + + protected override PropertyDescriptor CountryDescriptor => PaymentInstrumentPropertyEditor.Country; + + protected override PropertyDescriptor LanguageDescriptor => PaymentInstrumentPropertyEditor.Language; + + protected override PropertyDescriptor StateDescriptor => PaymentInstrumentPropertyEditor.State; + + public CreditCard CommittedCreditCard + { + get => this._committedCreditCard; + protected set + { + if (this._committedCreditCard == value) + return; + this._committedCreditCard = value; + this.FirePropertyChanged(nameof(CommittedCreditCard)); + } + } + + internal override Dictionary ErrorPropertyMappings + { + get + { + if (this._errorMappings == null) + { + this._errorMappings = new Dictionary(11); + this._errorMappings.Add(HRESULT._ZEST_E_CREDITCARD_ADDRESS_CITY_INVALID.Int, PaymentInstrumentPropertyEditor.City); + this._errorMappings.Add(HRESULT._ZEST_E_CREDITCARD_ADDRESS_POSTALCODE_INVALID.Int, PaymentInstrumentPropertyEditor.PostalCode); + this._errorMappings.Add(HRESULT._ZEST_E_CREDITCARD_ADDRESS_STATE_INVALID.Int, PaymentInstrumentPropertyEditor.State); + this._errorMappings.Add(HRESULT._ZEST_E_CREDITCARD_ADDRESS_STREET1_INVALID.Int, PaymentInstrumentPropertyEditor.Street1); + this._errorMappings.Add(HRESULT._ZEST_E_CREDITCARD_PARENTPHONE_INVALID.Int, PaymentInstrumentPropertyEditor.PhoneNumber); + this._errorMappings.Add(HRESULT._ZEST_E_INVALID_ARG_PARENT_PHONE_INVALID.Int, PaymentInstrumentPropertyEditor.PhoneNumber); + this._errorMappings.Add(HRESULT._ZEST_E_CREDITCARD_ADD_FAILED.Int, (PropertyDescriptor)null); + this._errorMappings.Add(HRESULT._ZEST_E_CREDITCARD_VALIDATE_FAILED.Int, (PropertyDescriptor)null); + this._errorMappings.Add(HRESULT._ZEST_E_CREDITCARD_INVALID.Int, (PropertyDescriptor)null); + this._errorMappings.Add(HRESULT._ZEST_E_CREDITCARD_ADDRESS_INVALID.Int, (PropertyDescriptor)null); + this._errorMappings.Add(HRESULT._ZEST_E_LIVEACCOUNT_PAYMENT_INSTRUMENT_INVALID.Int, (PropertyDescriptor)null); + this._errorMappings.Add(HRESULT._ZEST_E_LIVEACCOUNT_ADDRESS_INVALID.Int, (PropertyDescriptor)null); + } + return this._errorMappings; + } + } + + protected override void OnCountryChanged() + { + if (this.WizardPropertyEditor == null) + return; + this.WizardPropertyEditor.SetPropertyState(PaymentInstrumentPropertyEditor.AccountHolderName, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(PaymentInstrumentPropertyEditor.Street1, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(PaymentInstrumentPropertyEditor.Street2, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(PaymentInstrumentPropertyEditor.City, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(PaymentInstrumentPropertyEditor.State, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(PaymentInstrumentPropertyEditor.PostalCode, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(PaymentInstrumentPropertyEditor.PhoneNumber, (object)this.SelectedCountry); + this.WizardPropertyEditor.SetPropertyState(PaymentInstrumentPropertyEditor.PhoneExtension, (object)this.SelectedCountry); + } + + protected CreditCard CreateCreditCard() + { + CreditCard creditCard = new CreditCard(); + creditCard.ParentCreditCard = this.ParentAccount; + creditCard.AccountNumber = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.AccountNumber) as string; + creditCard.Address.City = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.City) as string; + creditCard.Address.PostalCode = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.PostalCode) as string; + creditCard.Address.State = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.State) as string; + creditCard.Address.Street1 = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.Street1) as string; + creditCard.Address.Street2 = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.Street2) as string; + creditCard.CCVNumber = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.CcvNumber) as string; + CreditCardType? uncommittedValue1 = (CreditCardType?)this.GetUncommittedValue(PaymentInstrumentPropertyEditor.CardType); + if (uncommittedValue1.HasValue && uncommittedValue1.HasValue) + creditCard.CreditCardType = uncommittedValue1.Value; + creditCard.Email = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.Email) as string; + DateTime? uncommittedValue2 = (DateTime?)this.GetUncommittedValue(PaymentInstrumentPropertyEditor.ExpirationDate); + if (uncommittedValue2.HasValue && uncommittedValue2.HasValue) + creditCard.ExpirationDate = uncommittedValue2.Value; + creditCard.AccountHolderName = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.AccountHolderName) as string; + creditCard.Locale = this.SelectedLocale; + creditCard.PhoneNumber = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.PhoneNumber) as string; + creditCard.PhoneExtension = this.GetUncommittedValue(PaymentInstrumentPropertyEditor.PhoneExtension) as string; + return creditCard; + } + } +} diff --git a/ZuneUI/PhoneBrandingStringMap.cs b/ZuneUI/PhoneBrandingStringMap.cs new file mode 100644 index 0000000..ddadd2e --- /dev/null +++ b/ZuneUI/PhoneBrandingStringMap.cs @@ -0,0 +1,130 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PhoneBrandingStringMap +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections.Generic; + +namespace ZuneUI +{ + internal class PhoneBrandingStringMap + { + private static readonly PhoneBrandingStringMap _instance = new PhoneBrandingStringMap(); + protected bool _isBrandingEnabled; + protected Dictionary _stringMap = new Dictionary(); + + protected PhoneBrandingStringMap() + { + } + + static PhoneBrandingStringMap() => PhoneBrandingStringMap._instance.Initialize(); + + public static PhoneBrandingStringMap Instance => PhoneBrandingStringMap._instance; + + public bool BrandingEnabled + { + get => this._isBrandingEnabled; + set + { + if (this._isBrandingEnabled == value) + return; + this._isBrandingEnabled = value; + } + } + + public StringId TryGetMappedStringId(StringId stringId) + { + StringId stringId1; + if (this._stringMap.TryGetValue(stringId, out stringId1)) + stringId = stringId1; + return stringId; + } + + public virtual void Initialize() + { + this._stringMap[StringId.IDS_FIRMWARE_CURRENT_VERSION] = StringId.IDS_PHONE_CURRENT_VERSION; + this._stringMap[StringId.IDS_LIBRARY_QUESTION_N_ITEMS] = StringId.IDS_PHONE_LIBRARY_QUESTION_N_ITEMS; + this._stringMap[StringId.IDS_FIRMWARE_UPDATE_WARNING] = StringId.IDS_PHONE_FIRMWARE_UPDATE_WARNING; + this._stringMap[StringId.IDS_FIRMWARE_INSTALLING] = StringId.IDS_PHONE_FIRMWARE_INSTALLING; + this._stringMap[StringId.IDS_FIRMWARE_UPDATE_UNAVAILABLE] = StringId.IDS_PHONE_FIRMWARE_UPDATE_UNAVAILABLE; + this._stringMap[StringId.IDS_ASSOCIATE_ZUNE_OFFER_LOGGEDOUT] = StringId.IDS_PHONE_ASSOCIATE_ZUNE_OFFER_LOGGEDOUT; + this._stringMap[StringId.IDS_ASSOCIATE_ZUNE_OFFER_LOGGEDIN] = StringId.IDS_PHONE_ASSOCIATE_ZUNE_OFFER_LOGGEDIN; + this._stringMap[StringId.IDS_ASSOCIATE_ZUNE_OFFER_LOGGEDIN_YES] = StringId.IDS_PHONE_ASSOCIATE_ZUNE_OFFER_LOGGEDIN_YES; + this._stringMap[StringId.IDS_ASSOCIATED_ZUNE] = StringId.IDS_PHONE_ASSOCIATED_ZUNE; + this._stringMap[StringId.IDS_DELETE_DEVICE_BUTTON] = StringId.IDS_PHONE_DELETE_DEVICE_BUTTON; + this._stringMap[StringId.IDS_FORMAT_IN_PROGRESS] = StringId.IDS_PHONE_FORMAT_IN_PROGRESS; + this._stringMap[StringId.IDS_WIRELESS_SYNC_TEST_FAILED] = StringId.IDS_PHONE_WIRELESS_SYNC_TEST_FAILED; + this._stringMap[StringId.IDS_FORMAT_DIALOG_TEXT] = StringId.IDS_PHONE_FORMAT_DIALOG_TEXT; + this._stringMap[StringId.IDS_WIRELESS_SUGG_MAC_FILTERING] = StringId.IDS_PHONE_WIRELESS_SUGG_MAC_FILTERING; + this._stringMap[StringId.IDS_FIRMWARE_NEW_VERSION_OPTIONAL] = StringId.IDS_PHONE_FIRMWARE_NEW_VERSION_OPTIONAL; + this._stringMap[StringId.IDS_WIRELESS_ALREADY_CONFIGURED] = StringId.IDS_PHONE_WIRELESS_ALREADY_CONFIGURED; + this._stringMap[StringId.IDS_WIRELESS_DEVICE_BUSY] = StringId.IDS_PHONE_WIRELESS_DEVICE_BUSY; + this._stringMap[StringId.IDS_EULA_DIALOG_TITLE] = StringId.IDS_PHONE_EULA_DIALOG_TITLE; + this._stringMap[StringId.IDS_EULA_DIALOG_TITLE_REQUIRED] = StringId.IDS_PHONE_EULA_DIALOG_TITLE_REQUIRED; + this._stringMap[StringId.IDS_FIRMWARE_NEW_VERSION_REQUIRED] = StringId.IDS_PHONE_FIRMWARE_NEW_VERSION; + this._stringMap[StringId.IDS_EULA_DIALOG_TEXTAREA_TITLE] = StringId.IDS_PHONE_EULA_DIALOG_TEXTAREA_TITLE; + this._stringMap[StringId.IDS_FIRMWARE_UPDATE_AVAILABLE_TITLE] = StringId.IDS_PHONE_UPDATE_AVAILABLE_TITLE; + this._stringMap[StringId.IDS_SPACE_RESERVATION_DESCRIPTION] = StringId.IDS_PHONE_SPACE_RESERVATION_DESCRIPTION; + this._stringMap[StringId.IDS_SPACE_RESERVATION_DESCRIPTION_NO_FEATURES] = StringId.IDS_PHONE_SPACE_RESERVATION_DESCRIPTION_NO_MARKETPLACE; + this._stringMap[StringId.IDS_SPACE_RESERVATION_DESCRIPTION_NO_MARKETPLACE] = StringId.IDS_PHONE_SPACE_RESERVATION_DESCRIPTION_NO_MARKETPLACE; + this._stringMap[StringId.IDS_SPACE_RESERVATION_DESCRIPTION_NO_SOCIAL] = StringId.IDS_PHONE_SPACE_RESERVATION_DESCRIPTION; + this._stringMap[StringId.IDS_FIRMWARE_UPDATE_SUCCESS_NOTICE] = StringId.IDS_DEVICE_RESTORE_MAY_DISCONNECT; + this._stringMap[StringId.IDS_FIRMWARE_UPDATE_SUCCESS] = StringId.IDS_PHONE_UPDATE_SUCCESS; + this._stringMap[StringId.IDS_MUSIC_DEVICE_EMPTY] = StringId.IDS_PHONE_MUSIC_DEVICE_EMPTY; + this._stringMap[StringId.IDS_VIDEO_DEVICE_EMPTY] = StringId.IDS_PHONE_VIDEO_DEVICE_EMPTY; + this._stringMap[StringId.IDS_PHOTO_DEVICE_EMPTY] = StringId.IDS_PHONE_PHOTO_DEVICE_EMPTY; + this._stringMap[StringId.IDS_PLAYLIST_DEVICE_EMPTY_TITLE] = StringId.IDS_PHONE_PLAYLIST_DEVICE_EMPTY_TITLE; + this._stringMap[StringId.IDS_FIRMWARE_TRANSFERRING] = StringId.IDS_PHONE_FIRMWARE_TRANSFERRING; + this._stringMap[StringId.IDS_FIRMWARE_VERSION_PRE_TEXT] = StringId.IDS_PHONE_FIRMWARE_VERSION_PRE_TEXT; + this._stringMap[StringId.IDS_ASSOCIATE_YOUR_ZUNE_DESCRIPTION2] = StringId.IDS_PHONE_ASSOCIATE_YOUR_ZUNE_DESCRIPTION2; + this._stringMap[StringId.IDS_NO_SYNC_OPTIONS_INFO] = StringId.IDS_PHONE_NO_SYNC_OPTIONS_INFO; + this._stringMap[StringId.IDS_TRANSCODE_VIDEO_PLAYBACK_OPTION] = StringId.IDS_PHONE_TRANSCODE_VIDEO_PLAYBACK_OPTION; + this._stringMap[StringId.IDS_REMOVE_SINGLE_SYNC_GROUP_DIALOG_TEXT] = StringId.IDS_PHONE_REMOVE_SINGLE_SYNC_GROUP_DIALOG_TEXT; + this._stringMap[StringId.IDS_REMOVE_MULTIPLE_SYNC_GROUP_DIALOG_TEXT] = StringId.IDS_PHONE_REMOVE_MULTIPLE_SYNC_GROUP_DIALOG_TEXT; + this._stringMap[StringId.IDS_REMOVE_SYNC_ALL_GROUP_DIALOG_TEXT] = StringId.IDS_PHONE_REMOVE_SYNC_ALL_GROUP_DIALOG_TEXT; + this._stringMap[StringId.IDS_FIRMWARE_UPDATE_SUCCESS] = StringId.IDS_PHONE_FIRMWARE_UPDATE_SUCCESS; + this._stringMap[StringId.IDS_ENABLE_ZUNE_MARKETPLACE_TEXT] = StringId.IDS_PHONE_ENABLE_ZUNE_MARKETPLACE_TEXT; + this._stringMap[StringId.IDS_ENABLE_ZUNE_MARKETPLACE_OPTION] = StringId.IDS_PHONE_ENABLE_ZUNE_MARKETPLACE_OPTION; + this._stringMap[StringId.IDS_PICK_A_NAME_HEADER] = StringId.IDS_PHONE_PICK_A_NAME_HEADER; + this._stringMap[StringId.IDS_DISABLE_MARKETPLACE_BUTTON] = StringId.IDS_PHONE_DISABLE_MARKETPLACE_BUTTON; + this._stringMap[StringId.IDS_FIRMWARE_UPDATE_ERROR_NOTICE2] = StringId.IDS_PHONE_FIRMWARE_UPDATE_ERROR_NOTICE2; + this._stringMap[StringId.IDS_FIRMWARE_NEW_VERSION_REQUIRED] = StringId.IDS_PHONE_FIRMWARE_NEW_VERSION_REQUIRED; + this._stringMap[StringId.IDS_FIRMWARE_NOTICE] = StringId.IDS_PHONE_FIRMWARE_NOTICE; + this._stringMap[StringId.IDS_FIRMWARE_UPDATE_SUCCESS_NOTICE] = StringId.IDS_PHONE_FIRMWARE_UPDATE_SUCCESS_NOTICE; + this._stringMap[StringId.IDS_SYNC_CHAN_FRIEND_DISABLED_EXPLANATION] = StringId.IDS_PHONE_SYNC_CHAN_FRIEND_DISABLED_EXPLANATION; + this._stringMap[StringId.IDS_FIRMWARE_MANDATE] = StringId.IDS_PHONE_FIRMWARE_MANDATE; + this._stringMap[StringId.IDS_ZUNE_MARKETPLACE_LINKEDTO] = StringId.IDS_PHONE_ZUNE_MARKETPLACE_LINKEDTO; + this._stringMap[StringId.IDS_ENABLE_ZUNE_SOCIAL_TEXT_NO_MP] = StringId.IDS_PHONE_ENABLE_ZUNE_SOCIAL_TEXT_NO_MP; + this._stringMap[StringId.IDS_FRIENDS_EMPTY_DEVICE_HEADER] = StringId.IDS_PHONE_FRIENDS_EMPTY_DEVICE_HEADER; + this._stringMap[StringId.IDS_RENT_TARGET_DEVICE] = StringId.IDS_PHONE_RENT_TARGET_DEVICE; + this._stringMap[StringId.IDS_PODCAST_EMPTY_DEVICE_TITLE] = StringId.IDS_PHONE_PODCAST_EMPTY_DEVICE_TITLE; + this._stringMap[StringId.IDS_CHANNELS_EMPTY_DEVICE_TITLE] = StringId.IDS_PHONE_CHANNELS_EMPTY_DEVICE_TITLE; + this._stringMap[StringId.IDS_DEVICE_UP_TO_DATE] = StringId.IDS_PHONE_DEVICE_UP_TO_DATE; + this._stringMap[StringId.IDS_DEVICE_NAME_EMPTY] = StringId.IDS_PHONE_DEVICE_NAME_EMPTY; + this._stringMap[StringId.IDS_ITEMS_SYNCED_DESCRIPTION] = StringId.IDS_PHONE_ITEMS_SYNCED_DESCRIPTION; + this._stringMap[StringId.IDS_ITEMS_REMAINING_DESCRIPTION] = StringId.IDS_PHONE_ITEMS_REMAINING_DESCRIPTION; + this._stringMap[StringId.IDS_DEVICE_SETTINGS_NAME] = StringId.IDS_PHONE_DEVICE_SETTINGS_NAME; + this._stringMap[StringId.IDS_ALL_SYNCED_ITEMS] = StringId.IDS_PHONE_ALL_SYNCED_ITEMS; + this._stringMap[StringId.IDS_COMPUTER_ICON_DROP_TARGET_TOOLTIP] = StringId.IDS_PHONE_COMPUTER_ICON_DROP_TARGET_TOOLTIP; + this._stringMap[StringId.IDS_ALL_PICTURE_ITEMS] = StringId.IDS_PHONE_ALL_PICTURE_ITEMS; + this._stringMap[StringId.IDS_ALL_PODCAST_ITEMS] = StringId.IDS_PHONE_ALL_PODCAST_ITEMS; + this._stringMap[StringId.IDS_DEVICE_HUNG] = StringId.IDS_PHONE_DEVICE_HUNG; + this._stringMap[StringId.IDS_OUT_OF_SPACE_GAS_GAUGE_FORMAT] = StringId.IDS_PHONE_OUT_OF_SPACE_GAS_GAUGE_FORMAT; + this._stringMap[StringId.IDS_GUEST_OUT_OF_SPACE_MESSAGE] = StringId.IDS_PHONE_GUEST_OUT_OF_SPACE_MESSAGE; + this._stringMap[StringId.IDS_DEVICE_STATUS_SOCIAL_DESC_NO_ASSOC] = StringId.IDS_PHONE_DEVICE_STATUS_SOCIAL_DESC_NO_ASSOC; + this._stringMap[StringId.IDS_NOT_OUT_OF_SPACE_GAS_GAUGE_FORMAT] = StringId.IDS_PHONE_NOT_OUT_OF_SPACE_GAS_GAUGE_FORMAT; + this._stringMap[StringId.IDS_DEVICE_STATUS_SOCIAL_DESC_ASSOC] = StringId.IDS_PHONE_DEVICE_STATUS_SOCIAL_DESC_ASSOC; + this._stringMap[StringId.IDS_DEVICE_SUMMARY_DEVICE_UPDATE_TITLE] = StringId.IDS_PHONE_DEVICE_SUMMARY_DEVICE_UPDATE_TITLE; + this._stringMap[StringId.IDS_DEVICE_RENTAL_GUEST_NOT_SUPPORTED] = StringId.IDS_PHONE_DEVICE_RENTAL_GUEST_NOT_SUPPORTED; + this._stringMap[StringId.IDS_HOW_TO_SYNC_TO_ZUNE_DEVICES] = StringId.IDS_HOW_TO_SYNC_TO_PHONE_DEVICES; + this._stringMap[StringId.IDS_DEVICE_PIVOT] = StringId.IDS_PHONE_PIVOT; + this._stringMap[StringId.IDS_ITEMS_SYNCED_TITLE] = StringId.IDS_PHONE_ITEMS_SYNCED_TITLE; + this._stringMap[StringId.IDS_ITEMS_REMAINING_TITLE] = StringId.IDS_PHONE_ITEMS_REMAINING_TITLE; + this._stringMap[StringId.IDS_ITEMS_REMOVED_TITLE] = StringId.IDS_PHONE_ITEMS_REMOVED_TITLE; + this._stringMap[StringId.IDS_ITEMS_FAILED_TITLE] = StringId.IDS_PHONE_ITEMS_FAILED_TITLE; + this._stringMap[StringId.IDS_NAME_ZUNE_HEADER] = StringId.IDS_NAME_PHONE_HEADER; + this._stringMap[StringId.IDS_DEVICE_SUMMARY_AVAILABLE_FW_VERSION_HEADER] = StringId.IDS_DEVICE_SUMMARY_AVAILABLE_UPDATE_HEADER; + } + } +} diff --git a/ZuneUI/PhoneNumberDescriptors.cs b/ZuneUI/PhoneNumberDescriptors.cs new file mode 100644 index 0000000..4e5c7cd --- /dev/null +++ b/ZuneUI/PhoneNumberDescriptors.cs @@ -0,0 +1,69 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PhoneNumberDescriptors +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text; + +namespace ZuneUI +{ + public class PhoneNumberDescriptors : CountryFieldValidationPropertyDescriptor + { + public PhoneNumberDescriptors(string name, CountryFieldValidatorType type) + : base(name, type) + { + } + + public bool Split(string value, out string areaCode, out string number) + { + value = PhoneNumberDescriptors.RemoveNonDigits(value); + if (value.Length >= 10) + { + number = value.Substring(value.Length - 7, 7); + areaCode = value.Substring(value.Length - 10, 3); + return true; + } + areaCode = string.Empty; + number = string.Empty; + return false; + } + + public string Combine(string areaCode, string number) + { + string str = (string)null; + if (!string.IsNullOrEmpty(number)) + { + StringBuilder stringBuilder = new StringBuilder(); + if (!string.IsNullOrEmpty(areaCode)) + { + stringBuilder.Append(areaCode); + stringBuilder.Append('-'); + } + if (number.Length >= 7) + { + stringBuilder.Append(number.Substring(0, 3)); + stringBuilder.Append('-'); + stringBuilder.Append(number.Substring(3)); + } + else + stringBuilder.Append(number); + str = stringBuilder.ToString(); + } + return str; + } + + private static string RemoveNonDigits(string value) + { + if (value == null) + return string.Empty; + StringBuilder stringBuilder = new StringBuilder(value.Length); + for (int index = 0; index < value.Length; ++index) + { + if (char.IsDigit(value[index])) + stringBuilder.Append(value[index]); + } + return stringBuilder.ToString(); + } + } +} diff --git a/ZuneUI/PhotoDetails.cs b/ZuneUI/PhotoDetails.cs new file mode 100644 index 0000000..0346149 --- /dev/null +++ b/ZuneUI/PhotoDetails.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PhotoDetails +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class PhotoDetails + { + private static int[] ColumnIndexes = new int[8] + { + 344, + 177, + 317, + 181, + 175, + (int) byte.MaxValue, + 254, + 68 + }; + private static string[] DataProperties = new string[8] + { + "Title", + "MediaType", + "ImagePath", + "FolderName", + "FileName", + "Width", + "Height", + "Copyright" + }; + + public static void Populate(object dataContainer, int libraryId) + { + DataProviderObject dataProviderObject = (DataProviderObject)dataContainer; + object[] fieldValues = new object[8] + { + (object) string.Empty, + (object) 0, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) 0, + (object) 0, + (object) string.Empty + }; + ZuneLibrary.GetFieldValues(libraryId, EListType.ePhotoList, PhotoDetails.ColumnIndexes.Length, PhotoDetails.ColumnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + for (int index = 0; index < PhotoDetails.ColumnIndexes.Length; ++index) + { + if (PhotoDetails.ColumnIndexes[index] == 177) + fieldValues[index] = (object)MediaDescriptions.Map((MediaType)fieldValues[index]); + dataProviderObject.SetProperty(PhotoDetails.DataProperties[index], fieldValues[index]); + } + } + } +} diff --git a/ZuneUI/PhotoFolderPanel.cs b/ZuneUI/PhotoFolderPanel.cs new file mode 100644 index 0000000..a483863 --- /dev/null +++ b/ZuneUI/PhotoFolderPanel.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PhotoFolderPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class PhotoFolderPanel : ListPanel + { + public PhotoFolderPanel(PhotoLibraryPage library) + : base((IModelItemOwner)library) + { + } + + protected PhotoLibraryPage LibraryPage => base.LibraryPage as PhotoLibraryPage; + + public override IList SelectedLibraryIds + { + get => this.LibraryPage.SelectedPhotoIds; + set => this.LibraryPage.SelectedPhotoIds = value; + } + } +} diff --git a/ZuneUI/PhotoLibraryPage.cs b/ZuneUI/PhotoLibraryPage.cs new file mode 100644 index 0000000..c25c5b2 --- /dev/null +++ b/ZuneUI/PhotoLibraryPage.cs @@ -0,0 +1,720 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PhotoLibraryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Security; +using System.Threading; +using UIXControls; + +namespace ZuneUI +{ + public class PhotoLibraryPage : LibraryPage, ISlideShowStateOwner, INotifyPropertyChanged + { + private string _invalidPathCharacters; + private PhotosPanel _photosPanel; + private PhotoFolderPanel _photoFolderPanel; + private IList _selectedPhotoIds; + private Dictionary _expandedFolderIds; + private Dictionary _refreshFolderIds; + private Dictionary _foldersToMonitor; + private int _folderId; + private int _deviceRootFolderId = -1; + private int _deviceCameraRollFolderId = -1; + private int _deviceSavedFolderId = -1; + private int _deviceParentFolderId = -1; + private int _libraryDefaultSaveFolderId = -1; + private SlideShowState _slideShowState; + private Command _deleteCommand; + private Command _refreshPictures; + private Command _editCommand; + private Command _createCommand; + private Command _deleteFromDeviceCommand; + private int _actionDepth; + private int _pendingFolderToExpandToRoot; + private int _pendingFolderDeleteId; + private int _pendingFolderId; + private string _photoSort; + private bool _hasSelectedFolder; + + public PhotoLibraryPage() + : this(false) + { + } + + public PhotoLibraryPage(bool showDevice) + : base(showDevice, MediaType.Photo) + { + this.UI = PhotoLibraryPage.LibraryTemplate; + this.UIPath = "Collection\\Photos"; + if (showDevice) + { + this.PivotPreference = ZuneUI.Shell.MainFrame.Device.Photos; + Deviceland.InitDevicePage((ZunePage)this); + } + else + this.PivotPreference = ZuneUI.Shell.MainFrame.Collection.Photos; + this.IsRootPage = true; + this._photosPanel = new PhotosPanel(this); + this._photoFolderPanel = new PhotoFolderPanel(this); + this.ShowPlaylistIcon = false; + this.TransportControlStyle = TransportControlStyle.Photo; + this._slideShowState = new SlideShowState((IModelItemOwner)this); + this._expandedFolderIds = new Dictionary(); + this._refreshFolderIds = new Dictionary(); + this._refreshPictures = new Command(); + this._pendingFolderToExpandToRoot = -1; + this._pendingFolderDeleteId = -1; + this._pendingFolderId = -1; + } + + public PhotosPanel PhotosPanel => this._photosPanel; + + public PhotoFolderPanel PhotoFolderPanel => this._photoFolderPanel; + + public SlideShowState SlideShowState => this._slideShowState; + + public IList SelectedPhotoIds + { + get => this._selectedPhotoIds; + set + { + if (this._selectedPhotoIds == value) + return; + this._selectedPhotoIds = value; + this.FirePropertyChanged(nameof(SelectedPhotoIds)); + } + } + + public Command RefreshPictures => this._refreshPictures; + + public void ScrollToFolder() + { + this.FirePropertyChanged("ScrollingToFolder"); + if (this.ScrollingToFolder == null) + return; + this.ScrollingToFolder((object)this, new EventArgs()); + } + + public void ExpandFolder(int id) + { + if (this._expandedFolderIds.ContainsKey(id)) + return; + this._expandedFolderIds.Add(id, true); + this.FirePropertyChanged("ExpandedFolders"); + if (this.ExpandedFolders == null) + return; + this.ExpandedFolders((object)this, new EventArgs()); + } + + public void CollapseFolder(int id) + { + if (!this._expandedFolderIds.ContainsKey(id)) + return; + this._expandedFolderIds.Remove(id); + this.FirePropertyChanged("ExpandedFolders"); + if (this.ExpandedFolders == null) + return; + this.ExpandedFolders((object)this, new EventArgs()); + } + + public bool FolderIsExpanded(int id) => this._expandedFolderIds.ContainsKey(id); + + public void ToggleFolder(int id) + { + if (this.FolderIsExpanded(id)) + this.CollapseFolder(id); + else + this.ExpandFolder(id); + } + + public void RefreshFolder(int id) + { + if (this._refreshFolderIds.ContainsKey(id)) + return; + this._refreshFolderIds.Add(id, true); + this.FirePropertyChanged("RefreshingFolders"); + if (this.RefreshingFolders == null) + return; + this.RefreshingFolders((object)this, new EventArgs()); + } + + public bool FolderHasRefreshPending(int id) => this._refreshFolderIds.ContainsKey(id); + + public void RefreshedFolder(int id) + { + if (!this._refreshFolderIds.ContainsKey(id)) + return; + this._refreshFolderIds.Remove(id); + } + + public bool HasSelectedFolder + { + get => this._hasSelectedFolder; + set => this._hasSelectedFolder = value; + } + + public int FolderId + { + get => this._folderId; + set + { + if (this._folderId == value) + return; + this._folderId = value; + this.HasSelectedFolder = true; + this.FirePropertyChanged(nameof(FolderId)); + } + } + + public int DeviceCameraRollFolderId + { + get => this._deviceCameraRollFolderId; + set + { + if (this._deviceCameraRollFolderId == value) + return; + this._deviceCameraRollFolderId = value; + this.FirePropertyChanged(nameof(DeviceCameraRollFolderId)); + } + } + + public int DeviceSavedFolderId + { + get => this._deviceSavedFolderId; + set + { + if (this._deviceSavedFolderId == value) + return; + this._deviceSavedFolderId = value; + this.FirePropertyChanged(nameof(DeviceSavedFolderId)); + } + } + + public int DeviceParentFolderId + { + get => this._deviceParentFolderId; + set + { + if (this._deviceParentFolderId == value) + return; + this._deviceParentFolderId = value; + this.FirePropertyChanged(nameof(DeviceParentFolderId)); + } + } + + public int DeviceRootFolderId + { + get => this._deviceRootFolderId; + set + { + if (this._deviceRootFolderId == value) + return; + this._deviceRootFolderId = value; + this.FirePropertyChanged(nameof(DeviceRootFolderId)); + } + } + + public int LibraryRootFolderId => 0; + + public int LibraryDefaultSaveFolderId + { + get => this._libraryDefaultSaveFolderId; + set + { + if (this._libraryDefaultSaveFolderId == value) + return; + this._libraryDefaultSaveFolderId = value; + this.FirePropertyChanged(nameof(LibraryDefaultSaveFolderId)); + } + } + + public Command DeleteCommand + { + get => this._deleteCommand; + set + { + if (this._deleteCommand == value) + return; + this._deleteCommand = value; + this.FirePropertyChanged(nameof(DeleteCommand)); + } + } + + public Command EditCommand + { + get => this._editCommand; + set + { + if (this._editCommand == value) + return; + this._editCommand = value; + this.FirePropertyChanged(nameof(EditCommand)); + } + } + + public Command CreateCommand + { + get => this._createCommand; + set + { + if (this._createCommand == value) + return; + this._createCommand = value; + this.FirePropertyChanged(nameof(CreateCommand)); + } + } + + public Command DeleteFromDeviceCommand + { + get => this._deleteFromDeviceCommand; + set + { + if (this._deleteFromDeviceCommand == value) + return; + this._deleteFromDeviceCommand = value; + this.FirePropertyChanged(nameof(DeleteFromDeviceCommand)); + } + } + + public int ActionDepth + { + get => this._actionDepth; + set + { + if (this._actionDepth == value) + return; + this._actionDepth = value; + this.FirePropertyChanged(nameof(ActionDepth)); + } + } + + public int PendingFolderToDelete + { + get => this._pendingFolderDeleteId; + set + { + if (this._pendingFolderDeleteId == value) + return; + this._pendingFolderDeleteId = value; + this.FirePropertyChanged(nameof(PendingFolderToDelete)); + } + } + + public int PendingFolderToEdit + { + get => this._pendingFolderId; + set + { + if (this._pendingFolderId == value) + return; + this._pendingFolderId = value; + this.FirePropertyChanged(nameof(PendingFolderToEdit)); + } + } + + public int PendingFolderToExpandToRoot + { + get => this._pendingFolderToExpandToRoot; + set + { + if (this._pendingFolderToExpandToRoot == value) + return; + this._pendingFolderToExpandToRoot = value; + this.FirePropertyChanged(nameof(PendingFolderToExpandToRoot)); + } + } + + public string PhotoSort + { + get => this._photoSort; + set + { + if (!(this._photoSort != value)) + return; + this._photoSort = value; + this.FirePropertyChanged(nameof(PhotoSort)); + } + } + + public string GetNextAvailableAlbumName(IList childList) + { + if (childList == null) + return ZuneUI.Shell.LoadString(StringId.IDS_NEW_ALBUM_NAME); + Dictionary dictionary = new Dictionary(); + foreach (DataProviderObject child in (IEnumerable)childList) + dictionary.Add(((string)child.GetProperty("Title")).ToLowerInvariant(), true); + string str1 = string.Empty; + for (int index = 1; index < int.MaxValue; ++index) + { + string empty = string.Empty; + string str2 = index != 1 ? string.Format(ZuneUI.Shell.LoadString(StringId.IDS_NEW_ALBUM_NAME_MULTIPLE), (object)index) : ZuneUI.Shell.LoadString(StringId.IDS_NEW_ALBUM_NAME); + if (!dictionary.ContainsKey(str2.ToLowerInvariant())) + { + str1 = str2; + break; + } + } + return str1; + } + + private Dictionary GetFoldersToMonitor( + IList paths, + ref string fileParentFolder) + { + Management management = ZuneShell.DefaultInstance.Management; + Dictionary dictionary = new Dictionary(); + bool flag = false; + foreach (object path in (IEnumerable)paths) + { + string str = path as string; + if (!string.IsNullOrEmpty(str) && !dictionary.ContainsKey(str)) + { + if (Directory.Exists(str)) + { + if (!management.IsMonitored(management.MonitoredPhotoFolders, str)) + dictionary.Add(str, true); + } + else if (!flag) + { + try + { + FileInfo fileInfo = new FileInfo(str); + fileParentFolder = fileInfo.DirectoryName; + flag = true; + } + catch + { + } + } + } + } + return dictionary; + } + + public override void CheckCanAddMedia(IList filenames) + { + this.CanAddMedia = false; + if (this.ShowDeviceContents || filenames == null || filenames.Count == 0) + return; + Management management = ZuneShell.DefaultInstance.Management; + List stringList = new List(); + string empty = string.Empty; + if (this.GetFoldersToMonitor(filenames, ref empty).Keys.Count > 0) + this.CanAddMedia = true; + else if (string.IsNullOrEmpty(empty) || management.IsMonitored(management.MonitoredPhotoFolders, empty)) + { + this.CanAddMedia = false; + } + else + { + foreach (string filename in (IEnumerable)filenames) + stringList.Add(filename); + base.CheckCanAddMedia((IList)stringList); + } + } + + public override void AddMedia(IList filenames) + { + if (this.ShowDeviceContents || filenames == null || filenames.Count == 0) + return; + string empty = string.Empty; + this._foldersToMonitor = this.GetFoldersToMonitor(filenames, ref empty); + if (!string.IsNullOrEmpty(empty)) + this._foldersToMonitor[empty] = true; + Command yesCommand = new Command((IModelItemOwner)this); + yesCommand.Invoked += (EventHandler)delegate + { + if (this._foldersToMonitor == null || this._foldersToMonitor.Count == 0) + return; + List stringList = new List((IEnumerable)this._foldersToMonitor.Keys); + stringList.Sort((IComparer)StringComparer.CurrentCultureIgnoreCase); + Management management = ZuneShell.DefaultInstance.Management; + foreach (string path in stringList) + { + if (management.UsingWin7Libraries) + Win7ShellManager.Instance.AddLocationToLibrary(EWin7LibraryKind.ePicturesLibrary, false, path); + else + management.AddMonitoredFolder(management.MonitoredPhotoFolders, path, true); + } + }; + yesCommand.Description = ZuneUI.Shell.LoadString(StringId.IDS_PHOTO_ADD_FOLDER_BUTTON); + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_PHOTO_ADD_FOLDER_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_PHOTO_ADD_FOLDER_DESCRIPTION), yesCommand, (Command)null, (BooleanChoice)null); + } + + protected override void OnNavigatedAwayWorker(IPage destination) + { + this._deviceCameraRollFolderId = -1; + this._deviceSavedFolderId = -1; + this._deviceRootFolderId = -1; + this._libraryDefaultSaveFolderId = -1; + base.OnNavigatedAwayWorker(destination); + } + + protected override void OnNavigatedToWorker() + { + if (this.NavigationArguments != null) + { + int nMediaId = -1; + int nFolderId = -1; + if (this.NavigationArguments.Contains((object)"PhotoLibraryId")) + nMediaId = (int)this.NavigationArguments[(object)"PhotoLibraryId"]; + if (this.NavigationArguments.Contains((object)"FolderId")) + { + int navigationArgument = (int)this.NavigationArguments[(object)"FolderId"]; + if (navigationArgument > -1) + nFolderId = navigationArgument; + } + this._selectedPhotoIds = (IList)null; + if (nMediaId > -1) + this._selectedPhotoIds = (IList)new int[1] + { + nMediaId + }; + if (nMediaId > -1 && nFolderId == -1) + { + PhotoManager.Instance.FindPhotoContainer(nMediaId, out nFolderId); + this.PendingFolderToExpandToRoot = nFolderId; + } + if (nFolderId > -1) + { + this.PendingFolderToExpandToRoot = nFolderId; + this.FolderId = nFolderId; + } + this.NavigationArguments = (IDictionary)null; + } + base.OnNavigatedToWorker(); + } + + public static void FindInCollection(int folderId, int photoId) + { + if (photoId >= 0 && folderId < 0) + folderId = -1; + Hashtable hashtable = new Hashtable(); + hashtable.Add((object)"FolderId", (object)folderId); + if (photoId >= 0) + hashtable.Add((object)"PhotoLibraryId", (object)photoId); + ZuneShell.DefaultInstance.Execute("Collection\\Photos", (IDictionary)hashtable); + } + + public override IPageState SaveAndRelease() + { + this._photosPanel.Release(); + this._photoFolderPanel.Release(); + return base.SaveAndRelease(); + } + + public void Rename(DataProviderObject source, string folderName) + { + if (string.IsNullOrEmpty(folderName) || source == null || source.TypeName != "MediaFolder") + return; + int id = (int)source.GetProperty("LibraryId"); + if (id <= 0) + return; + int parentId = (int)source.GetProperty("ParentId"); + if (parentId < 0) + return; + string property = (string)source.GetProperty("FolderPath"); + if (!Directory.Exists(property)) + return; + try + { + if (string.Compare(new DirectoryInfo(property).Name, folderName, StringComparison.CurrentCulture) == 0) + return; + } + catch (SecurityException ex) + { + } + catch (ArgumentException ex) + { + return; + } + ZuneShell.DefaultInstance.Management.RemoveChildMonitoredFolders(property, true); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!PhotoManager.Instance.RenameFolder(id, folderName).IsSuccess) + return; + this.RefreshFolder(parentId); + this.RefreshPictures.Invoke(); + }, (object)null); + } + + public void MoveFolder(DataProviderObject source, DataProviderObject target) + { + if (source == null || target == null || (source.TypeName != "MediaFolder" || target.TypeName != "MediaFolder")) + return; + int property1 = (int)source.GetProperty("LibraryId"); + if (property1 <= 0) + return; + int property2 = (int)source.GetProperty("ParentId"); + if (property2 < 0) + return; + int property3 = (int)target.GetProperty("LibraryId"); + if (property3 <= 0) + return; + string property4 = (string)source.GetProperty("FolderPath"); + string property5 = (string)target.GetProperty("FolderPath"); + this.MoveFolder(property1, property2, property4, property3, property5); + } + + private void MoveFolder( + int sourceId, + int sourceParentId, + string sourceFolderPath, + int targetId, + string targetFolderPath) + { + if (sourceId <= 0 || !Directory.Exists(sourceFolderPath)) + return; + ZuneShell.DefaultInstance.Management.RemoveChildMonitoredFolders(sourceFolderPath, true); + int[] sourceIds = new int[1] { sourceId }; + string resultantFolderPath = Path.Combine(targetFolderPath, Path.GetFileName(sourceFolderPath)); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!PhotoManager.Instance.Move(sourceIds, EMediaTypes.eMediaTypeFolder, targetId).IsSuccess) + return; + ZuneApplication.ZuneLibrary.AddGrovelerScanDirectory(sourceFolderPath, EMediaTypes.eMediaTypeImage); + this.RefreshFolder(sourceParentId); + ZuneApplication.ZuneLibrary.AddGrovelerScanDirectory(resultantFolderPath, EMediaTypes.eMediaTypeImage); + this.RefreshFolder(targetId); + }, (object)null); + } + + public void Import(IList shellItems, int destinationFolderId) + { + foreach (object shellItem in (IEnumerable)shellItems) + { + string path = shellItem as string; + if (!string.IsNullOrEmpty(path) && destinationFolderId > 0) + { + if (File.Exists(path) && ZuneApplication.ZuneLibrary.CanAddMedia(path, EMediaTypes.eMediaTypeImage)) + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + PhotoManager.Instance.Import(path, EMediaTypes.eMediaTypeImage, destinationFolderId); + this.FolderId = destinationFolderId; + this.RefreshPictures.Invoke(); + }, (object)null); + else if (Directory.Exists(path)) + { + if (this.FindFolder(path) > 0) + ZuneShell.DefaultInstance.Management.RemoveChildMonitoredFolders(path, true); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!PhotoManager.Instance.Import(path, EMediaTypes.eMediaTypeFolder, destinationFolderId).IsSuccess || destinationFolderId <= 0) + return; + ZuneApplication.ZuneLibrary.AddGrovelerScanDirectory(path, EMediaTypes.eMediaTypeImage); + this.FolderId = destinationFolderId; + this.RefreshFolder(destinationFolderId); + this.ExpandFolder(destinationFolderId); + }, (object)null); + } + } + } + } + + public static bool DeleteFolder(DataProviderObject folderItem) + { + if (folderItem == null || folderItem.TypeName != "MediaFolder") + return false; + int property = (int)folderItem.GetProperty("LibraryId"); + if (property <= 0) + return false; + if (ZuneShell.DefaultInstance.Management.RemoveChildMonitoredFolders((string)folderItem.GetProperty("FolderPath"), true)) + Thread.Sleep(500); + return ZuneApplication.ZuneLibrary.DeleteFilesystemFolder(property, EMediaTypes.eMediaTypeImage); + } + + public void MovePhotos(IList sourceDataProviderList, int targetId) + { + int[] sourceIds = new int[sourceDataProviderList.Count]; + for (int index = 0; index < sourceDataProviderList.Count; ++index) + { + DataProviderObject sourceDataProvider = (DataProviderObject)sourceDataProviderList[index]; + sourceIds[index] = (int)sourceDataProvider.GetProperty("LibraryId"); + } + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + PhotoManager.Instance.Move(sourceIds, EMediaTypes.eMediaTypeImage, targetId); + this.RefreshPictures.Invoke(); + }, (object)null); + } + + public int CreateFolder(string name, int targetId) + { + int nCreatedFolderId = 0; + PhotoManager.Instance.CreateFolder(name, targetId, out nCreatedFolderId); + return nCreatedFolderId; + } + + public int FindFolder(string folderName) + { + int nFolderId; + return !PhotoManager.Instance.FindFolder(folderName, out nFolderId).IsSuccess ? -1 : nFolderId; + } + + public bool CanDropShellFolder(string treePath, string dropPath) + { + try + { + if (!Directory.Exists(treePath) || !Directory.Exists(dropPath)) + return false; + DirectoryInfo directoryInfo1 = new DirectoryInfo(treePath); + DirectoryInfo directoryInfo2 = new DirectoryInfo(dropPath); + if ((directoryInfo1.FullName + (object)Path.DirectorySeparatorChar).IndexOf(directoryInfo2.FullName + (object)Path.DirectorySeparatorChar, StringComparison.CurrentCultureIgnoreCase) >= 0) + return false; + if (string.Compare(directoryInfo1.FullName, directoryInfo2.Parent.FullName, StringComparison.CurrentCultureIgnoreCase) == 0) + return false; + } + catch + { + return false; + } + return true; + } + + public string GetInvalidPathCharacters() + { + if (string.IsNullOrEmpty(this._invalidPathCharacters)) + { + char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); + if (invalidFileNameChars != null && invalidFileNameChars.Length > 0) + { + bool flag = true; + for (int index = 0; index < invalidFileNameChars.Length; ++index) + { + if (!char.IsControl(invalidFileNameChars[index])) + { + if (flag) + { + this._invalidPathCharacters = invalidFileNameChars[index].ToString(); + flag = false; + } + else + this._invalidPathCharacters += string.Format(" {0}", (object)invalidFileNameChars[index]); + } + } + } + } + return this._invalidPathCharacters; + } + + public bool ValidateFilename(string filename) => !string.IsNullOrEmpty(filename) && filename.IndexOfAny(Path.GetInvalidFileNameChars()) == -1; + + public event EventHandler ExpandedFolders; + + public event EventHandler RefreshingFolders; + + public event EventHandler ScrollingToFolder; + + private static string LibraryTemplate => "res://ZuneShellResources!PhotoLibrary.uix#PhotoLibrary"; + } +} diff --git a/ZuneUI/PhotoNavigationCommandHandler.cs b/ZuneUI/PhotoNavigationCommandHandler.cs new file mode 100644 index 0000000..b266411 --- /dev/null +++ b/ZuneUI/PhotoNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PhotoNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class PhotoNavigationCommandHandler : DeviceAwareNavigationHandler + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new PhotoLibraryPage(this.ShowDeviceContents); + } +} diff --git a/ZuneUI/PhotoUtilities.cs b/ZuneUI/PhotoUtilities.cs new file mode 100644 index 0000000..ece419b --- /dev/null +++ b/ZuneUI/PhotoUtilities.cs @@ -0,0 +1,175 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PhotoUtilities +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Win32; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Xml; + +namespace ZuneUI +{ + public static class PhotoUtilities + { + public static bool IsPhotoGalleryInstalled => InstalledProductChecker.IsInstalled(ClientConfiguration.Pictures.WinLivePhotoGalleryUpgradeCode, ClientConfiguration.Pictures.WinLivePhotoGalleryMajorVersion, ClientConfiguration.Pictures.WinLivePhotoGalleryMinorVersion); + + public static string PhotoGalleryExecutablePath + { + get + { + string empty1 = string.Empty; + try + { + string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), Shell.LoadString(StringId.IDS_PHOTOS_PHOTO_GALLERY_PATH)); + if (File.Exists(path)) + return path; + } + catch (Exception ex) + { + } + string empty2 = string.Empty; + try + { + string path = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles(x86)"), Shell.LoadString(StringId.IDS_PHOTOS_PHOTO_GALLERY_PATH)); + if (File.Exists(path)) + return path; + } + catch (Exception ex) + { + } + return string.Empty; + } + } + + public static bool IsMovieMakerInstalled => InstalledProductChecker.IsInstalled(ClientConfiguration.Pictures.WinLiveMovieMakerUpgradeCode, ClientConfiguration.Pictures.WinLiveMovieMakerMajorVersion, ClientConfiguration.Pictures.WinLiveMovieMakerMinorVersion); + + public static string MovieMakerExecutablePath + { + get + { + string str = string.Empty; + try + { + string path1 = (string)((Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows Live\\Movie Maker") ?? Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node\\Microsoft\\Windows Live\\Movie Maker")) ?? throw new Exception("Could not open registry key")).GetValue("InstallLocation", (object)string.Empty); + if (!string.IsNullOrEmpty(path1)) + str = Path.Combine(path1, "MovieMaker.exe"); + } + catch (Exception ex) + { + } + return str; + } + } + + public static void PlaySlideShow(int folderId, int startIndex) => PhotoUtilities.PlaySlideShow(folderId, string.Empty, startIndex); + + public static void PlaySlideShow(int folderId, string sort, int startIndex) + { + SlideShowState slideShowState = new SlideShowState((IModelItemOwner)null); + SlideshowLand slideshowLand = new SlideshowLand(); + slideshowLand.SlideShowState = slideShowState; + slideShowState.Sort = sort; + slideShowState.Index = startIndex >= 0 ? startIndex : 0; + slideShowState.FolderId = folderId; + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)slideshowLand); + } + + public static void ViewInPhotoGallery(string path) + { + if (!PhotoUtilities.IsPhotoGalleryAvailable) + return; + try + { + string str = string.Empty; + if (!string.IsNullOrEmpty(path)) + str = !File.Exists(path) ? string.Format(Shell.LoadString(StringId.IDS_PHOTOS_PHOTO_GALLERY_OPEN_FOLDER), (object)path, (object)path) : string.Format(Shell.LoadString(StringId.IDS_PHOTOS_PHOTO_GALLERY_OPEN_FILE), (object)Path.GetDirectoryName(path), (object)path); + if (string.IsNullOrEmpty(PhotoUtilities.PhotoGalleryExecutablePath)) + return; + new Process() + { + StartInfo = { + FileName = PhotoUtilities.PhotoGalleryExecutablePath, + WorkingDirectory = Path.GetDirectoryName(PhotoUtilities.PhotoGalleryExecutablePath), + Arguments = str + } + }.Start(); + SQMLog.Log(SQMDataId.LaunchWLPG, 1); + } + catch (FileNotFoundException ex) + { + } + catch (Win32Exception ex) + { + } + } + + public static bool IsPhotoGalleryAvailable => !OSVersion.IsXP() && PhotoUtilities.IsPhotoGalleryInstalled; + + public static bool IsMovieMakerAvailable => !OSVersion.IsXP() && PhotoUtilities.IsMovieMakerInstalled; + + public static string WriteMovieMakerMedia(IList mediaFiles) + { + string path2 = Guid.NewGuid().ToString() + ".xml"; + string outputFileName = Path.Combine(Path.GetTempPath(), path2); + using (XmlWriter xmlWriter = XmlWriter.Create(outputFileName, new XmlWriterSettings() + { + Indent = true + })) + { + xmlWriter.WriteStartElement("MovieMaker"); + xmlWriter.WriteStartElement("Content"); + foreach (string mediaFile in (IEnumerable)mediaFiles) + { + xmlWriter.WriteStartElement("ContentFile"); + xmlWriter.WriteAttributeString("Filename", mediaFile); + xmlWriter.WriteEndElement(); + } + xmlWriter.WriteEndElement(); + xmlWriter.WriteStartElement("AutoEdit"); + xmlWriter.WriteAttributeString("Style", "FadeReveal"); + xmlWriter.WriteEndElement(); + xmlWriter.WriteStartElement("DeleteOnClose"); + xmlWriter.WriteEndElement(); + xmlWriter.WriteEndElement(); + xmlWriter.Flush(); + } + return outputFileName; + } + + public static void LaunchMovieMaker(IList mediaFiles) + { + if (!PhotoUtilities.IsMovieMakerAvailable) + return; + string str = PhotoUtilities.WriteMovieMakerMedia(mediaFiles); + string format = Shell.LoadString(StringId.IDS_PHOTOS_MOVIE_MAKER_ARGS); + try + { + if (string.IsNullOrEmpty(PhotoUtilities.MovieMakerExecutablePath)) + return; + new Process() + { + StartInfo = { + FileName = PhotoUtilities.MovieMakerExecutablePath, + WorkingDirectory = Path.GetDirectoryName(PhotoUtilities.MovieMakerExecutablePath), + Arguments = string.Format(format, (object) str) + } + }.Start(); + SQMLog.Log(SQMDataId.LaunchMovieMaker, 1); + } + catch (FileNotFoundException ex) + { + } + catch (Win32Exception ex) + { + } + } + } +} diff --git a/ZuneUI/PhotosPanel.cs b/ZuneUI/PhotosPanel.cs new file mode 100644 index 0000000..229033c --- /dev/null +++ b/ZuneUI/PhotosPanel.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PhotosPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class PhotosPanel : ListPanel + { + public PhotosPanel(PhotoLibraryPage library) + : base((IModelItemOwner)library) + { + } + + protected PhotoLibraryPage LibraryPage => base.LibraryPage as PhotoLibraryPage; + + public override IList SelectedLibraryIds + { + get => this.LibraryPage.SelectedPhotoIds; + set => this.LibraryPage.SelectedPhotoIds = value; + } + } +} diff --git a/ZuneUI/PinHelper.cs b/ZuneUI/PinHelper.cs new file mode 100644 index 0000000..2db966b --- /dev/null +++ b/ZuneUI/PinHelper.cs @@ -0,0 +1,86 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PinHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class PinHelper + { + public static int AddPin(int id, EMediaTypes mediaType, int userId) => PinHelper.AddPin(EPinType.ePinTypeGeneric, -1, id, mediaType, userId); + + public static int AddPin( + EPinType pinType, + int pinOrdinal, + int id, + EMediaTypes mediaType, + int userId) + { + int pinId; + PinManager.Instance.AddPin(pinType, id, mediaType, userId, pinOrdinal, out pinId); + SingletonModelItem.Instance.JumpListPinUpdateRequested.Invoke(); + return pinId; + } + + public static int AddPin( + string moniker, + EServiceMediaType mediaType, + string description, + int userId) + { + return PinHelper.AddPin(EPinType.ePinTypeGeneric, description, -1, moniker, mediaType, userId); + } + + public static int AddPin( + EPinType pinType, + string description, + int pinOrdinal, + string moniker, + EServiceMediaType mediaType, + int userId) + { + int nPinId; + PinManager.Instance.AddPin(pinType, moniker, description, mediaType, userId, pinOrdinal, out nPinId); + SingletonModelItem.Instance.JumpListPinUpdateRequested.Invoke(); + return nPinId; + } + + public static int FindPin(int id, EMediaTypes type, int userId, int maxAge) + { + int nPinId; + PinManager.Instance.FindPin(EPinType.ePinTypeGeneric, id, type, userId, maxAge, out nPinId); + return nPinId; + } + + public static int FindPin(string moniker, EServiceMediaType type, int userId, int maxAge) + { + int nPinId; + PinManager.Instance.FindPin(EPinType.ePinTypeGeneric, moniker, type, userId, maxAge, out nPinId); + return nPinId; + } + + public static void DeletePin(int id) + { + PinManager.Instance.DeletePin(id); + SingletonModelItem.Instance.JumpListPinUpdateRequested.Invoke(); + } + + public static EServiceMediaType MapMarketplaceObjectToServiceMediaType( + DataProviderObject dataProviderObject) + { + switch (dataProviderObject.TypeName) + { + case "Album": + return EServiceMediaType.eServiceMediaTypeAlbum; + case "Artist": + return EServiceMediaType.eServiceMediaTypeArtist; + default: + return EServiceMediaType.eServiceMediaTypeInvalid; + } + } + } +} diff --git a/ZuneUI/PlayNavigationOptions.cs b/ZuneUI/PlayNavigationOptions.cs new file mode 100644 index 0000000..59b9c4e --- /dev/null +++ b/ZuneUI/PlayNavigationOptions.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlayNavigationOptions +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum PlayNavigationOptions + { + None, + NavigateVideosToNowPlaying, + NavigateToNowPlaying, + NavigateToNowPlayingWithMix, + } +} diff --git a/ZuneUI/PlaybackContext.cs b/ZuneUI/PlaybackContext.cs new file mode 100644 index 0000000..ca68235 --- /dev/null +++ b/ZuneUI/PlaybackContext.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaybackContext +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum PlaybackContext + { + None, + Music, + LibraryVideo, + LibraryPodcast, + MarketplaceVideo, + MarketplacePodcast, + QuickMix, + } +} diff --git a/ZuneUI/PlaybackPage.cs b/ZuneUI/PlaybackPage.cs new file mode 100644 index 0000000..7da8931 --- /dev/null +++ b/ZuneUI/PlaybackPage.cs @@ -0,0 +1,99 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaybackPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class PlaybackPage : ZunePage + { + private bool _showingArtistBio; + private TransportControlStyle _activeStyle; + private bool _showMixOnEntry; + private bool _exitOnPlaybackStopped; + private int _initialPlaybackID; + + public PlaybackPage() + { + this.UI = PlaybackPage.LandUI; + this.ShowAppBackground = false; + this.ShowBackArrow = true; + this.ShowCDIcon = false; + this.ShowDeviceIcon = false; + this.ShowComputerIcon = ComputerIconState.Hide; + this.ShowNowPlayingBackgroundOnIdle = false; + this.ShowNowPlayingX = true; + this.ShowPivots = false; + this.ShowPlaylistIcon = false; + this.ShowSearch = false; + this.ShowSettings = false; + this.ShowLogo = false; + if (SingletonModelItem.Instance.CurrentTrack == null) + return; + this._initialPlaybackID = SingletonModelItem.Instance.CurrentTrack.PlaybackID; + } + + public TransportControlStyle ActiveTransportControlStyle + { + get => this._activeStyle; + set + { + if (this._activeStyle == value) + return; + this._activeStyle = value; + this.FirePropertyChanged(nameof(ActiveTransportControlStyle)); + } + } + + public bool ShowingArtistBio + { + get => this._showingArtistBio; + set + { + if (this._showingArtistBio == value) + return; + this._showingArtistBio = value; + this.FirePropertyChanged(nameof(ShowingArtistBio)); + } + } + + public bool ShowMixOnEntry + { + get => this._showMixOnEntry; + set + { + if (this._showMixOnEntry == value) + return; + this._showMixOnEntry = value; + this.FirePropertyChanged(nameof(ShowMixOnEntry)); + } + } + + public bool ExitOnPlaybackStopped + { + get => this._exitOnPlaybackStopped; + set + { + if (this._exitOnPlaybackStopped == value) + return; + this._exitOnPlaybackStopped = value; + this.FirePropertyChanged(nameof(ExitOnPlaybackStopped)); + } + } + + public int InitialPlaybackID => this._initialPlaybackID; + + public override bool HandleEscape() + { + if (this.ShouldHandleEscape) + return base.HandleEscape(); + ZuneShell.DefaultInstance.NavigateBack(); + return true; + } + + public override bool CanNavigateForwardTo(IZunePage destination) => !(destination is CDLand) && !(destination is Deviceland); + + private static string LandUI => "res://ZuneShellResources!NowPlayingLand.uix#NowPlayingLand"; + } +} diff --git a/ZuneUI/PlaybackTrack.cs b/ZuneUI/PlaybackTrack.cs new file mode 100644 index 0000000..7357323 --- /dev/null +++ b/ZuneUI/PlaybackTrack.cs @@ -0,0 +1,104 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaybackTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZunePlayback; +using System; +using System.Runtime.Serialization; + +namespace ZuneUI +{ + [Serializable] + public abstract class PlaybackTrack + { + public const long c_TicksPerSecond = 10000000; + public const long c_TicksPerMinute = 600000000; + public const long c_incrementPlayCountAfter = 200000000; + private static int s_nextPlaybackID; + protected ContainerPlayMarker _containerPlayMarker; + [NonSerialized] + private int _playbackID; + [NonSerialized] + private Command _ratingChanged; + + public PlaybackTrack() => this.AcquirePlaybackID(); + + public int PlaybackID => this._playbackID; + + public Command RatingChanged + { + get + { + if (this._ratingChanged == null) + this._ratingChanged = new Command(); + return this._ratingChanged; + } + } + + public abstract string Title { get; } + + public abstract TimeSpan Duration { get; } + + public abstract Guid ZuneMediaId { get; } + + public virtual Guid ZuneMediaInstanceId => Guid.Empty; + + public virtual bool CanRate => false; + + public virtual int UserRating + { + get => 0; + set + { + } + } + + public virtual bool IsInCollection => false; + + public virtual bool IsInVisibleCollection => false; + + public virtual bool IsMusic => false; + + public virtual bool IsVideo => false; + + public virtual bool IsStreaming => false; + + public virtual bool IsHD => false; + + public virtual MediaType MediaType => MediaType.Undefined; + + public virtual string ServiceContext => (string)null; + + public abstract HRESULT GetURI(out string uri); + + internal virtual void OnBeginPlayback(PlayerInterop playbackWrapper) => SingletonModelItem.Instance.ClearError(this); + + internal virtual void OnPositionChanged(long position) + { + } + + internal virtual void OnSkip() + { + } + + internal virtual void OnEndPlayback(bool endOfMedia) + { + } + + public override string ToString() => string.Format("TRACK[{0}]: {1}", (object)this._playbackID, (object)this.Title); + + private void AcquirePlaybackID() + { + this._playbackID = ++PlaybackTrack.s_nextPlaybackID; + if (this._playbackID != 0) + return; + this._playbackID = ++PlaybackTrack.s_nextPlaybackID; + } + + [OnDeserialized] + internal void HandleDeserialization(StreamingContext context) => this.AcquirePlaybackID(); + } +} diff --git a/ZuneUI/PlaylistAttachment.cs b/ZuneUI/PlaylistAttachment.cs new file mode 100644 index 0000000..5eb1fe0 --- /dev/null +++ b/ZuneUI/PlaylistAttachment.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public class PlaylistAttachment : Attachment + { + public const string RequestTypeString = "playlist"; + + public PlaylistAttachment(Guid id, string title, string imageUri) + : base(id, title, (string)null, imageUri) + { + this.AttachmentUI = "res://ZuneShellResources!SocialComposer.uix#PlaylistAttachmentUI"; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_PLAYLIST_ATTACHMENT); + } + + public override MediaType MediaType => MediaType.Playlist; + + public override string RequestType => "playlist"; + + public override void LogSend() => SQMLog.Log(SQMDataId.InboxMessageSendPlaylist, 1); + } +} diff --git a/ZuneUI/PlaylistContentsPanel.cs b/ZuneUI/PlaylistContentsPanel.cs new file mode 100644 index 0000000..feb4273 --- /dev/null +++ b/ZuneUI/PlaylistContentsPanel.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistContentsPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class PlaylistContentsPanel : ListPanel + { + private IList _selectedIds; + private IList _selectedPlaylistIds; + + internal PlaylistContentsPanel(LibraryPage page) + : base((IModelItemOwner)page) + => this.UI = PlaylistContentsPanel.PanelTemplate; + + public override MediaType MediaType => MediaType.PlaylistContentItem; + + public override IList SelectedLibraryIds + { + get => this._selectedIds; + set + { + if (this._selectedIds == value) + return; + this._selectedIds = value; + this.FirePropertyChanged(nameof(SelectedLibraryIds)); + } + } + + public IList SelectedPlaylistIds + { + get => this._selectedPlaylistIds; + set + { + if (this._selectedPlaylistIds == value) + return; + PlaylistManager.Instance.UnfreezeAutoPlaylist(this.SelectedPlaylistId); + this._selectedPlaylistIds = value; + this.FirePropertyChanged(nameof(SelectedPlaylistIds)); + this.FirePropertyChanged("SelectedPlaylistId"); + PlaylistManager.Instance.FreezeAutoPlaylist(this.SelectedPlaylistId); + } + } + + public int SelectedPlaylistId => this._selectedPlaylistIds != null ? (int)this._selectedPlaylistIds[0] : -1; + + internal override void Release() + { + PlaylistManager.Instance.UnfreezeAutoPlaylist(this.SelectedPlaylistId); + base.Release(); + } + + private static string PanelTemplate => "res://ZuneShellResources!PlaylistContentsPanel.uix#PlaylistContentsPanel"; + } +} diff --git a/ZuneUI/PlaylistError.cs b/ZuneUI/PlaylistError.cs new file mode 100644 index 0000000..eca3dea --- /dev/null +++ b/ZuneUI/PlaylistError.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistError +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum PlaylistError + { + Success, + NameExists, + InvalidName, + InvalidId, + NoResults, + Other, + } +} diff --git a/ZuneUI/PlaylistFactory.cs b/ZuneUI/PlaylistFactory.cs new file mode 100644 index 0000000..a6f3fd9 --- /dev/null +++ b/ZuneUI/PlaylistFactory.cs @@ -0,0 +1,53 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistFactory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Playlist; +using System; +using System.ComponentModel; + +namespace ZuneUI +{ + public abstract class PlaylistFactory : INotifyPropertyChanged, IDisposable + { + private bool _ready; + protected readonly bool _navigateOnCreate; + + public event PropertyChangedEventHandler PropertyChanged; + + protected PlaylistFactory(bool navigateOnCreate) => this._navigateOnCreate = navigateOnCreate; + + public virtual void Dispose() + { + } + + public abstract string GetUniqueTitle(); + + public abstract PlaylistResult CreatePlaylist( + string title, + CreatePlaylistOption option); + + public bool Ready + { + get => this._ready; + protected set + { + if (this._ready == value) + return; + this._ready = value; + this.NotifyPropertyChanged(nameof(Ready)); + } + } + + public bool NavigateOnCreate => this._navigateOnCreate; + + protected void NotifyPropertyChanged(string propertyName) + { + if (this.PropertyChanged == null) + return; + this.PropertyChanged((object)this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/ZuneUI/PlaylistManager.cs b/ZuneUI/PlaylistManager.cs new file mode 100644 index 0000000..7fc981c --- /dev/null +++ b/ZuneUI/PlaylistManager.cs @@ -0,0 +1,873 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistManager +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Playlist; +using Microsoft.Zune.QuickMix; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Subscription; +using Microsoft.Zune.Util; +using MicrosoftZuneInterop; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using UIXControls; +using ZuneXml; + +namespace ZuneUI +{ + public class PlaylistManager : ModelItem + { + private const int DefaultAutoRefreshFreq = 7; + private const PlaylistLimitType DefaultPlaylistLimitType = PlaylistLimitType.Count; + private static object s_invalidMediaId = (object)-1; + private static object s_invalidMediaType = (object)MediaType.Undefined; + private static char[] s_autoPlaylistSplitChars = new char[1] + { + ';' + }; + private static PlaylistManager _instance; + private QueryPropertyBag _queryContext; + private int _defaultPlaylistId = int.MinValue; + private Microsoft.Zune.Playlist.PlaylistManager _playlistManagerInterop; + private Notification _notification; + + public static PlaylistManager Instance + { + get + { + if (PlaylistManager._instance == null) + PlaylistManager._instance = new PlaylistManager(); + return PlaylistManager._instance; + } + } + + private PlaylistManager() + { + this._playlistManagerInterop = Microsoft.Zune.Playlist.PlaylistManager.Instance; + this._queryContext = new QueryPropertyBag(); + this._queryContext.SetValue("QueryView", (object)0); + } + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + this._queryContext = (QueryPropertyBag)null; + } + + public PlaylistResult CreatePlaylist(string title) => this.CreatePlaylist(title, CreatePlaylistOption.None); + + public PlaylistResult CreateAutoPlaylist( + string title, + CreatePlaylistOption options) + { + SQMLog.Log(SQMDataId.AutoPlaylistCreations, 1); + return this.CreatePlaylist(title, CreatePlaylistOption.AutoPlaylist | options); + } + + public PlaylistResult CreateComplexSyncRulePlaylist(string title) => this.CreatePlaylist(title, CreatePlaylistOption.SyncRule | CreatePlaylistOption.AutoPlaylist); + + internal PlaylistResult CreatePlaylist(string title, bool privatePlaylist) => this.CreatePlaylist(title, privatePlaylist ? CreatePlaylistOption.PrivatePlaylist : CreatePlaylistOption.None); + + public PlaylistResult CreatePlaylist(string title, CreatePlaylistOption options) + { + int playlistId; + HRESULT playlist = this._playlistManagerInterop.CreatePlaylist(title, (string)null, (ValueType)null, options, out playlistId); + return new PlaylistResult(playlistId, playlist); + } + + public PlaylistResult SavePlaylistAsStatic( + int playlistId, + PlaylistAsyncOperationCompleted completedDelegate) + { + HRESULT hr = this._playlistManagerInterop.SavePlaylistAsStatic(playlistId, completedDelegate); + return new PlaylistResult(playlistId, hr); + } + + public PlaylistResult GetPlaylistByServiceMediaId(Guid serviceMediaId) + { + int playlistId = PlaylistManager.InvalidPlaylistId; + HRESULT byServiceMediaId = this._playlistManagerInterop.GetPlaylistByServiceMediaId(serviceMediaId, out playlistId); + return new PlaylistResult(playlistId, byServiceMediaId); + } + + public PlaylistResult CreateAndAddToUniquePlaylist( + string title, + Guid? serviceMediaId, + IList items) + { + int playlistId; + HRESULT playlist1 = this._playlistManagerInterop.CreatePlaylist(title, (string)null, (ValueType)serviceMediaId, CreatePlaylistOption.RenameOnConflict, out playlistId); + if (playlist1.IsError) + return new PlaylistResult(playlistId, playlist1); + PlaylistError playlist2 = this.AddToPlaylist(playlistId, items); + return new PlaylistResult(playlistId, playlist2); + } + + public PlaylistResult CreateAndAddToUniquePlaylist(string title, IList items) => this.CreateAndAddToUniquePlaylist(title, new Guid?(), items); + + public PlaylistError AddToPlaylist(int playlistId, IList items) => this.AddToPlaylist(playlistId, items, true); + + public PlaylistError AddToPlaylist( + int playlistId, + IList items, + bool rememberAsDefault) + { + return this.AddToPlaylist(playlistId, items, rememberAsDefault, true); + } + + public PlaylistError AddToPlaylist( + int playlistId, + IList items, + bool rememberAsDefault, + bool notify) + { + int capacity = items != null ? items.Count : 0; + int count = 0; + if (capacity > 0) + { + int startIndex = 0; + List playbackTrackList = new List(capacity); + bool flag = playlistId == PlaylistManager.NowPlayingId; + bool materializeMarketplaceTracks = !flag; + bool allowVideo = playlistId == CDAccess.Instance.BurnListId; + bool allowPictures = allowVideo; + PlaylistManager.AddItemsToTrackList(items, (IList)playbackTrackList, ref startIndex, allowVideo, allowPictures, materializeMarketplaceTracks, (ContainerPlayMarker)null); + count = playbackTrackList.Count; + if (count > 0) + { + if (!flag) + { + int[] mediaIds = new int[count]; + int[] mediaTypeIds = new int[count]; + for (int index = 0; index < count; ++index) + { + if (playbackTrackList[index] is LibraryPlaybackTrack libraryPlaybackTrack) + { + mediaIds[index] = libraryPlaybackTrack.MediaId; + mediaTypeIds[index] = (int)libraryPlaybackTrack.MediaType; + } + } + if (this._playlistManagerInterop.AddMediaToPlaylist(playlistId, mediaIds.Length, mediaIds, mediaTypeIds, -1, (int[])null).IsError) + { + if (playlistId == this.DefaultPlaylistId) + this.DefaultPlaylistId = PlaylistManager.InvalidPlaylistId; + return PlaylistError.InvalidId; + } + } + else + SingletonModelItem.Instance.AddToNowPlaying(items); + } + } + if (rememberAsDefault) + this.DefaultPlaylistId = playlistId; + if (notify) + this.NotifyItemsAdded(playlistId, count); + return PlaylistError.Success; + } + + public void NotifyItemsAdded(int playlistId, int count) + { + string playlistName = PlaylistManager.GetPlaylistName(playlistId); + this.ShowNewNotification(count <= 0 ? string.Format(ZuneUI.Shell.LoadString(StringId.IDS_PLAYLIST_NEW_DEFAULT), (object)playlistName) : (count != 1 ? string.Format(ZuneUI.Shell.LoadString(StringId.IDS_PLAYLIST_ADDED_N_ITEMS), (object)count, (object)playlistName) : string.Format(ZuneUI.Shell.LoadString(StringId.IDS_PLAYLIST_ADDED_1_ITEM), (object)playlistName))); + } + + public void NotifyAutoPlaylistCreated() => this.ShowNewNotification(ZuneUI.Shell.LoadString(StringId.IDS_AUTOPLAYLIST_CREATED)); + + private void ShowNewNotification(string message) + { + if (this._notification != null && !this._notification.IsDisposed) + NotificationArea.Instance.Remove(this._notification); + this._notification = (Notification)new MessageNotification(message, NotificationTask.EditPlaylist, NotificationState.OneShot, 5000); + NotificationArea.Instance.Add(this._notification); + } + + public void RemoveFromPlaylist(int playlistId, IList items) + { + int count = items.Count; + int[] playlistContentIds = new int[count]; + for (int index = 0; index < count; ++index) + playlistContentIds[index] = (int)((DataProviderObject)items[index]).GetProperty("LibraryId"); + this._playlistManagerInterop.RemoveMediaFromPlaylist(playlistId, count, playlistContentIds); + } + + public void ReorderInPlaylist(int playlistId, IList items, int newIndex) + { + int count = items.Count; + int[] playlistContentIds = new int[count]; + for (int index = 0; index < count; ++index) + playlistContentIds[index] = (int)((DataProviderObject)items[index]).GetProperty("LibraryId"); + this._playlistManagerInterop.UpdateMediaPositionInPlaylist(playlistId, count, playlistContentIds, newIndex + 1); + } + + public PlaylistResult RenamePlaylist(int playlistId, string newTitle) + { + HRESULT hr = this._playlistManagerInterop.RenamePlaylist(playlistId, newTitle); + return new PlaylistResult(playlistId, hr); + } + + public void SetSubType(int playlistId, int subtype) + { + SQMLog.LogToStream(SQMDataId.PlaylistSubType, (uint)subtype); + PlaylistManager.SetFieldValue(playlistId, EListType.ePlaylistList, 324, subtype); + } + + public void SetLimitType(int playlistId, int type) + { + SQMLog.LogToStream(SQMDataId.PlaylistLimitType, (uint)type); + PlaylistManager.SetFieldValue(playlistId, EListType.ePlaylistList, 220, type); + } + + public void SetLimitValue(int playlistId, int value, int type) + { + SQMLog.LogToStream((SQMDataId)(type == 0 ? 205 : 206), (uint)value); + PlaylistManager.SetFieldValue(playlistId, EListType.ePlaylistList, 221, value); + } + + public void SetAutoRefresh(int playlistId, bool enable) + { + SQMLog.Log(SQMDataId.PlaylistAutoRefresh, enable ? 1 : 0); + PlaylistManager.SetFieldValue(playlistId, EListType.ePlaylistList, 25, enable); + } + + public void SetAutoRefreshFreq(int playlistId, int freq) => PlaylistManager.SetFieldValue(playlistId, EListType.ePlaylistList, 26, freq); + + public PlaylistResult RefreshAutoPlaylist(int playlistId) + { + HRESULT hr = this._playlistManagerInterop.RefreshAutoPlaylist(playlistId); + return new PlaylistResult(playlistId, hr); + } + + public PlaylistResult FreezeAutoPlaylist(int playlistId) + { + HRESULT hr = this._playlistManagerInterop.DisableAutomaticRefresh(playlistId); + return new PlaylistResult(playlistId, hr); + } + + public PlaylistResult UnfreezeAutoPlaylist(int playlistId) + { + HRESULT hr = this._playlistManagerInterop.EnableAutomaticRefresh(playlistId); + return new PlaylistResult(playlistId, hr); + } + + public int DefaultPlaylistId + { + get => this._defaultPlaylistId; + private set + { + if (this._defaultPlaylistId == value) + return; + this._defaultPlaylistId = value; + this.FirePropertyChanged(nameof(DefaultPlaylistId)); + this.FirePropertyChanged("DefaultPlaylistName"); + } + } + + public string DefaultPlaylistName => PlaylistManager.GetPlaylistName(this._defaultPlaylistId); + + public void ValidateDefaultPlaylist() + { + if (this.DefaultPlaylistId < 0) + return; + if (string.IsNullOrEmpty(PlaylistManager.GetFieldValue(this.DefaultPlaylistId, EListType.ePlaylistList, 317, (string)null))) + this.DefaultPlaylistId = PlaylistManager.InvalidPlaylistId; + else + this.FirePropertyChanged("DefaultPlaylistName"); + } + + public static string GetPlaylistName(int playlistId) + { + if (playlistId == PlaylistManager.NowPlayingId) + return ZuneUI.Shell.LoadString(StringId.IDS_NOW_PLAYING); + return playlistId >= 0 ? PlaylistManager.GetFieldValue(playlistId, EListType.ePlaylistList, 344, string.Empty) : (string)null; + } + + public static bool GetPlaylistAutoRefresh(int playlistId) => playlistId >= 0 && PlaylistManager.GetFieldValue(playlistId, EListType.ePlaylistList, 25, false); + + public static int GetPlaylistAutoRefreshFreq(int playlistId) => playlistId >= 0 ? PlaylistManager.GetFieldValue(playlistId, EListType.ePlaylistList, 26, 7) : 7; + + public Choice GetSubTypeChoice(QuickMixSessionManager manager) + { + List commandList = new List(); + commandList.Add((Command)new QuickMixSubTypeCommand(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIXPLAYLIST_LOCAL_CONTENT_ONLY), EQuickMixType.eQuickMixTypeLocal, manager.QuickMixSession)); + if (FeatureEnablement.IsFeatureEnabled(Features.eQuickMixZmp)) + { + commandList.Add((Command)new QuickMixSubTypeCommand(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIXPLAYLIST_MIXED_CONTENT), EQuickMixType.eQuickMixTypeMixed, manager.QuickMixSession)); + commandList.Add((Command)new QuickMixSubTypeCommand(ZuneUI.Shell.LoadString(StringId.IDS_QUICKMIXPLAYLIST_MP_CONTENT_ONLY), EQuickMixType.eQuickMixTypeRadio, manager.QuickMixSession)); + } + return new Choice() { Options = (IList)commandList }; + } + + public static int GetSubType(int playlistId) => playlistId >= 0 ? PlaylistManager.GetFieldValue(playlistId, EListType.ePlaylistList, 324, 0) : -1; + + public static int GetLimitType(int playlistId) => playlistId >= 0 ? PlaylistManager.GetFieldValue(playlistId, EListType.ePlaylistList, 220, 2) : 2; + + public static int GetLimitValue(int playlistId) => playlistId >= 0 ? PlaylistManager.GetFieldValue(playlistId, EListType.ePlaylistList, 221, 0) : 0; + + public static int GetPlaylistType(int playlistId) => playlistId >= 0 ? PlaylistManager.GetFieldValue(playlistId, EListType.ePlaylistList, 265, 0) : 0; + + public static bool IsChannel(int playlistId) + { + if (playlistId >= 0) + { + switch ((PlaylistType)PlaylistManager.GetPlaylistType(playlistId)) + { + case PlaylistType.Channel: + case PlaylistType.PersonalChannel: + return true; + } + } + return false; + } + + public static MediaType GetAutoPlaylistSchema(int playlistId) + { + EMediaTypes schema; + return playlistId >= 0 && Microsoft.Zune.Playlist.PlaylistManager.Instance.GetAutoPlaylistSchema(playlistId, out schema).IsSuccess ? (MediaType)schema : MediaType.Undefined; + } + + public static void AddItemsToTrackList( + IList items, + IList tracks, + ref int startIndex, + bool allowVideo, + bool allowPictures, + bool materializeMarketplaceTracks, + ContainerPlayMarker containerPlayMarkerOverride) + { + int num1 = startIndex; + if (items == null || tracks == null) + return; + int count = items.Count; + if (count <= 0) + return; + MediaType mediaType1 = MediaType.Undefined; + if (items[0] is LibraryDataProviderItemBase providerItemBase) + { + if (providerItemBase.TypeName == "Artist") + mediaType1 = MediaType.Artist; + else if (providerItemBase.TypeName == "Album") + mediaType1 = MediaType.Album; + else if (providerItemBase.TypeName == "Genre") + mediaType1 = MediaType.Genre; + } + if (mediaType1 == MediaType.Artist || mediaType1 == MediaType.Genre || mediaType1 == MediaType.Album) + { + IList list = (IList)new ArrayList(count); + foreach (LibraryDataProviderItemBase providerItemBase in (IEnumerable)items) + list.Add((object)(int)providerItemBase.GetProperty("LibraryId")); + bool singleAlbum = list.Count == 1; + if ((mediaType1 == MediaType.Artist || mediaType1 == MediaType.Genre) && list.Count == 1) + { + ZuneQueryList zuneQueryList = mediaType1 != MediaType.Artist ? ZuneApplication.ZuneLibrary.GetAlbumsByGenres(list, (string)null) : ZuneApplication.ZuneLibrary.GetAlbumsByArtists(list, (string)null); + int num2 = (int)zuneQueryList.AddRef(); + singleAlbum = zuneQueryList.Count == 1; + int num3 = (int)zuneQueryList.Release(); + zuneQueryList.Dispose(); + } + string sort = (string)null; + if (ZuneShell.DefaultInstance.CurrentPage is MusicLibraryPage currentPage) + sort = currentPage.GetSort(singleAlbum, mediaType1); + if (sort == null) + sort = "+WM/TrackNumber"; + ZuneQueryList zuneQueryList1 = (ZuneQueryList)null; + switch (mediaType1) + { + case MediaType.Album: + zuneQueryList1 = ZuneApplication.ZuneLibrary.GetTracksByAlbums(list, sort); + break; + case MediaType.Genre: + zuneQueryList1 = ZuneApplication.ZuneLibrary.GetTracksByGenres(list, sort); + break; + case MediaType.Artist: + zuneQueryList1 = ZuneApplication.ZuneLibrary.GetTracksByArtists(list, sort); + break; + } + int num4 = (int)zuneQueryList1.AddRef(); + ArrayList uniqueIds = zuneQueryList1.GetUniqueIds(); + int num5 = uniqueIds != null ? uniqueIds.Count : 0; + for (int index = 0; index < num5; ++index) + { + ContainerPlayMarker containerPlayMarker; + if (containerPlayMarkerOverride != null) + { + containerPlayMarker = containerPlayMarkerOverride; + } + else + { + containerPlayMarker = new ContainerPlayMarker(); + containerPlayMarker.MediaType = mediaType1; + } + LibraryPlaybackTrack libraryPlaybackTrack = new LibraryPlaybackTrack((int)uniqueIds[index], MediaType.Track, containerPlayMarker); + tracks.Add((object)libraryPlaybackTrack); + } + int num6 = (int)zuneQueryList1.Release(); + zuneQueryList1.Dispose(); + } + else + { + bool flag1 = PlaylistManager.CanFastAddList(items); + ArrayList arrayList = (ArrayList)null; + int num2 = count; + bool flag2 = false; + if (flag1) + { + arrayList = PlaylistManager.GetUniqueIdsFromList(items); + if (arrayList != null) + num2 = arrayList.Count; + else + flag1 = false; + } + for (int index = 0; index < num2; ++index) + { + if (index == num1) + startIndex = tracks.Count; + if (flag1) + { + PlaylistManager.AddLibraryDataProviderItemToTrackList((int)arrayList[index], MediaType.Track, tracks, allowVideo, allowPictures, containerPlayMarkerOverride); + } + else + { + object obj = items[index]; + switch (obj) + { + case LibraryDataProviderItemBase _: + int mediaId = -1; + EMediaTypes mediaType2 = EMediaTypes.eMediaTypeInvalid; + (obj as LibraryDataProviderItemBase).GetMediaIdAndType(out mediaId, out mediaType2); + PlaylistManager.AddLibraryDataProviderItemToTrackList(mediaId, (MediaType)mediaType2, tracks, allowVideo, allowPictures, containerPlayMarkerOverride); + continue; + case SubscriptionDataProviderItem _: + PlaylistManager.AddSubscriptionDataProviderItemToTrackList((SubscriptionDataProviderItem)obj, tracks, allowVideo, allowPictures); + continue; + case DataProviderObject _: + bool blockedExplicitContent = false; + PlaylistManager.AddDataProviderObjectToTrackList((DataProviderObject)obj, tracks, materializeMarketplaceTracks, containerPlayMarkerOverride, out blockedExplicitContent); + flag2 |= blockedExplicitContent; + continue; + case FileEntry _: + PlaylistManager.AddFileEntryToTrackList((FileEntry)obj, tracks, allowVideo, allowPictures, materializeMarketplaceTracks, containerPlayMarkerOverride); + continue; + case LibraryPlaybackTrack _: + case VideoPlaybackTrack _: + PlaylistManager.AddLibraryOrVideoPlaybackTrackToTrackList(obj, tracks); + continue; + case MarketplacePlaybackTrack _: + PlaylistManager.AddMarketplacePlaybackTrackToTrackList((MarketplacePlaybackTrack)obj, tracks, materializeMarketplaceTracks); + continue; + case QuickMixItem _: + PlaylistManager.AddQuickMixItemToTrackList((QuickMixItem)obj, tracks, containerPlayMarkerOverride); + continue; + default: + continue; + } + } + } + if (!flag2) + return; + if (SignIn.Instance.SignedIn) + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_ExplicitErrorHeading), ZuneUI.Shell.LoadString(StringId.IDS_ExplicitNeedAdult), (EventHandler)null); + else + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_ExplicitErrorHeading), ZuneUI.Shell.LoadString(StringId.IDS_ExplicitMustLogin), (EventHandler)null); + } + } + + private static bool CanFastAddList(IList list) + { + bool flag = false; + if (list != null && list is LibraryVirtualList && (list[0] is LibraryDataProviderItemBase && ((DataProviderObject)list[0]).TypeName == "Track")) + flag = true; + return flag; + } + + private static ArrayList GetUniqueIdsFromList(IList list) + { + ArrayList arrayList = (ArrayList)null; + if (list is LibraryVirtualList libraryVirtualList) + arrayList = libraryVirtualList.GetUniqueIds(); + return arrayList; + } + + private static void AddLibraryDataProviderItemToTrackList( + int libraryId, + MediaType mediaType, + IList tracks, + bool allowVideo, + bool allowPictures, + ContainerPlayMarker containerPlayMarkerOverride) + { + if (libraryId == -1) + return; + switch (mediaType) + { + case MediaType.Track: + case MediaType.Video: + case MediaType.Photo: + case MediaType.PodcastEpisode: + if (!PlaylistManager.CanEnqueue(libraryId, mediaType, allowVideo, allowPictures)) + break; + ContainerPlayMarker containerPlayMarker1 = (ContainerPlayMarker)null; + if (mediaType == MediaType.Track) + { + if (containerPlayMarkerOverride != null) + { + containerPlayMarker1 = containerPlayMarkerOverride; + } + else + { + containerPlayMarker1 = new ContainerPlayMarker(); + containerPlayMarker1.MediaType = MediaType.Album; + containerPlayMarker1.LibraryId = -1; + } + } + tracks.Add((object)new LibraryPlaybackTrack(libraryId, mediaType, containerPlayMarker1)); + break; + case MediaType.Playlist: + ZuneQueryList tracksByPlaylist = ZuneApplication.ZuneLibrary.GetTracksByPlaylist(0, libraryId, EQuerySortType.eQuerySortOrderAscending, 437U); + int num1 = (int)tracksByPlaylist.AddRef(); + ContainerPlayMarker containerPlayMarker2 = new ContainerPlayMarker(); + containerPlayMarker2.LibraryId = libraryId; + containerPlayMarker2.MediaType = MediaType.Playlist; + containerPlayMarker2.PlaylistType = (PlaylistType)PlaylistManager.GetPlaylistType(libraryId); + containerPlayMarker2.PlaylistSubType = PlaylistManager.GetSubType(libraryId); + int count = tracksByPlaylist.Count; + for (uint index = 0; (long)index < (long)count; ++index) + { + int fieldValue1 = (int)tracksByPlaylist.GetFieldValue(index, typeof(int), 233U, PlaylistManager.s_invalidMediaId); + int fieldValue2 = (int)tracksByPlaylist.GetFieldValue(index, typeof(int), 234U, PlaylistManager.s_invalidMediaType); + if (fieldValue1 != -1) + tracks.Add((object)new LibraryPlaybackTrack(fieldValue1, (MediaType)fieldValue2, containerPlayMarker2)); + } + int num2 = (int)tracksByPlaylist.Release(); + tracksByPlaylist.Dispose(); + break; + } + } + + private static void AddSubscriptionDataProviderItemToTrackList( + SubscriptionDataProviderItem podcastEpisode, + IList tracks, + bool allowVideo, + bool allowPictures) + { + int property = (int)podcastEpisode.GetProperty("LibraryId"); + if (!PlaylistManager.CanEnqueue(property, MediaType.PodcastEpisode, allowVideo, allowPictures)) + return; + tracks.Add((object)new LibraryPlaybackTrack(property, MediaType.PodcastEpisode, (ContainerPlayMarker)null)); + } + + private static void AddDataProviderObjectToTrackList( + DataProviderObject dpItem, + IList tracks, + bool materializeMarketplaceTracks, + ContainerPlayMarker containerPlayMarkerOverride, + out bool blockedExplicitContent) + { + blockedExplicitContent = false; + if (dpItem == null) + return; + if (dpItem is Track) + { + Track track = (Track)dpItem; + int dbMediaId = -1; + if (track.IsParentallyBlocked && !track.InCollection) + { + blockedExplicitContent = true; + } + else + { + if (!ZuneApplication.Service.InCompleteCollection(track.Id, Microsoft.Zune.Service.EContentType.MusicTrack, out dbMediaId, out bool _) && materializeMarketplaceTracks && (track.IsDownloading || track.CanDownload || track.CanPurchase)) + dbMediaId = ZuneApplication.ZuneLibrary.AddTrack(track.Id, track.AlbumId, track.TrackNumber, track.Title, track.Duration, track.AlbumTitle, track.Artist, track.PrimaryGenre.Title); + if (dbMediaId >= 0) + { + tracks.Add((object)new LibraryPlaybackTrack(dbMediaId, MediaType.Track, (ContainerPlayMarker)null)); + } + else + { + if (!track.CanPlay) + return; + tracks.Add((object)new MarketplacePlaybackTrack(track.CanSubscriptionPlay, track.Id, track.Title, track.Duration, track.AlbumTitle, track.Artist, track.TrackNumber, track.PrimaryGenre.Title, track.AlbumId, track.ReferrerContext)); + } + } + } + else if (dpItem is Video) + { + Video video = (Video)dpItem; + if (video.IsParentallyBlocked && !video.InCollection) + blockedExplicitContent = true; + else + tracks.Add((object)new VideoPlaybackTrack(video.Id, video.Title, (string)null, (string)null, false, false, false, true, false, VideoDefinitionEnum.None)); + } + else + { + if (!(dpItem.TypeName == "RadioStation")) + return; + tracks.Add((object)new StreamingRadioPlaybackTrack((string)dpItem.GetProperty("SourceURL"), (string)dpItem.GetProperty("Title"), MediaType.Track)); + } + } + + private static void AddFileEntryToTrackList( + FileEntry file, + IList tracks, + bool allowVideo, + bool allowPictures, + bool materializeMarketplaceTracks, + ContainerPlayMarker containerPlayMarkerOverride) + { + if (file == null) + return; + int dbMediaId; + bool fFileAlreadyExists; + bool fTimedout; + bool flag1 = AddTransientMediaTask.AddTransientMediaWithTimeout(file.Path, (MediaType)file.MediaType, TimeSpan.FromSeconds((double)ClientConfiguration.GeneralSettings.AccessMediaHangTimeoutSec), out dbMediaId, out fFileAlreadyExists, out fTimedout); + if (fTimedout) + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_GENERIC_ERROR), ZuneUI.Shell.LoadString(StringId.IDS_PLAYLIST_MEDIA_NOTACCESSIBLE), (EventHandler)null); + else if (flag1 && !fFileAlreadyExists) + { + if (!PlaylistManager.CanEnqueue(dbMediaId, (MediaType)file.MediaType, allowVideo, allowPictures)) + return; + tracks.Add((object)new LibraryPlaybackTrack(dbMediaId, (MediaType)file.MediaType, (ContainerPlayMarker)null)); + } + else + { + bool flag2 = false; + if (file.MediaType == EMediaTypes.eMediaTypeVideo && fFileAlreadyExists) + { + MediaType type = MediaType.Undefined; + Guid zuneMediaId = Guid.Empty; + string title = string.Empty; + bool isHD = false; + PlaylistManager.GetVideoValues(dbMediaId, out type, out zuneMediaId, out title, out isHD); + if (type == MediaType.VideoMBR) + { + tracks.Add((object)new VideoPlaybackTrack(zuneMediaId, title, (string)null, (string)null, false, true, false, false, false, isHD ? VideoDefinitionEnum.HD : VideoDefinitionEnum.SD)); + flag2 = true; + } + } + if (flag2) + return; + string str = file.Path; + try + { + str = Path.GetFileName(str); + } + catch (ArgumentException ex) + { + } + tracks.Add((object)new StreamingPlaybackTrack(file.Path, str, (MediaType)file.MediaType)); + } + } + + private static void AddLibraryOrVideoPlaybackTrackToTrackList(object item, IList tracks) => tracks.Add(item); + + private static void AddMarketplacePlaybackTrackToTrackList( + MarketplacePlaybackTrack marketplacePlaybackTrack, + IList tracks, + bool materializeMarketplaceTracks) + { + if (marketplacePlaybackTrack == null) + return; + int dbMediaId; + if (!ZuneApplication.Service.InCompleteCollection(marketplacePlaybackTrack.ZuneMediaId, Microsoft.Zune.Service.EContentType.MusicTrack, out dbMediaId, out bool _)) + dbMediaId = ZuneApplication.ZuneLibrary.AddTrack(marketplacePlaybackTrack.ZuneMediaId, marketplacePlaybackTrack.AlbumId, marketplacePlaybackTrack.TrackNumber, marketplacePlaybackTrack.Title, marketplacePlaybackTrack.Duration, marketplacePlaybackTrack.Album, marketplacePlaybackTrack.Artist, marketplacePlaybackTrack.Genre); + if (dbMediaId < 0) + return; + tracks.Add((object)new LibraryPlaybackTrack(dbMediaId, MediaType.Track, (ContainerPlayMarker)null)); + } + + private static void AddQuickMixItemToTrackList( + QuickMixItem quickMixItem, + IList tracks, + ContainerPlayMarker containerPlayMarkerOverride) + { + if (quickMixItem == null) + return; + tracks.Add((object)new LibraryPlaybackTrack(quickMixItem.MediaId, MediaType.Track, containerPlayMarkerOverride)); + } + + internal QueryPropertyBag QueryContext + { + get + { + if (this._queryContext != null) + this._queryContext.SetValue("UserId", (object)SignIn.Instance.LastSignedInUserId); + return this._queryContext; + } + } + + public static T GetFieldValue(int mediaId, EListType listType, int atom, T defaultValue) + { + int[] columnIndexes = new int[1] { atom }; + object[] fieldValues = new object[1] + { + (object) defaultValue + }; + ZuneLibrary.GetFieldValues(mediaId, listType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + return (T)fieldValues[0]; + } + + public static void SetFieldValue(int mediaId, EListType listType, int atom, T value) + { + int[] columnIndexes = new int[1] { atom }; + object[] fieldValues = new object[1] { (object)value }; + ZuneLibrary.SetFieldValues(mediaId, listType, 1, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + } + + public static bool IsVideo(int mediaId, MediaType mediaType) + { + switch (mediaType) + { + case MediaType.Video: + return true; + case MediaType.PodcastEpisode: + if (PlaylistManager.GetFieldValue(mediaId, EListType.ePodcastEpisodeList, 161, MediaType.Undefined) == MediaType.Video) + return true; + break; + } + return false; + } + + public static void GetVideoValues( + int dbMediaId, + out MediaType type, + out Guid zuneMediaId, + out string title, + out bool isHD) + { + int[] columnIndexes = new int[4] { 177, 451, 344, 440 }; + object[] fieldValues = new object[4] + { + (object) MediaType.Undefined, + (object) Guid.Empty, + (object) string.Empty, + (object) VideoDefinition.Unknown + }; + ZuneLibrary.GetFieldValues(dbMediaId, EListType.eVideoList, columnIndexes.Length, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + type = (MediaType)fieldValues[0]; + zuneMediaId = (Guid)fieldValues[1]; + title = (string)fieldValues[2]; + isHD = VideoDefinitionHelper.IsHD((VideoDefinition)fieldValues[3]); + } + + public static bool CanEnqueue( + int mediaId, + MediaType mediaType, + bool allowVideo, + bool allowPictures) + { + switch (mediaType) + { + case MediaType.Photo: + return allowPictures; + case MediaType.PodcastEpisode: + if (PlaylistManager.GetFieldValue(mediaId, EListType.ePodcastEpisodeList, 145, EItemDownloadState.eDownloadStateNone) != EItemDownloadState.eDownloadStateDownloaded) + return false; + break; + } + return allowVideo || !PlaylistManager.IsVideo(mediaId, mediaType); + } + + public static bool IsInCollection(int mediaId, MediaType mediaType) + { + EListType listType = PlaylistManager.MediaTypeToListType(mediaType); + if (listType == EListType.eListTypeCount) + return false; + string fieldValue = PlaylistManager.GetFieldValue(mediaId, listType, 317, (string)null); + bool flag = false; + if (!string.IsNullOrEmpty(fieldValue) && !fieldValue.StartsWith("zunecd://")) + flag = true; + return flag; + } + + public static bool IsInVisibleCollection(int mediaId, MediaType mediaType) + { + bool flag = false; + if (mediaId != -1) + { + EListType listType = PlaylistManager.MediaTypeToListType(mediaType); + if (listType != EListType.eListTypeCount) + flag = PlaylistManager.GetFieldValue(mediaId, listType, 204, false); + } + return flag; + } + + public static EListType MediaTypeToListType(MediaType mediaType) + { + switch (mediaType) + { + case MediaType.Track: + return EListType.eTrackList; + case MediaType.Video: + return EListType.eVideoList; + case MediaType.Photo: + return EListType.ePhotoList; + case MediaType.Playlist: + return EListType.ePlaylistList; + case MediaType.Album: + return EListType.eAlbumList; + case MediaType.PodcastEpisode: + return EListType.ePodcastEpisodeList; + case MediaType.Podcast: + return EListType.ePodcastList; + case MediaType.Genre: + return EListType.eGenreList; + case MediaType.Artist: + return EListType.eArtistList; + default: + return EListType.eListTypeCount; + } + } + + public static int GetPlaylistId(int contentItemId) => PlaylistManager.GetFieldValue(contentItemId, EListType.ePlaylistContentList, 263, -1); + + public static List SplitAutoPlaylistValue(string value) + { + List stringList = (List)null; + if (value != null) + { + if (value.IndexOf(';') >= 0) + { + string[] strArray = value.Split(PlaylistManager.s_autoPlaylistSplitChars, StringSplitOptions.RemoveEmptyEntries); + foreach (string str1 in strArray) + { + string str2 = str1.Trim(); + if (str2.Length > 0) + { + if (stringList == null) + stringList = new List(strArray.Length); + stringList.Add(str2); + } + } + } + else + { + value = value.Trim(); + if (value.Length > 0) + { + stringList = new List(1); + stringList.Add(value); + } + } + } + return stringList; + } + + [Conditional("DEBUG_PLAYLIST")] + private static void _DEBUG_Trace(string message, params object[] args) + { + } + + public static int InvalidPlaylistId => int.MinValue; + + public static int NowPlayingId => -1; + + public static int ImportErrorCode => HRESULT._NS_E_WMP_PLAYLIST_IMPORT_ERROR.Int; + } +} diff --git a/ZuneUI/PlaylistNavigationCommandHandler.cs b/ZuneUI/PlaylistNavigationCommandHandler.cs new file mode 100644 index 0000000..a61c059 --- /dev/null +++ b/ZuneUI/PlaylistNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class PlaylistNavigationCommandHandler : DeviceAwareNavigationHandler + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new MusicLibraryPage(this.ShowDeviceContents, MusicLibraryView.Playlist); + } +} diff --git a/ZuneUI/PlaylistOverrideNotification.cs b/ZuneUI/PlaylistOverrideNotification.cs new file mode 100644 index 0000000..72afd83 --- /dev/null +++ b/ZuneUI/PlaylistOverrideNotification.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistOverrideNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class PlaylistOverrideNotification : MessageNotification + { + private static string message = Shell.LoadString(StringId.IDS_PLAYLIST_LAND_NOTIFICATION); + + public PlaylistOverrideNotification() + : base(PlaylistOverrideNotification.message, NotificationTask.EditPlaylist, NotificationState.Normal) + { + } + } +} diff --git a/ZuneUI/PlaylistResult.cs b/ZuneUI/PlaylistResult.cs new file mode 100644 index 0000000..692c021 --- /dev/null +++ b/ZuneUI/PlaylistResult.cs @@ -0,0 +1,46 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistResult +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class PlaylistResult + { + private PlaylistError _error; + private int _playlistId; + private HRESULT _hr; + + internal PlaylistResult(int playlistId, HRESULT hr) + { + this._hr = hr; + if (hr.IsSuccess && playlistId > 0) + { + this._playlistId = playlistId; + } + else + { + this._playlistId = PlaylistManager.InvalidPlaylistId; + if ((HRESULT)hr.Int == HRESULT._DB_E_RESOURCEEXISTS) + this._error = PlaylistError.NameExists; + else if ((HRESULT)hr.Int == HRESULT._DB_E_BADPARAMETERNAME) + this._error = PlaylistError.InvalidName; + else + this._error = PlaylistError.Other; + } + } + + public PlaylistResult(int playlistId, PlaylistError error) + { + this._playlistId = playlistId; + this._error = error; + } + + public PlaylistError Error => this._error; + + public int PlaylistId => this._playlistId; + + public HRESULT HR => this._hr; + } +} diff --git a/ZuneUI/PlaylistTypeFilterList.cs b/ZuneUI/PlaylistTypeFilterList.cs new file mode 100644 index 0000000..272358b --- /dev/null +++ b/ZuneUI/PlaylistTypeFilterList.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistTypeFilterList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Playlist; +using System.Collections; + +namespace ZuneUI +{ + public class PlaylistTypeFilterList : FilterList + { + private IList _typesToInclude = PlaylistTypeFilterList.AllTypes; + private static int[] _allTypes = new int[0]; + + public IList TypesToInclude + { + get => this._typesToInclude; + set + { + if (this._typesToInclude == value) + return; + this._typesToInclude = value; + this.FirePropertyChanged(nameof(TypesToInclude)); + this.ProduceFilteredList(); + } + } + + protected override bool ShouldIncludeItem(int sourceIndex, int targetIndex, object item) + { + if (this.TypesToInclude == PlaylistTypeFilterList.AllTypes) + return true; + if (this.TypesToInclude == null || this.TypesToInclude.Count <= 0 || !(item is DataProviderObject dataProviderObject)) + return false; + object property = dataProviderObject.GetProperty("PlaylistType"); + return property != null && property is int && this.TypesToInclude.Contains((object)(PlaylistType)property); + } + + public static IList AllTypes => (IList)PlaylistTypeFilterList._allTypes; + } +} diff --git a/ZuneUI/PlaylistsPanel.cs b/ZuneUI/PlaylistsPanel.cs new file mode 100644 index 0000000..954e24a --- /dev/null +++ b/ZuneUI/PlaylistsPanel.cs @@ -0,0 +1,36 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PlaylistsPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class PlaylistsPanel : ListPanel + { + private IList _selectedIds; + + internal PlaylistsPanel(MusicLibraryPage page) + : base((IModelItemOwner)page) + => this.UI = PlaylistsPanel.PanelTemplate; + + public override IList SelectedLibraryIds + { + get => this._selectedIds; + set + { + if (this._selectedIds == value) + return; + this._selectedIds = value; + this.FirePropertyChanged(nameof(SelectedLibraryIds)); + } + } + + protected MusicLibraryPage LibraryPage => base.LibraryPage as MusicLibraryPage; + + private static string PanelTemplate => "res://ZuneShellResources!PlaylistsPanel.uix#PlaylistsPanel"; + } +} diff --git a/ZuneUI/PodcastAttachment.cs b/ZuneUI/PodcastAttachment.cs new file mode 100644 index 0000000..242c6f1 --- /dev/null +++ b/ZuneUI/PodcastAttachment.cs @@ -0,0 +1,53 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PodcastAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public class PodcastAttachment : Attachment + { + public const string RequestTypeString = "podcast"; + private string _url; + + public PodcastAttachment(Guid id, string title, string author, string url, string imageUri) + : base(id, title, author, imageUri) + { + this.AttachmentUI = "res://ZuneShellResources!SocialComposer.uix#PodcastAttachmentUI"; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_PODCAST_ATTACHMENT); + this._url = url; + } + + public string Url + { + get => this._url; + set + { + this._url = value; + this.FirePropertyChanged(nameof(Url)); + } + } + + public override MediaType MediaType => MediaType.Podcast; + + public override string RequestType => "podcast"; + + public override string[] Properties => new string[8] + { + "type", + this.RequestType, + "podcasturl", + this._url ?? string.Empty, + "podcastmediaid", + this.Id.ToString(), + "podcastname", + this.Title + }; + + public override void LogSend() => SQMLog.Log(SQMDataId.InboxMessageSendPodcast, 1); + } +} diff --git a/ZuneUI/PodcastCredentials.cs b/ZuneUI/PodcastCredentials.cs new file mode 100644 index 0000000..a1b92cc --- /dev/null +++ b/ZuneUI/PodcastCredentials.cs @@ -0,0 +1,75 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PodcastCredentials +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Subscription; +using System; +using System.Threading; + +namespace ZuneUI +{ + public class PodcastCredentials : NetworkSignInCredentials + { + private static PodcastCredentials _instance; + private PodcastSignIn _inputDialog; + + private PodcastCredentials() + { + } + + public static PodcastCredentials Instance + { + get + { + if (PodcastCredentials._instance == null) + PodcastCredentials._instance = new PodcastCredentials(); + return PodcastCredentials._instance; + } + } + + public static bool HasInstance => PodcastCredentials._instance != null; + + public override void Phase2Init() => SubscriptionManager.Instance.SetCredentialHandler(EMediaTypes.eMediaTypePodcastSeries, new SubscriptionCredentialHandler(this.GetCredentials)); + + private bool GetCredentials(SubscriptonCredentialRequestArguments args) + { + this._completed = false; + if (!Application.IsApplicationThread && this._dialogClosed == null) + { + this._dialogClosed = new EventWaitHandle(false, EventResetMode.ManualReset); + Application.DeferredInvoke(new DeferredInvokeHandler(this.ShowDialog), (object)args); + this._dialogClosed.WaitOne(); + this._dialogClosed.Close(); + this._dialogClosed = (EventWaitHandle)null; + } + return this._completed; + } + + private void ShowDialog(object args) + { + if (!Application.IsApplicationThread || !(args is SubscriptonCredentialRequestArguments)) + return; + if (this._inputDialog != null) + { + this._inputDialog.Dispose(); + this._inputDialog = (PodcastSignIn)null; + } + this._inputDialog = new PodcastSignIn((SubscriptonCredentialRequestArguments)args, new EventHandler(((NetworkSignInCredentials)this).OnDialogSignIn), new EventHandler(((NetworkSignInCredentials)this).OnDialogCanceled)); + this._inputDialog.Show(); + } + + public override void Dispose() + { + SubscriptionManager.Instance.SetCredentialHandler(EMediaTypes.eMediaTypePodcastSeries, (SubscriptionCredentialHandler)null); + if (this._inputDialog != null) + { + this._inputDialog.Dispose(); + this._inputDialog = (PodcastSignIn)null; + } + base.Dispose(); + } + } +} diff --git a/ZuneUI/PodcastEpisodeDetails.cs b/ZuneUI/PodcastEpisodeDetails.cs new file mode 100644 index 0000000..49aa425 --- /dev/null +++ b/ZuneUI/PodcastEpisodeDetails.cs @@ -0,0 +1,79 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PodcastEpisodeDetails +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; + +namespace ZuneUI +{ + public class PodcastEpisodeDetails + { + private static int[] ColumnIndexes = new int[14] + { + 344, + 312, + 172, + 24, + 292, + 151, + 177, + 317, + 222, + 175, + 181, + 176, + 32, + 68 + }; + private static string[] DataProperties = new string[14] + { + "Title", + "SeriesTitle", + "SeriesFeedUrl", + "Author", + "ReleaseDate", + "Duration", + "MediaType", + "SourceUrl", + "EnclosureUrl", + "FileName", + "FolderName", + "FileSize", + "Bitrate", + "Copyright" + }; + + public static void Populate(object dataContainer, int libraryId) + { + DataProviderObject dataProviderObject = (DataProviderObject)dataContainer; + object[] fieldValues = new object[14] + { + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) DateTime.MinValue, + (object) TimeSpan.Zero, + (object) EMediaTypes.eMediaTypeAudio, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) 0L, + (object) 0, + (object) string.Empty + }; + ZuneLibrary.GetFieldValues(libraryId, EListType.ePodcastEpisodeList, PodcastEpisodeDetails.ColumnIndexes.Length, PodcastEpisodeDetails.ColumnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + for (int index = 0; index < PodcastEpisodeDetails.ColumnIndexes.Length; ++index) + { + if (PodcastEpisodeDetails.ColumnIndexes[index] == 177) + fieldValues[index] = (object)MediaDescriptions.Map((MediaType)fieldValues[index]); + dataProviderObject.SetProperty(PodcastEpisodeDetails.DataProperties[index], fieldValues[index]); + } + } + } +} diff --git a/ZuneUI/PodcastLibraryPage.cs b/ZuneUI/PodcastLibraryPage.cs new file mode 100644 index 0000000..2e79189 --- /dev/null +++ b/ZuneUI/PodcastLibraryPage.cs @@ -0,0 +1,66 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PodcastLibraryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + public class PodcastLibraryPage : SubscriptionLibraryPage + { + public PodcastLibraryPage() + : this(false) + { + } + + protected override string LandUI => "res://ZuneShellResources!PodcastLibrary.uix#PodcastLibrary"; + + protected override EMediaTypes SeriesMediaType => EMediaTypes.eMediaTypePodcastSeries; + + protected override EListType SeriesListType => EListType.ePodcastEpisodeList; + + protected override StringId SubscriptionErrorStringId => StringId.IDS_PODCAST_SUBSCRIPTION_ERROR; + + public static Guid GetZuneMediaId(int seriesId) => SubscriptionLibraryPage.GetZuneMediaId(seriesId, EListType.ePodcastList); + + public PodcastLibraryPage(bool showDevice) + : base(showDevice, MediaType.Podcast) + { + this.UIPath = "Collection\\Podcasts"; + if (showDevice) + { + this.PivotPreference = Shell.MainFrame.Device.Podcasts; + Deviceland.InitDevicePage((ZunePage)this); + } + else + this.PivotPreference = Shell.MainFrame.Collection.Podcasts; + this.IsRootPage = true; + this.SeriesPanel = new SubscriptionSeriesPanel((SubscriptionLibraryPage)this); + this.EpisodePanel = new SubscriptionEpisodePanel((SubscriptionLibraryPage)this); + if (!showDevice) + this.DetailsPanel = (LibraryPanel)new SubscriptionDetailsPanel((SubscriptionLibraryPage)this); + this.m_markAllAsPlayed = new MenuItemCommand(Shell.LoadString(StringId.IDS_PODCAST_MARK_AS_PLAYED_MENUITEM)); + this.m_markAllAsUnplayed = new MenuItemCommand(Shell.LoadString(StringId.IDS_PODCAST_MARK_AS_UNPLAYED_MENUITEM)); + this.TransportControlStyle = TransportControlStyle.Music; + this.PlaybackContext = PlaybackContext.LibraryPodcast; + this.ShowPlaylistIcon = false; + } + + public static void FindInCollection(int seriesId) => PodcastLibraryPage.FindInCollection(seriesId, -1); + + public static void FindInCollection(int seriesId, int libraryId) + { + if (seriesId <= 0 && libraryId <= 0) + return; + Hashtable hashtable = new Hashtable(); + if (seriesId > 0) + hashtable.Add((object)"SeriesLibraryId", (object)seriesId); + if (libraryId > 0) + hashtable.Add((object)"EpisodeLibraryId", (object)libraryId); + ZuneShell.DefaultInstance.Execute("Collection\\Podcasts", (IDictionary)hashtable); + } + } +} diff --git a/ZuneUI/PodcastNavigationCommandHandler.cs b/ZuneUI/PodcastNavigationCommandHandler.cs new file mode 100644 index 0000000..995ef57 --- /dev/null +++ b/ZuneUI/PodcastNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PodcastNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class PodcastNavigationCommandHandler : DeviceAwareNavigationHandler + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new PodcastLibraryPage(this.ShowDeviceContents); + } +} diff --git a/ZuneUI/PodcastSignIn.cs b/ZuneUI/PodcastSignIn.cs new file mode 100644 index 0000000..f58469b --- /dev/null +++ b/ZuneUI/PodcastSignIn.cs @@ -0,0 +1,71 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PodcastSignIn +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Subscription; +using System; +using System.Net; + +namespace ZuneUI +{ + public class PodcastSignIn : NetworkSignInDialogHelper + { + private SubscriptonCredentialRequestArguments _credentials; + private string _seriesTitle; + + public string TargetUrl => this._credentials.TargetUrl; + + public override string UserName + { + get => this._credentials.Credential.UserName; + set => this._credentials.Credential.UserName = value; + } + + public override string Password + { + get => this._credentials.Credential.Password; + set => this._credentials.Credential.Password = value; + } + + public string SeriesTitle => this._seriesTitle; + + public PodcastSignIn( + SubscriptonCredentialRequestArguments credentials, + EventHandler signInHandler, + EventHandler cancelHandler) + : base(signInHandler, cancelHandler, "res://ZuneShellResources!PodcastDialogs.uix#PodcastSignInDialogUI") + { + this._credentials = credentials; + this.Cancel.Invoked += new EventHandler(((NetworkSignInDialogHelper)this).OnInvoked); + this._seriesTitle = this._credentials.SubscriptionMediaId <= 0 ? string.Empty : PlaylistManager.GetFieldValue(this._credentials.SubscriptionMediaId, EListType.ePodcastList, 344, string.Empty); + this._title = Shell.LoadString(StringId.IDS_PODCAST_SIGN_IN_TITLE); + Uri uri = new Uri(this._credentials.TargetUrl); + this._hostName = uri.Scheme + Uri.SchemeDelimiter + uri.Host; + this._realmName = this._credentials.Realm; + this._credentials.Credential = new NetworkCredential(); + this._credentials.Credential.UserName = this._credentials.LastUserName; + if (this._credentials.LastError < 0) + this.SetError((HRESULT)this._credentials.LastError); + this.SetWarning(credentials); + } + + protected override void OnInvoked(object sender, EventArgs args) + { + this._credentials.Save = this._rememberPassword.Value; + base.OnInvoked(sender, args); + } + + private void SetWarning(SubscriptonCredentialRequestArguments credentials) + { + string str = (string)null; + if (!credentials.IsAuthenticationSchemeSafe) + str = this.AuthSchemeToString(credentials.AuthScheme); + if (str != null) + this._warning = string.Format(Shell.LoadString(StringId.IDS_PODCAST_SIGN_IN_INSECURE_AUTH_WARNING), (object)str); + else + this._warning = (string)null; + } + } +} diff --git a/ZuneUI/PodcastSyncLimit.cs b/ZuneUI/PodcastSyncLimit.cs new file mode 100644 index 0000000..6e5ae6f --- /dev/null +++ b/ZuneUI/PodcastSyncLimit.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PodcastSyncLimit +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum PodcastSyncLimit + { + Invalid = -1, // 0xFFFFFFFF + Everything = 0, + AllUnplayed = 2, + FirstUnplayed = 3, + Nothing = 4, + } +} diff --git a/ZuneUI/PodcastTypeFilteringList.cs b/ZuneUI/PodcastTypeFilteringList.cs new file mode 100644 index 0000000..637d41f --- /dev/null +++ b/ZuneUI/PodcastTypeFilteringList.cs @@ -0,0 +1,39 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PodcastTypeFilteringList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using ZuneXml; + +namespace ZuneUI +{ + public class PodcastTypeFilteringList : FilterList + { + private const string PodcastTypeAudio = "audio"; + private const string PodcastTypeVideo = "video"; + private const string PodcastTypeAudioAndVideo = "both"; + private string _filterType; + + public string FilterType + { + get => this._filterType; + set + { + if (!(this._filterType != value)) + return; + this._filterType = value; + this.FirePropertyChanged(nameof(FilterType)); + this.ProduceFilteredList(); + } + } + + protected override bool ShouldIncludeItem(int sourceIndex, int targetIndex, object item) + { + if (!(item is PodcastSeries podcastSeries)) + return false; + string type = podcastSeries.Type; + return this._filterType == null || type == this._filterType; + } + } +} diff --git a/ZuneUI/PostalCodeDescriptor.cs b/ZuneUI/PostalCodeDescriptor.cs new file mode 100644 index 0000000..4aec9a6 --- /dev/null +++ b/ZuneUI/PostalCodeDescriptor.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PostalCodeDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class PostalCodeDescriptor : CountryFieldValidationPropertyDescriptor + { + public PostalCodeDescriptor(string name) + : base(name, CountryFieldValidatorType.PostalCode) + { + } + } +} diff --git a/ZuneUI/PrepaidCodePropertyDescriptor.cs b/ZuneUI/PrepaidCodePropertyDescriptor.cs new file mode 100644 index 0000000..100c3c7 --- /dev/null +++ b/ZuneUI/PrepaidCodePropertyDescriptor.cs @@ -0,0 +1,66 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PrepaidCodePropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text; + +namespace ZuneUI +{ + public class PrepaidCodePropertyDescriptor : PropertyDescriptor + { + private static int s_subLength = 5; + private static int s_subCount = 5; + private static int s_length = PrepaidCodePropertyDescriptor.s_subLength * PrepaidCodePropertyDescriptor.s_subCount; + private static int s_lengthWithDelimiters = PrepaidCodePropertyDescriptor.s_length + PrepaidCodePropertyDescriptor.s_subCount - 1; + private static string s_delimiter = "-"; + + public PrepaidCodePropertyDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : base(name, multiValueString, unknownString, PrepaidCodePropertyDescriptor.s_lengthWithDelimiters, required) + { + } + + public override bool IsValidInternal(string value) + { + bool flag = false; + if (value != null) + flag = value.Replace(PrepaidCodePropertyDescriptor.s_delimiter, "").Length == PrepaidCodePropertyDescriptor.s_length; + return flag; + } + + public override object ConvertFromString(string value) + { + string str = string.Empty; + if (value != null) + str = PrepaidCodePropertyDescriptor.AddDelimiters(value); + return (object)str; + } + + public override string ConvertToString(object value) => PrepaidCodePropertyDescriptor.AddDelimiters(value as string); + + public static string AddDelimiters(string value) + { + StringBuilder stringBuilder = new StringBuilder(PrepaidCodePropertyDescriptor.s_length); + if (value != null) + { + int num = 0; + for (int index = 0; index < value.Length; ++index) + { + if (char.IsLetterOrDigit(value[index])) + { + if (num % PrepaidCodePropertyDescriptor.s_subLength == 0 && num != 0) + stringBuilder.Append(PrepaidCodePropertyDescriptor.s_delimiter); + stringBuilder.Append(value[index]); + ++num; + } + } + } + return stringBuilder.ToString().ToUpper(); + } + } +} diff --git a/ZuneUI/PreparingPlayNotification.cs b/ZuneUI/PreparingPlayNotification.cs new file mode 100644 index 0000000..0e04354 --- /dev/null +++ b/ZuneUI/PreparingPlayNotification.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PreparingPlayNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class PreparingPlayNotification : Notification + { + public PreparingPlayNotification() + : base(NotificationTask.PreparingPlay, NotificationState.Normal, 10000) + { + } + } +} diff --git a/ZuneUI/PrivacyInfoSettings.cs b/ZuneUI/PrivacyInfoSettings.cs new file mode 100644 index 0000000..3044698 --- /dev/null +++ b/ZuneUI/PrivacyInfoSettings.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PrivacyInfoSettings +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + [Flags] + public enum PrivacyInfoSettings + { + None = 0, + AllowExplicitContent = 1, + AllowFriends = 2, + AllowMicrosoftCommunications = 4, + AllowPartnerCommunications = 8, + AllowPurchase = 16, // 0x00000010 + Communications = 32, // 0x00000020 + FriendsSharing = 64, // 0x00000040 + MusicSharing = 128, // 0x00000080 + ProfileCustomization = 256, // 0x00000100 + AllSocial = 512, // 0x00000200 + UsageCollection = 1024, // 0x00000400 + CreateNewAccount = UsageCollection | AllowMicrosoftCommunications, // 0x00000404 + CreateNewAccountWithSocial = CreateNewAccount | AllSocial, // 0x00000604 + CreateChildAccount = UsageCollection | AllowPurchase | AllowExplicitContent, // 0x00000411 + CreateChildAccountWithSocial = CreateChildAccount | ProfileCustomization | MusicSharing | FriendsSharing | Communications | AllowFriends, // 0x000005F3 + SocialSettings = UsageCollection | ProfileCustomization | MusicSharing | FriendsSharing | Communications, // 0x000005E0 + NewsletterSettings = AllowMicrosoftCommunications, // 0x00000004 + NoNewsletterSettings = SocialSettings | AllSocial | AllowPurchase | AllowFriends | AllowExplicitContent, // 0x000007F3 + All = NoNewsletterSettings | NewsletterSettings | AllowPartnerCommunications, // 0x000007FF + } +} diff --git a/ZuneUI/PrivacyInfoStep.cs b/ZuneUI/PrivacyInfoStep.cs new file mode 100644 index 0000000..4e7bc86 --- /dev/null +++ b/ZuneUI/PrivacyInfoStep.cs @@ -0,0 +1,500 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PrivacyInfoStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using Microsoft.Zune.Util; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class PrivacyInfoStep : AccountManagementStep + { + private BooleanChoice _allowMicrosoftCommunications; + private BooleanChoice _allowPartnerCommunications; + private BooleanChoice _usageCollection; + private PrivacyInfoSettings _showSettings; + private AccountSettings _committedSettings; + private FamilySettings _familySettings; + private IList _privacySettings; + private IList _familySettingsChoices; + + public PrivacyInfoStep( + Wizard owner, + AccountManagementWizardState state, + bool parentAccount, + PrivacyInfoSettings showSettings) + : base(owner, state, parentAccount) + { + this._showSettings = showSettings; + if (this.ShowingNewsletterSettings && !parentAccount) + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ACCOUNT_INFO_STEP); + else if (parentAccount || SignIn.Instance.SignedIn && SignIn.Instance.IsParentallyControlled) + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_FAMILY_HEADER); + else + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ACCOUNT_INFO_STEP); + this.Initialize((WizardPropertyEditor)null); + this.CanNavigateInto = false; + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#PrivacyInfoStep"; + + public override bool IsEnabled => this.ShowingSettings; + + public AccountSettings CommittedSettings + { + get => this._committedSettings; + set + { + if (this._committedSettings == value) + return; + this._committedSettings = value; + this.SetUncommittedSettings(); + this.FirePropertyChanged(nameof(CommittedSettings)); + } + } + + public PrivacyInfoSettings ShowSettings + { + get => this._showSettings; + set + { + if (this._showSettings == value) + return; + this._showSettings = value; + this.ResetSettings(); + this.FirePropertyChanged(nameof(ShowSettings)); + } + } + + public FamilySettings FamilySettings + { + get => this._familySettings; + private set + { + if (this._familySettings == value) + return; + this._familySettings = value; + this.FirePropertyChanged(nameof(FamilySettings)); + } + } + + public IList PrivacySettings + { + get => this._privacySettings; + private set + { + if (this._privacySettings == value) + return; + this._privacySettings = value; + this.FirePropertyChanged(nameof(PrivacySettings)); + } + } + + public IList FamilySettingsChoices + { + get => this._familySettingsChoices; + private set + { + if (this._familySettingsChoices == value) + return; + this._familySettingsChoices = value; + this.FirePropertyChanged(nameof(FamilySettingsChoices)); + } + } + + public bool ShowingCommunicationSetting => (this.ShowSettings & PrivacyInfoSettings.Communications) != PrivacyInfoSettings.None || (this.ShowSettings & PrivacyInfoSettings.AllSocial) != PrivacyInfoSettings.None; + + public bool ShowingCreateNewSettings => this.ShowSettings == PrivacyInfoSettings.CreateNewAccount || this.ShowSettings == PrivacyInfoSettings.CreateNewAccountWithSocial; + + public bool ShowingFriendsListSharingSetting => (this.ShowSettings & PrivacyInfoSettings.FriendsSharing) != PrivacyInfoSettings.None || (this.ShowSettings & PrivacyInfoSettings.AllSocial) != PrivacyInfoSettings.None; + + public bool ShowingMusingSharingSetting => (this.ShowSettings & PrivacyInfoSettings.MusicSharing) != PrivacyInfoSettings.None || (this.ShowSettings & PrivacyInfoSettings.AllSocial) != PrivacyInfoSettings.None; + + public bool ShowingNewsletterSettings => this.ShowSettings == PrivacyInfoSettings.AllowMicrosoftCommunications; + + public bool ShowingProfileCustomizationSetting => (this.ShowSettings & PrivacyInfoSettings.ProfileCustomization) != PrivacyInfoSettings.None || (this.ShowSettings & PrivacyInfoSettings.AllSocial) != PrivacyInfoSettings.None; + + public BooleanChoice AllowMicrosoftCommunications + { + get => this._allowMicrosoftCommunications; + set + { + if (this._allowMicrosoftCommunications == value) + return; + this._allowMicrosoftCommunications = value; + this.FirePropertyChanged(nameof(AllowMicrosoftCommunications)); + } + } + + public BooleanChoice AllowPartnerCommunications + { + get => this._allowPartnerCommunications; + set + { + if (this._allowPartnerCommunications == value) + return; + this._allowPartnerCommunications = value; + this.FirePropertyChanged(nameof(AllowPartnerCommunications)); + } + } + + public BooleanChoice UsageCollection + { + get => this._usageCollection; + set + { + if (this._usageCollection == value) + return; + this._usageCollection = value; + this.FirePropertyChanged(nameof(UsageCollection)); + } + } + + private bool CountrySupportsNewsletterOptions + { + get + { + bool flag = true; + if (this.State.BasicAccountInfoStep.IsEnabled) + { + AccountCountry country = AccountCountryList.Instance.GetCountry(this.State.BasicAccountInfoStep.SelectedCountry); + if (country != null) + flag = country.ShowNewsletterOptions; + } + return flag; + } + } + + private bool ShowingSettings => this.ShowSettings != PrivacyInfoSettings.None && (this.ShowSettings & PrivacyInfoSettings.NoNewsletterSettings) == PrivacyInfoSettings.None ? this.CountrySupportsNewsletterOptions : this.ShowSettings != PrivacyInfoSettings.None; + + internal override bool OnMovingNext() + { + string str = (string)null; + if (this.PrivacySettings != null) + { + foreach (PrivacySettingChoice privacySetting in (IEnumerable)this.PrivacySettings) + { + if (privacySetting.ChosenValue == null) + { + str = privacySetting.Description; + break; + } + } + } + if (this.FamilySettingsChoices != null) + { + foreach (FamilySettingChoice familySettingsChoice in (IEnumerable)this.FamilySettingsChoices) + { + if (familySettingsChoice.ChosenValue == null) + { + str = familySettingsChoice.Title; + break; + } + } + } + if (str == null) + { + this.StatusMessage = (string)null; + return base.OnMovingNext(); + } + this.StatusMessage = string.Format(Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_SELECT_VALUE), (object)str); + return false; + } + + protected override void OnActivate() + { + this.ServiceActivationRequestsDone = false; + base.OnActivate(); + } + + internal override void Deactivate() + { + base.Deactivate(); + this.SetCommittedSettings(); + } + + protected override void OnStartActivationRequests(object state) + { + this.InitializeHelpersOnWorkerThread(); + base.OnStartActivationRequests(state); + } + + protected void InitializeHelpersOnWorkerThread() + { + AccountCountryList.Instance.LoadDataOnWorkerThread(); + RatingSystemList.Instance.LoadDataOnWorkerThread(); + } + + protected override void OnEndActivationRequests(object args) + { + this.InitializeSettings(); + if (this.CountrySupportsNewsletterOptions) + return; + this.AllowMicrosoftCommunications = (BooleanChoice)null; + this.AllowPartnerCommunications = (BooleanChoice)null; + if ((this.ShowSettings & PrivacyInfoSettings.NoNewsletterSettings) != PrivacyInfoSettings.None) + return; + this._owner.MoveNext(); + } + + private void SetCommittedSettings() + { + this.SetDefaultSettings(); + if (this.AllowMicrosoftCommunications != null) + this.CommittedSettings.AllowZuneEmails = this.AllowMicrosoftCommunications.Value; + if (this.AllowPartnerCommunications != null) + this.CommittedSettings.AllowPartnerEmails = this.AllowPartnerCommunications.Value; + if (this.UsageCollection != null) + this.CommittedSettings.PrivacySettings[PrivacySettingId.UsageCollection] = this.UsageCollection.Value ? PrivacySettingValue.Allow : PrivacySettingValue.Deny; + if (this._privacySettings != null) + { + foreach (PrivacySettingChoice privacySetting in (IEnumerable)this._privacySettings) + { + if (privacySetting.SettingId == PrivacySettingId.Unknown) + this.SetCommittedSpecialProperties(privacySetting); + else + this.CommittedSettings.PrivacySettings[privacySetting.SettingId] = privacySetting.SettingValue; + } + } + if (this.FamilySettingsChoices == null || this.FamilySettingsChoices.Count <= 0) + return; + foreach (FamilySettingChoice familySettingsChoice in (IEnumerable)this.FamilySettingsChoices) + { + if (familySettingsChoice.SettingValue != null) + this.FamilySettings.SetSetting(familySettingsChoice.SettingId, familySettingsChoice.SettingValue.Value, familySettingsChoice.BlockUnrated.Value); + } + } + + private void SetCommittedSpecialProperties(PrivacySettingChoice multiSetting) + { + if (this.CommittedSettings == null || multiSetting == null || (multiSetting.SettingId != PrivacySettingId.Unknown || multiSetting.InfoSettings != PrivacyInfoSettings.AllSocial)) + return; + this.CommittedSettings.PrivacySettings[PrivacySettingId.Communication] = multiSetting.SettingValue; + this.CommittedSettings.PrivacySettings[PrivacySettingId.FriendsListSharing] = multiSetting.SettingValue; + this.CommittedSettings.PrivacySettings[PrivacySettingId.MusicSharing] = multiSetting.SettingValue; + this.CommittedSettings.PrivacySettings[PrivacySettingId.ProfileCustomization] = multiSetting.SettingValue; + } + + private void SetDefaultSettings() + { + if (this.CommittedSettings == null) + { + this.CommittedSettings = new AccountSettings(); + this.CommittedSettings.AllowZuneEmails = true; + if (this.State.BasicAccountInfoStep.NewAccounType == AccountUserType.Adult) + { + this.CommittedSettings.PrivacySettings[PrivacySettingId.ExplicitContent] = PrivacySettingValue.Allow; + this.CommittedSettings.PrivacySettings[PrivacySettingId.OnlineFriends] = PrivacySettingValue.Allow; + this.CommittedSettings.PrivacySettings[PrivacySettingId.PremiumContent] = PrivacySettingValue.Allow; + this.CommittedSettings.PrivacySettings[PrivacySettingId.UsageCollection] = this.UsageCollectionDefault; + this.CommittedSettings.PrivacySettings[PrivacySettingId.Communication] = this.ShowingCommunicationSetting ? PrivacySettingValue.Unknown : PrivacySettingValue.Deny; + this.CommittedSettings.PrivacySettings[PrivacySettingId.FriendsListSharing] = this.ShowingFriendsListSharingSetting ? PrivacySettingValue.Unknown : PrivacySettingValue.Deny; + this.CommittedSettings.PrivacySettings[PrivacySettingId.ProfileCustomization] = this.ShowingProfileCustomizationSetting ? PrivacySettingValue.Unknown : PrivacySettingValue.Deny; + this.CommittedSettings.PrivacySettings[PrivacySettingId.MusicSharing] = this.ShowingMusingSharingSetting ? PrivacySettingValue.Unknown : PrivacySettingValue.Deny; + } + else if (this.State.BasicAccountInfoStep.NewAccounType == AccountUserType.ChildWithSocial) + { + this.CommittedSettings.PrivacySettings[PrivacySettingId.ExplicitContent] = PrivacySettingValue.Unknown; + this.CommittedSettings.PrivacySettings[PrivacySettingId.OnlineFriends] = PrivacySettingValue.Unknown; + this.CommittedSettings.PrivacySettings[PrivacySettingId.PremiumContent] = PrivacySettingValue.Unknown; + this.CommittedSettings.PrivacySettings[PrivacySettingId.Communication] = PrivacySettingValue.Unknown; + this.CommittedSettings.PrivacySettings[PrivacySettingId.FriendsListSharing] = PrivacySettingValue.Unknown; + this.CommittedSettings.PrivacySettings[PrivacySettingId.ProfileCustomization] = PrivacySettingValue.Unknown; + this.CommittedSettings.PrivacySettings[PrivacySettingId.MusicSharing] = PrivacySettingValue.Unknown; + this.CommittedSettings.PrivacySettings[PrivacySettingId.UsageCollection] = this.UsageCollectionDefault; + } + else + { + this.CommittedSettings.PrivacySettings[PrivacySettingId.ExplicitContent] = PrivacySettingValue.Unknown; + this.CommittedSettings.PrivacySettings[PrivacySettingId.OnlineFriends] = PrivacySettingValue.Deny; + this.CommittedSettings.PrivacySettings[PrivacySettingId.PremiumContent] = PrivacySettingValue.Unknown; + this.CommittedSettings.PrivacySettings[PrivacySettingId.Communication] = PrivacySettingValue.Deny; + this.CommittedSettings.PrivacySettings[PrivacySettingId.FriendsListSharing] = PrivacySettingValue.Deny; + this.CommittedSettings.PrivacySettings[PrivacySettingId.ProfileCustomization] = PrivacySettingValue.Deny; + this.CommittedSettings.PrivacySettings[PrivacySettingId.MusicSharing] = PrivacySettingValue.Deny; + this.CommittedSettings.PrivacySettings[PrivacySettingId.UsageCollection] = this.UsageCollectionDefault; + } + } + if (this.FamilySettings != null) + return; + this.FamilySettings = new FamilySettings(); + if (!SignIn.Instance.SignedIn) + return; + this.FamilySettings.UserId = SignIn.Instance.LastSignedInUserId; + } + + private void SetUncommittedSettings() + { + if (this.IsDisposed) + return; + this.SetDefaultSettings(); + if (this.AllowMicrosoftCommunications != null) + this.AllowMicrosoftCommunications.Value = this.CommittedSettings.AllowZuneEmails; + if (this.AllowPartnerCommunications != null) + this.AllowPartnerCommunications.Value = this.CommittedSettings.AllowPartnerEmails; + if (this.UsageCollection != null && this.CommittedSettings.PrivacySettings.ContainsKey(PrivacySettingId.UsageCollection)) + this.UsageCollection.Value = this.CommittedSettings.PrivacySettings[PrivacySettingId.UsageCollection] == PrivacySettingValue.Allow; + if (this._privacySettings != null) + { + foreach (PrivacySettingChoice privacySetting in (IEnumerable)this._privacySettings) + { + if (privacySetting.SettingId == PrivacySettingId.Unknown) + this.SetUncommittedSpecialProperties(privacySetting); + else if (this.CommittedSettings.PrivacySettings.ContainsKey(privacySetting.SettingId)) + privacySetting.SettingValue = this.CommittedSettings.PrivacySettings[privacySetting.SettingId]; + } + } + if (this.FamilySettingsChoices == null) + return; + FamilySettings familySettings = SignIn.Instance.FamilySettings; + if (familySettings == null && this.State.TermsOfServiceStep.IsEnabled && !string.IsNullOrEmpty(this.State.TermsOfServiceStep.Username)) + { + int idFromPassportId = SignIn.GetUserIdFromPassportId(this.State.TermsOfServiceStep.Username); + if (idFromPassportId != 0) + familySettings = new FamilySettings(idFromPassportId); + } + if (familySettings == null) + return; + this.FamilySettings.Settings = new Dictionary((IDictionary)familySettings.Settings); + foreach (FamilySettingChoice familySettingsChoice in (IEnumerable)this.FamilySettingsChoices) + { + RatingSystemList.Instance.GetRatingSystem(familySettingsChoice.SettingId); + if (familySettings.Settings.ContainsKey(familySettingsChoice.SettingId)) + { + familySettingsChoice.SettingValue = familySettingsChoice.GetSettingValueById(familySettings.Settings[familySettingsChoice.SettingId].RatingLevel); + familySettingsChoice.BlockUnrated.Value = familySettings.Settings[familySettingsChoice.SettingId].BlockUnrated; + } + } + } + + private PrivacySettingValue UsageCollectionDefault + { + get + { + bool flag = false; + string abbreviation = (string)null; + if (SignIn.Instance.SignedIn) + abbreviation = SignIn.Instance.CountryCode; + else if (this.State.BasicAccountInfoStep.IsEnabled) + abbreviation = this.State.BasicAccountInfoStep.SelectedCountry; + if (abbreviation != null) + { + AccountCountry country = AccountCountryList.Instance.GetCountry(abbreviation); + if (country != null) + flag = country.UsageCollection; + } + return !flag ? PrivacySettingValue.Deny : PrivacySettingValue.Allow; + } + } + + private void SetUncommittedSpecialProperties(PrivacySettingChoice multiSetting) + { + if (this.CommittedSettings == null || multiSetting == null || (multiSetting.SettingId != PrivacySettingId.Unknown || multiSetting.InfoSettings != PrivacyInfoSettings.AllSocial)) + return; + multiSetting.SettingValue = PrivacySettingValue.Unknown; + PrivacySettingValue privacySettingValue1 = this.CommittedSettings.PrivacySettings.ContainsKey(PrivacySettingId.Communication) ? this.CommittedSettings.PrivacySettings[PrivacySettingId.Communication] : PrivacySettingValue.Unknown; + PrivacySettingValue privacySettingValue2 = this.CommittedSettings.PrivacySettings.ContainsKey(PrivacySettingId.FriendsListSharing) ? this.CommittedSettings.PrivacySettings[PrivacySettingId.FriendsListSharing] : PrivacySettingValue.Unknown; + PrivacySettingValue privacySettingValue3 = this.CommittedSettings.PrivacySettings.ContainsKey(PrivacySettingId.MusicSharing) ? this.CommittedSettings.PrivacySettings[PrivacySettingId.MusicSharing] : PrivacySettingValue.Unknown; + PrivacySettingValue privacySettingValue4 = this.CommittedSettings.PrivacySettings.ContainsKey(PrivacySettingId.ProfileCustomization) ? this.CommittedSettings.PrivacySettings[PrivacySettingId.ProfileCustomization] : PrivacySettingValue.Unknown; + if (privacySettingValue1 != PrivacySettingValue.Unknown && (multiSetting.SettingValue == PrivacySettingValue.Unknown || multiSetting.SettingValue > privacySettingValue1)) + multiSetting.SettingValue = privacySettingValue1; + if (privacySettingValue2 != PrivacySettingValue.Unknown && (multiSetting.SettingValue == PrivacySettingValue.Unknown || multiSetting.SettingValue > privacySettingValue2)) + multiSetting.SettingValue = privacySettingValue2; + if (privacySettingValue3 != PrivacySettingValue.Unknown && (multiSetting.SettingValue == PrivacySettingValue.Unknown || multiSetting.SettingValue > privacySettingValue3)) + multiSetting.SettingValue = privacySettingValue3; + if (privacySettingValue4 == PrivacySettingValue.Unknown || multiSetting.SettingValue != PrivacySettingValue.Unknown && multiSetting.SettingValue <= privacySettingValue4) + return; + multiSetting.SettingValue = privacySettingValue4; + } + + private void ResetSettings() + { + this.AllowMicrosoftCommunications = (BooleanChoice)null; + this.AllowPartnerCommunications = (BooleanChoice)null; + this.UsageCollection = (BooleanChoice)null; + this.PrivacySettings = (IList)null; + this.FamilySettingsChoices = (IList)null; + this.FamilySettings = (FamilySettings)null; + if (this._owner.CurrentPage != this) + return; + this.InitializeSettings(); + } + + protected void InitializeSettings() + { + if (this.IsDisposed) + return; + if ((this.ShowSettings & PrivacyInfoSettings.AllowMicrosoftCommunications) == PrivacyInfoSettings.AllowMicrosoftCommunications && this._allowMicrosoftCommunications == null && this.CountrySupportsNewsletterOptions) + this._allowMicrosoftCommunications = new BooleanChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_COMM_DESC)); + if ((this.ShowSettings & PrivacyInfoSettings.AllowPartnerCommunications) == PrivacyInfoSettings.AllowPartnerCommunications && this._allowPartnerCommunications == null && this.CountrySupportsNewsletterOptions) + this._allowPartnerCommunications = new BooleanChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_PARTNER_DESC)); + bool flag = (this.ShowSettings & PrivacyInfoSettings.NoNewsletterSettings) != PrivacyInfoSettings.None; + if (this.PrivacySettings == null && flag) + { + ArrayList arrayList = new ArrayList(); + if ((this.ShowSettings & PrivacyInfoSettings.AllSocial) == PrivacyInfoSettings.AllSocial) + arrayList.Add((object)new PrivacySettingChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_ALL_SOCIAL_DESC), Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_ALL_SOCIAL_HEAD), PrivacySettingChoice.AllowFriendDenyChoices, PrivacySettingId.Unknown, PrivacyInfoSettings.AllSocial)); + if ((this.ShowSettings & PrivacyInfoSettings.AllowExplicitContent) == PrivacyInfoSettings.AllowExplicitContent) + { + StringId stringId1 = StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_DESC; + StringId stringId2 = StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_HEAD; + string linkDescription = string.Empty; + string linkUrl = string.Empty; + if (FeatureEnablement.IsFeatureEnabled(Features.eApps) || FeatureEnablement.IsFeatureEnabled(Features.eGames)) + { + linkDescription = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_LINK); + linkUrl = "http://go.microsoft.com/fwlink/?LinkId=218881"; + if (FeatureEnablement.IsFeatureEnabled(Features.eMusic)) + { + stringId1 = StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_DESC2; + stringId2 = StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_HEAD2; + } + else + { + stringId1 = StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_DESC3; + stringId2 = StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_HEAD3; + } + } + arrayList.Add((object)new PrivacySettingChoice((IModelItemOwner)this, Shell.LoadString(stringId1), Shell.LoadString(stringId2), PrivacySettingChoice.AllowDenyChoices, PrivacySettingId.ExplicitContent, PrivacyInfoSettings.AllowExplicitContent, linkDescription, linkUrl)); + } + if ((this.ShowSettings & PrivacyInfoSettings.AllowFriends) == PrivacyInfoSettings.AllowFriends) + arrayList.Add((object)new PrivacySettingChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_NEWFRIEND_DESC), Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_NEWFRIEND_HEAD), PrivacySettingChoice.AllowDenyChoices, PrivacySettingId.OnlineFriends, PrivacyInfoSettings.AllowFriends)); + if ((this.ShowSettings & PrivacyInfoSettings.AllowPurchase) == PrivacyInfoSettings.AllowPurchase) + arrayList.Add((object)new PrivacySettingChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_PURCHASE_DESC), Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_PURCHASE_HEAD), PrivacySettingChoice.AllowDenyChoices, PrivacySettingId.PremiumContent, PrivacyInfoSettings.AllowPurchase)); + if ((this.ShowSettings & PrivacyInfoSettings.Communications) == PrivacyInfoSettings.Communications) + arrayList.Add((object)new PrivacySettingChoice((IModelItemOwner)this, Shell.LoadString(this.ParentAccount ? StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_COMM_DESC : StringId.IDS_ACCOUNT_CREATION_ZUNE_SOCIAL_COMM_DESC), Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_SOCIAL_COMM_HEADER), PrivacySettingChoice.AllowFriendDenyChoices, PrivacySettingId.Communication, PrivacyInfoSettings.Communications)); + if ((this.ShowSettings & PrivacyInfoSettings.FriendsSharing) == PrivacyInfoSettings.FriendsSharing) + arrayList.Add((object)new PrivacySettingChoice((IModelItemOwner)this, Shell.LoadString(this.ParentAccount ? StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_FRIENDS_DESC : StringId.IDS_ACCOUNT_CREATION_ZUNE_FRIENDS_DESC), Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_FRIENDS_HEAD), PrivacySettingChoice.AllowFriendDenyChoices, PrivacySettingId.FriendsListSharing, PrivacyInfoSettings.FriendsSharing)); + if ((this.ShowSettings & PrivacyInfoSettings.MusicSharing) == PrivacyInfoSettings.MusicSharing) + arrayList.Add((object)new PrivacySettingChoice((IModelItemOwner)this, Shell.LoadString(this.ParentAccount ? StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_MUSIC_DESC : StringId.IDS_ACCOUNT_CREATION_SOCIAL_PROP_DESC), Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_SOCIAL_PROP_HEADER), PrivacySettingChoice.AllowFriendDenyChoices, PrivacySettingId.MusicSharing, PrivacyInfoSettings.MusicSharing)); + if ((this.ShowSettings & PrivacyInfoSettings.ProfileCustomization) == PrivacyInfoSettings.ProfileCustomization) + arrayList.Add((object)new PrivacySettingChoice((IModelItemOwner)this, Shell.LoadString(this.ParentAccount ? StringId.IDS_ACCOUNT_CREATION_ZUNE_CHILD_PROFILE_DESC : StringId.IDS_ACCOUNT_CREATION_ZUNE_PROFILE_DESC), Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_PROFILE_HEAD), PrivacySettingChoice.AllowFriendDenyChoices, PrivacySettingId.ProfileCustomization, PrivacyInfoSettings.ProfileCustomization)); + if ((this.ShowSettings & PrivacyInfoSettings.UsageCollection) == PrivacyInfoSettings.UsageCollection && this._usageCollection == null) + this._usageCollection = new BooleanChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_PERSONALIZE_DESC)); + this.PrivacySettings = (IList)arrayList; + } + if (this.FamilySettingsChoices == null && flag && (RatingSystemList.Instance.RatingSystems != null && (this.ShowSettings & PrivacyInfoSettings.AllowExplicitContent) == PrivacyInfoSettings.AllowExplicitContent)) + { + ArrayList arrayList1 = new ArrayList(); + foreach (string ratingSystem1 in (IEnumerable)RatingSystemList.Instance.RatingSystems) + { + RatingSystem ratingSystem2 = RatingSystemList.Instance.GetRatingSystem(ratingSystem1); + ArrayList arrayList2 = new ArrayList(); + foreach (RatingValue rating in ratingSystem2.Ratings) + { + if (!rating.TreatAsUnrated) + arrayList2.Add((object)new FamilySettingValue(ratingSystem2.GetRatingName(rating.Order), rating.Order)); + } + arrayList1.Add((object)new FamilySettingChoice((IModelItemOwner)this, ratingSystem2.Title, ratingSystem2.Description, ratingSystem2.BlockText, ratingSystem2.Name, ratingSystem2.ShowBlockUnrated, (IList)arrayList2)); + } + this.FamilySettingsChoices = (IList)arrayList1; + } + this.SetUncommittedSettings(); + } + } +} diff --git a/ZuneUI/PrivacySettingChoice.cs b/ZuneUI/PrivacySettingChoice.cs new file mode 100644 index 0000000..6a92dfc --- /dev/null +++ b/ZuneUI/PrivacySettingChoice.cs @@ -0,0 +1,107 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PrivacySettingChoice +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using System.Collections; + +namespace ZuneUI +{ + public class PrivacySettingChoice : Choice + { + private string m_detailedDescription; + private PrivacySettingId m_settingId; + private PrivacyInfoSettings m_infoSettings; + private static IList s_allowDenyChoices; + private static IList s_allowFriendsDenyChoices; + + public PrivacySettingChoice( + IModelItemOwner owner, + string detailedDescription, + string description, + IList choices, + PrivacySettingId settingId, + PrivacyInfoSettings infoSettings, + string linkDescription, + string linkUrl) + : this(owner, detailedDescription, description, choices, settingId, infoSettings) + { + this.LinkDescription = linkDescription; + this.LinkUrl = linkUrl; + } + + public PrivacySettingChoice( + IModelItemOwner owner, + string detailedDescription, + string description, + IList choices, + PrivacySettingId settingId, + PrivacyInfoSettings infoSettings) + : base(owner, description, choices) + { + this.m_detailedDescription = detailedDescription; + this.m_settingId = settingId; + this.m_infoSettings = infoSettings; + } + + public PrivacySettingId SettingId => this.m_settingId; + + public PrivacyInfoSettings InfoSettings => this.m_infoSettings; + + public string DetailedDescription => this.m_detailedDescription; + + public PrivacySettingValue SettingValue + { + get => this.ChosenValue is PrivacySettingValue ? (PrivacySettingValue)this.ChosenValue : PrivacySettingValue.Unknown; + set + { + if (this.Options.Contains((object)value)) + { + this.ChosenValue = (object)value; + } + else + { + if (value != PrivacySettingValue.Unknown) + return; + this.Clear(); + } + } + } + + public string LinkDescription { get; private set; } + + public string LinkUrl { get; private set; } + + internal static IList AllowDenyChoices + { + get + { + if (PrivacySettingChoice.s_allowDenyChoices == null) + { + PrivacySettingChoice.s_allowDenyChoices = (IList)new ArrayList(2); + PrivacySettingChoice.s_allowDenyChoices.Add((object)PrivacySettingValue.Allow); + PrivacySettingChoice.s_allowDenyChoices.Add((object)PrivacySettingValue.Deny); + } + return PrivacySettingChoice.s_allowDenyChoices; + } + } + + internal static IList AllowFriendDenyChoices + { + get + { + if (PrivacySettingChoice.s_allowFriendsDenyChoices == null) + { + PrivacySettingChoice.s_allowFriendsDenyChoices = (IList)new ArrayList(3); + PrivacySettingChoice.s_allowFriendsDenyChoices.Add((object)PrivacySettingValue.Allow); + PrivacySettingChoice.s_allowFriendsDenyChoices.Add((object)PrivacySettingValue.FriendsOnly); + PrivacySettingChoice.s_allowFriendsDenyChoices.Add((object)PrivacySettingValue.Deny); + } + return PrivacySettingChoice.s_allowFriendsDenyChoices; + } + } + } +} diff --git a/ZuneUI/PrivacySettingsWizard.cs b/ZuneUI/PrivacySettingsWizard.cs new file mode 100644 index 0000000..1628ba4 --- /dev/null +++ b/ZuneUI/PrivacySettingsWizard.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PrivacySettingsWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class PrivacySettingsWizard : AccountManagementWizard + { + private AccountManagementFinishStep _finishStep; + private AccountManagementErrorPage _errorStep; + private EditPrivacyInfoStep _editPrivacyInfoStep; + + public PrivacySettingsWizard() + { + this._editPrivacyInfoStep = new EditPrivacyInfoStep((Wizard)this, this.State, false, PrivacyInfoSettings.None); + this._finishStep = new AccountManagementFinishStep((Wizard)this, this.State, Shell.LoadString(StringId.IDS_ACCOUNT_FINISHED_DESCRIPTION), this.State.PrivacyInfoStep.DetailDescription); + this._errorStep = new AccountManagementErrorPage((Wizard)this, Shell.LoadString(StringId.IDS_ACCOUNT_PRIVACY_UPDATE_ERROR_TITLE), Shell.LoadString(StringId.IDS_ACCOUNT_PRIVACY_UPDATE_ERROR_DESC)); + this.AddPage((WizardPage)this.State.PassportPasswordParentStep); + this.AddPage((WizardPage)this._editPrivacyInfoStep); + this.AddPage((WizardPage)this._finishStep); + this.AddPage((WizardPage)this._errorStep); + } + + protected override void OnAsyncCommitCompleted(bool success) + { + base.OnAsyncCommitCompleted(success); + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_ACCOUNT_PRIVACY_UPDATE_SUCCESS_DESC); + if (!success) + return; + SignIn.Instance.RefreshAccount(); + } + } +} diff --git a/ZuneUI/ProfileAttachment.cs b/ZuneUI/ProfileAttachment.cs new file mode 100644 index 0000000..5237a33 --- /dev/null +++ b/ZuneUI/ProfileAttachment.cs @@ -0,0 +1,37 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public class ProfileAttachment : Attachment + { + public const string RequestTypeString = "card"; + + public ProfileAttachment(string zuneTag, string status, string imageUri) + : base(Guid.Empty, zuneTag, status, imageUri) + { + this.AttachmentUI = "res://ZuneShellResources!SocialComposer.uix#ProfileAttachmentUI"; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_FRIEND_ATTACHMENT); + } + + public override MediaType MediaType => MediaType.UserCard; + + public override string RequestType => "card"; + + public override string[] Properties => new string[4] + { + "type", + this.RequestType, + "zunetag", + this.Title + }; + + public override void LogSend() => SQMLog.Log(SQMDataId.InboxMessageSendProfileCard, 1); + } +} diff --git a/ZuneUI/ProfileBadge.cs b/ZuneUI/ProfileBadge.cs new file mode 100644 index 0000000..3a26e67 --- /dev/null +++ b/ZuneUI/ProfileBadge.cs @@ -0,0 +1,75 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileBadge +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; +using ZuneXml; + +namespace ZuneUI +{ + public class ProfileBadge : NotifyPropertyChangedImpl + { + private BadgeData _rawData; + private DataProviderObject _mediaData; + + public ProfileBadge(DataProviderObject rawData, DataProviderObject mediaData) + { + this._rawData = (BadgeData)rawData; + this._mediaData = mediaData; + } + + public DataProviderObject RawData => (DataProviderObject)this._rawData; + + public DataProviderObject MediaData + { + get => this._mediaData; + set + { + if (this._mediaData == value) + return; + this._mediaData = value; + this.FirePropertyChanged(nameof(MediaData)); + } + } + + public static ProfileBadge.GroupingComparer CreateGroupingComparer() => new ProfileBadge.GroupingComparer(); + + public class GroupingComparer : IComparer + { + public int Compare(object x, object y) + { + int num = -1; + BadgeData badgeData1 = (BadgeData)null; + BadgeData badgeData2 = (BadgeData)null; + if (x is ProfileBadge) + badgeData1 = ((ProfileBadge)x)._rawData; + else if (x is BadgeData) + badgeData1 = (BadgeData)x; + if (y is ProfileBadge) + badgeData2 = ((ProfileBadge)y)._rawData; + else if (y is BadgeData) + badgeData2 = (BadgeData)y; + if (badgeData1 != null && badgeData2 != null) + { + int typeId1 = badgeData1.TypeId; + int typeId2 = badgeData2.TypeId; + if (typeId1 < 0 && typeId2 < 0) + { + string type1 = badgeData1.Type; + string type2 = badgeData2.Type; + if (type1 != null && type2 != null) + num = string.Compare(type1, type2); + } + else if (typeId1 == typeId2) + num = 0; + else if (typeId1 > typeId2) + num = 1; + } + return num; + } + } + } +} diff --git a/ZuneUI/ProfileCardData.cs b/ZuneUI/ProfileCardData.cs new file mode 100644 index 0000000..338cdc3 --- /dev/null +++ b/ZuneUI/ProfileCardData.cs @@ -0,0 +1,152 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileCardData +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using ZuneXml; + +namespace ZuneUI +{ + public class ProfileCardData : IDatabaseMedia + { + private LibraryDataProviderListItem _libraryData; + private XmlDataProviderObject _serviceData; + private ProfileInterests _profileInterests; + private bool _isFriend; + private string _zuneTag; + private int _badgeCount; + + internal ProfileCardData( + LibraryDataProviderListItem libraryData, + XmlDataProviderObject serviceData) + { + this._libraryData = libraryData; + this._serviceData = serviceData; + this._isFriend = false; + this._badgeCount = -1; + } + + public static ProfileCardData Create(object item1, object item2) + { + LibraryDataProviderListItem libraryData = (LibraryDataProviderListItem)null; + XmlDataProviderObject serviceData = (XmlDataProviderObject)null; + if (item1 is LibraryDataProviderListItem) + libraryData = (LibraryDataProviderListItem)item1; + else if (item1 is XmlDataProviderObject) + serviceData = (XmlDataProviderObject)item1; + switch (item2) + { + case LibraryDataProviderListItem _: + libraryData = (LibraryDataProviderListItem)item2; + break; + case XmlDataProviderObject _: + serviceData = (XmlDataProviderObject)item2; + break; + } + return new ProfileCardData(libraryData, serviceData); + } + + public bool IsFriend + { + get => this._isFriend; + set => this._isFriend = value; + } + + public int BadgeCount + { + get => this._badgeCount; + set => this._badgeCount = value; + } + + public string ZuneTag + { + get + { + if (this._zuneTag == null) + { + if (this.LibraryData != null) + this._zuneTag = this.LibraryData.GetProperty(nameof(ZuneTag)) as string; + else if (this.ServiceData != null) + this._zuneTag = this.ServiceData.GetProperty(nameof(ZuneTag)) as string; + } + return this._zuneTag; + } + } + + public DataProviderObject LibraryData => (DataProviderObject)this._libraryData; + + public DataProviderObject ServiceData => (DataProviderObject)this._serviceData; + + public ProfileInterests ProfileInterests + { + get + { + if (this._profileInterests == null) + this._profileInterests = new ProfileInterests(); + return this._profileInterests; + } + } + + public void GetMediaIdAndType(out int mediaId, out EMediaTypes mediaType) + { + if (this._libraryData != null) + { + this._libraryData.GetMediaIdAndType(out mediaId, out mediaType); + } + else + { + mediaId = -1; + mediaType = EMediaTypes.eMediaTypeInvalid; + } + } + + public static object GetDataProviderObject(object data) + { + object obj = (object)null; + switch (data) + { + case ProfileCardData _: + ProfileCardData profileCardData = (ProfileCardData)data; + obj = profileCardData.ServiceData == null ? (object)profileCardData.LibraryData : (object)profileCardData.ServiceData; + break; + case DataProviderObject _: + obj = data; + break; + } + return obj; + } + + public static object GetLibraryDataProviderListItem(object data) + { + object obj = (object)null; + switch (data) + { + case ProfileCardData _: + obj = (object)((ProfileCardData)data).LibraryData; + break; + case LibraryDataProviderListItem _: + obj = data; + break; + } + return obj; + } + + public static object GetXmlDataProviderObject(object data) + { + object obj = (object)null; + switch (data) + { + case ProfileCardData _: + obj = (object)((ProfileCardData)data).ServiceData; + break; + case XmlDataProviderObject _: + obj = data; + break; + } + return obj; + } + } +} diff --git a/ZuneUI/ProfileCategories.cs b/ZuneUI/ProfileCategories.cs new file mode 100644 index 0000000..f23bab8 --- /dev/null +++ b/ZuneUI/ProfileCategories.cs @@ -0,0 +1,80 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileCategories +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class ProfileCategories + { + private static Category _badges; + private static Category _biography; + private static Category _favorites; + private static Category _lastPlayed; + private static Category _topArtists; + private static Category _comments; + + public static Category Badges + { + get + { + if (ProfileCategories._badges == null) + ProfileCategories._badges = new Category(StringId.IDS_PROFILE_BADGES_PIVOT, "res://ZuneShellResources!ProfileCategories.uix#ProfileCategoryBadges", false, SQMDataId.SocialViewBadges); + return ProfileCategories._badges; + } + } + + public static Category Biography + { + get + { + if (ProfileCategories._biography == null) + ProfileCategories._biography = new Category(StringId.IDS_PROFILE_BIOGRAPHY_PIVOT, "res://ZuneShellResources!ProfileCategories.uix#ProfileCategoryBiography", false, SQMDataId.SocialViewAbout); + return ProfileCategories._biography; + } + } + + public static Category Comments + { + get + { + if (ProfileCategories._comments == null) + ProfileCategories._comments = new Category(StringId.IDS_PROFILE_COMMENTS_PIVOT, "res://ZuneShellResources!ProfileCategories.uix#ProfileCategoryComments", false, SQMDataId.SocialViewComments); + return ProfileCategories._comments; + } + } + + public static Category Favorites + { + get + { + if (ProfileCategories._favorites == null) + ProfileCategories._favorites = new Category(StringId.IDS_PROFILE_FAVORITES_PIVOT, "res://ZuneShellResources!ProfileCategories.uix#ProfileCategoryFavorites", false, SQMDataId.SocialViewFavorites); + return ProfileCategories._favorites; + } + } + + public static Category RecentlyPlayed + { + get + { + if (ProfileCategories._lastPlayed == null) + ProfileCategories._lastPlayed = new Category(StringId.IDS_PROFILE_RECENTLY_PLAYED_PIVOT, "res://ZuneShellResources!ProfileCategories.uix#ProfileCategoryRecentlyPlayed", false, SQMDataId.SocialViewRecentPlays); + return ProfileCategories._lastPlayed; + } + } + + public static Category TopArtists + { + get + { + if (ProfileCategories._topArtists == null) + ProfileCategories._topArtists = new Category(StringId.IDS_PROFILE_MOST_PLAYED_ARTISTS_PIVOT, "res://ZuneShellResources!ProfileCategories.uix#ProfileCategoryTopArtists", false, SQMDataId.SocialViewTopArtists); + return ProfileCategories._topArtists; + } + } + } +} diff --git a/ZuneUI/ProfileDataHelper.cs b/ZuneUI/ProfileDataHelper.cs new file mode 100644 index 0000000..115e002 --- /dev/null +++ b/ZuneUI/ProfileDataHelper.cs @@ -0,0 +1,81 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileDataHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Win32; +using Microsoft.Zune.Configuration; +using System; + +namespace ZuneUI +{ + public static class ProfileDataHelper + { + private const int c_updateServicePlayCountHours = 2; + + public static int ProfilePlayCount + { + get => ProfileDataHelper.GetSetPlayCountCache(-1); + set => ProfileDataHelper.GetSetPlayCountCache(value); + } + + public static DateTime CommentsLastRead + { + get => ProfileDataHelper.GetCommentsLastRead(); + set => ProfileDataHelper.SetCommentsLastRead(value); + } + + private static SocialUserGuidConfiguration GetSocialUserGuidConfiguration( + string userGuid) + { + return new SocialUserGuidConfiguration(RegistryHive.CurrentUser, ClientConfiguration.Social.ConfigurationPath, userGuid); + } + + public static void InitializePlayCountCache() => ProfileDataHelper.GetSetPlayCountCache(ClientConfiguration.Service.LastSignedInUserGuid, -1, true); + + private static int GetSetPlayCountCache(int newValue) => ProfileDataHelper.GetSetPlayCountCache(ClientConfiguration.Service.LastSignedInUserGuid, newValue, false); + + private static int GetSetPlayCountCache(string userGuid, int newValue, bool clearStaleCache) + { + int num = -1; + if (!string.IsNullOrEmpty(userGuid) && userGuid != Guid.Empty.ToString()) + { + SocialUserGuidConfiguration guidConfiguration = ProfileDataHelper.GetSocialUserGuidConfiguration(userGuid); + num = guidConfiguration.ProfilePlayCount; + bool flag = false; + if (num < newValue) + flag = true; + else if (clearStaleCache) + flag = guidConfiguration.ProfilePlayCountUpdated.AddHours(2.0) <= DateTime.UtcNow; + if (flag) + { + guidConfiguration.ProfilePlayCount = newValue; + num = newValue; + if (clearStaleCache) + guidConfiguration.ProfilePlayCountUpdated = DateTime.UtcNow; + } + } + return num; + } + + private static DateTime GetCommentsLastRead() => ProfileDataHelper.GetCommentsLastRead(ClientConfiguration.Service.LastSignedInUserGuid); + + private static DateTime GetCommentsLastRead(string userGuid) + { + DateTime dateTime = DateTime.MinValue; + if (!string.IsNullOrEmpty(userGuid) && userGuid != Guid.Empty.ToString()) + dateTime = ProfileDataHelper.GetSocialUserGuidConfiguration(userGuid).ProfileCommentsLastRead; + return dateTime; + } + + private static void SetCommentsLastRead(DateTime commentsLastRead) => ProfileDataHelper.SetCommentsLastRead(ClientConfiguration.Service.LastSignedInUserGuid, commentsLastRead); + + private static void SetCommentsLastRead(string userGuid, DateTime commentsLastRead) + { + if (string.IsNullOrEmpty(userGuid) || !(userGuid != Guid.Empty.ToString())) + return; + ProfileDataHelper.GetSocialUserGuidConfiguration(userGuid).ProfileCommentsLastRead = commentsLastRead; + } + } +} diff --git a/ZuneUI/ProfileImage.cs b/ZuneUI/ProfileImage.cs new file mode 100644 index 0000000..45b8c93 --- /dev/null +++ b/ZuneUI/ProfileImage.cs @@ -0,0 +1,149 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileImage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class ProfileImage + { + private ProfileImageType m_type; + private string m_typeName; + private SafeBitmapWithData m_image; + private string m_source; + private static Size s_defaultTileSize; + private static Size s_defaultBackgroundSize; + + public ProfileImage(ProfileImageType type, SafeBitmapWithData image) + { + this.m_type = type; + this.m_image = image; + } + + public ProfileImage( + ProfileImageType type, + SafeBitmapWithData image, + int srcX, + int srcY, + int srcWidth, + int srcHeight) + { + this.m_type = type; + this.m_image = image.Clone(srcX, srcY, srcWidth, srcHeight, this.Width, this.Height); + } + + public ProfileImage(ProfileImageType type, string source) + { + this.m_type = type; + this.m_source = source; + } + + public ProfileImageType Type => this.m_type; + + public string TypeName + { + get + { + if (this.m_typeName == null) + this.m_typeName = this.m_type != ProfileImageType.Background ? (this.m_type != ProfileImageType.Tile ? string.Empty : "usertile") : "background"; + return this.m_typeName; + } + } + + public SafeBitmapWithData Image => this.m_image; + + public string ResourceId + { + get + { + string str = (string)null; + int startIndex = -1; + if (!string.IsNullOrEmpty(this.Source)) + startIndex = this.Source.IndexOf('!') + 1; + if (startIndex > 0 && this.Source.Length > startIndex) + str = this.Source.Substring(startIndex); + return str; + } + } + + public string Source => this.m_source; + + public int Width + { + get + { + int num = 0; + if (this.m_type == ProfileImageType.Background) + num = ProfileImage.DefaultBackgroundSize.Width; + else if (this.m_type == ProfileImageType.Tile) + num = ProfileImage.DefaultTileSize.Width; + return num; + } + } + + public int Height + { + get + { + int num = 0; + if (this.m_type == ProfileImageType.Background) + num = ProfileImage.DefaultBackgroundSize.Height; + else if (this.m_type == ProfileImageType.Tile) + num = ProfileImage.DefaultTileSize.Height; + return num; + } + } + + public static Size DefaultTileSize + { + get + { + if (ProfileImage.s_defaultTileSize == null) + ProfileImage.s_defaultTileSize = new Size(64, 64); + return ProfileImage.s_defaultTileSize; + } + } + + public static Size DefaultBackgroundSize + { + get + { + if (ProfileImage.s_defaultBackgroundSize == null) + ProfileImage.s_defaultBackgroundSize = new Size(535, 196); + return ProfileImage.s_defaultBackgroundSize; + } + } + + public static string[] SupportedFileTypes + { + get + { + string str1 = Shell.LoadString(StringId.IDS_IMAGE_ALL_FILTER_NAME); + string str2 = Shell.LoadString(StringId.IDS_IMAGE_JPEG_FILTER_NAME); + string str3 = Shell.LoadString(StringId.IDS_IMAGE_PNG_FILTER_NAME); + string str4 = Shell.LoadString(StringId.IDS_IMAGE_BITMAP_FILTER_NAME); + string str5 = Shell.LoadString(StringId.IDS_IMAGE_GIF_FILTER_NAME); + string str6 = Shell.LoadString(StringId.IDS_IMAGE_TIFF_FILTER_NAME); + return new string[12] + { + str1, + "*.jpg;*.jpeg;*.jpe;*.jfif;*.png;*.bmp;*.dip;*.gif;*.tif;*.tiff", + str4, + "*.bmp;*.dib", + str2, + "*.jpg;*.jpeg;*.jpe;*.jfif", + str5, + "*.gif", + str6, + "*.tif;*.tiff", + str3, + "*.png" + }; + } + } + } +} diff --git a/ZuneUI/ProfileImageType.cs b/ZuneUI/ProfileImageType.cs new file mode 100644 index 0000000..b467ff3 --- /dev/null +++ b/ZuneUI/ProfileImageType.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileImageType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum ProfileImageType + { + Tile, + Background, + } +} diff --git a/ZuneUI/ProfileInterests.cs b/ZuneUI/ProfileInterests.cs new file mode 100644 index 0000000..e1a181a --- /dev/null +++ b/ZuneUI/ProfileInterests.cs @@ -0,0 +1,134 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileInterests +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using ZuneXml; + +namespace ZuneUI +{ + public class ProfileInterests : NotifyPropertyChangedImpl + { + private const int c_maxIterests = 4; + private IList _recentPlays; + private IList _favorites; + private IList _topArtists; + private ArrayList _topAlbums; + + public ProfileInterests() => this._topAlbums = new ArrayList(4); + + public IList RecentPlays + { + get => this._recentPlays; + set + { + if (this._recentPlays == value) + return; + if (this._recentPlays == null) + { + this._recentPlays = value; + this.AddNewTopAlbums(ProfileCategories.RecentlyPlayed, value); + } + else + { + this._recentPlays = value; + this.RecreateTopAlbums(); + } + this.FirePropertyChanged(nameof(RecentPlays)); + } + } + + public IList Favorites + { + get => this._favorites; + set + { + if (this._favorites == value) + return; + if (this._favorites == null) + { + this._favorites = value; + this.AddNewTopAlbums(ProfileCategories.Favorites, value); + } + else + { + this._favorites = value; + this.RecreateTopAlbums(); + } + this.FirePropertyChanged(nameof(Favorites)); + } + } + + public IList TopArtists + { + get => this._topArtists; + set + { + if (this._topArtists == value) + return; + if (this._topArtists == null) + { + this._topArtists = value; + this.AddNewTopAlbums(ProfileCategories.TopArtists, value); + } + else + { + this._topArtists = value; + this.RecreateTopAlbums(); + } + this.FirePropertyChanged(nameof(TopArtists)); + } + } + + public bool TopAlbumsFull => this._topAlbums.Count >= 4; + + public IList TopAlbums => (IList)this._topAlbums; + + private void AddNewTopAlbums(Category category, IList newInterests) + { + if (newInterests == null) + return; + foreach (object newInterest in (IEnumerable)newInterests) + { + if (this.TopAlbumsFull) + { + this.FirePropertyChanged("TopAlbumsFull"); + break; + } + Track track = newInterest as Track; + if (this.CanAddTrack(track)) + { + this._topAlbums.Add((object)new ProfileTrack(category, (DataProviderObject)track)); + this.FirePropertyChanged("TopAlbums"); + } + } + } + + private bool CanAddTrack(Track track) + { + if (track == null || string.IsNullOrEmpty(track.AlbumTitle)) + return false; + Guid albumId = track.AlbumId; + if (Guid.Empty == albumId) + return false; + foreach (ProfileTrack topAlbum in this._topAlbums) + { + if (((Track)topAlbum.Track).AlbumId == albumId) + return false; + } + return true; + } + + private void RecreateTopAlbums() + { + this._topAlbums.Clear(); + this.AddNewTopAlbums(ProfileCategories.RecentlyPlayed, this._recentPlays); + this.AddNewTopAlbums(ProfileCategories.Favorites, this._favorites); + this.AddNewTopAlbums(ProfileCategories.TopArtists, this._topArtists); + } + } +} diff --git a/ZuneUI/ProfileMerger.cs b/ZuneUI/ProfileMerger.cs new file mode 100644 index 0000000..64da9d0 --- /dev/null +++ b/ZuneUI/ProfileMerger.cs @@ -0,0 +1,90 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileMerger +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneUI +{ + public static class ProfileMerger + { + public static IList Merge(IList profiles1, IList profiles2, bool matchesOnly) => ProfileMerger.Merge(profiles1, profiles2, matchesOnly, (IComparer)new DataProviderPropertyComparer() + { + PropertyName = "ZuneTag" + }, new ProfileMerger.MergeObjects(ProfileMerger.MergeProfile)); + + public static IList MergeWithFriends(IList profiles, IList friends, bool matchesOnly) => ProfileMerger.Merge(profiles, friends, matchesOnly, (IComparer)new DataProviderPropertyComparer() + { + PropertyName = "ZuneTag" + }, new ProfileMerger.MergeObjects(ProfileMerger.MergeWithFriend)); + + public static ProfileCardData MergeWithFriends( + DataProviderObject profile, + IList friends) + { + return ProfileMerger.MergeWithFriends((IList)new object[1] + { + (object) profile + }, friends, false)[0] as ProfileCardData; + } + + public static object MergeProfile(object item1, object item2) => (object)ProfileCardData.Create(item1, item2); + + private static object MergeWithFriend(object profile, object friend) + { + ProfileCardData profileCardData = ProfileCardData.Create(profile, friend); + if (friend != null) + profileCardData.IsFriend = true; + return (object)profileCardData; + } + + private static IList Merge( + IList list1, + IList list2, + bool matchesOnly, + IComparer comparer, + ProfileMerger.MergeObjects mergeDelegate) + { + ArrayList arrayList; + if (list1 != null && list2 != null) + { + arrayList = new ArrayList(Math.Min(list1.Count, list2.Count)); + Hashtable hashtable = new Hashtable(); + int num = 0; + for (int index1 = 0; index1 < list1.Count; ++index1) + { + bool flag = false; + for (int index2 = num; index2 < list2.Count; ++index2) + { + if (!hashtable.ContainsKey((object)index2) && comparer.Compare(list1[index1], list2[index2]) == 0) + { + arrayList.Add(mergeDelegate(list1[index1], list2[index2])); + hashtable.Add((object)index2, (object)true); + if (num == index2) + ++num; + flag = true; + break; + } + } + if (!flag && !matchesOnly) + arrayList.Add(mergeDelegate(list1[index1], (object)null)); + } + } + else if (!matchesOnly && list1 != null) + { + arrayList = new ArrayList(list1.Count); + foreach (object obj in (IEnumerable)list1) + arrayList.Add(mergeDelegate(obj, (object)null)); + } + else + arrayList = new ArrayList(); + return (IList)arrayList; + } + + public delegate object MergeObjects(object item1, object item2); + } +} diff --git a/ZuneUI/ProfileMultiLinePropertyDescriptor.cs b/ZuneUI/ProfileMultiLinePropertyDescriptor.cs new file mode 100644 index 0000000..727427d --- /dev/null +++ b/ZuneUI/ProfileMultiLinePropertyDescriptor.cs @@ -0,0 +1,40 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileMultiLinePropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ProfileMultiLinePropertyDescriptor : ProfilePropertyDescriptor + { + private int _maxTrimmedLength; + + public ProfileMultiLinePropertyDescriptor( + string name, + string serviceName, + StringId displayNameId, + int maxTrimmedLength) + : base(name, serviceName, displayNameId, maxTrimmedLength * 2) + { + this._maxTrimmedLength = maxTrimmedLength; + } + + public int MaxTrimmedLength => this._maxTrimmedLength; + + public override string GetServiceValue(string value) + { + if (value != null) + value = value.Replace("\r\n", "\n"); + return value; + } + + public override bool IsValidInternal(string value) + { + value = this.GetServiceValue(value); + return (value == null || this._maxTrimmedLength >= value.Length) && base.IsValidInternal(value); + } + + public override object ConvertFromString(string value) => (object)this.GetServiceValue(base.ConvertFromString(value) as string); + } +} diff --git a/ZuneUI/ProfileNavigationCommandHandler.cs b/ZuneUI/ProfileNavigationCommandHandler.cs new file mode 100644 index 0000000..f91b636 --- /dev/null +++ b/ZuneUI/ProfileNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class ProfileNavigationCommandHandler : NavigationCommandHandlerBase + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)ProfilePage.CreateInstance(args); + } +} diff --git a/ZuneUI/ProfilePage.cs b/ZuneUI/ProfilePage.cs new file mode 100644 index 0000000..ee4de81 --- /dev/null +++ b/ZuneUI/ProfilePage.cs @@ -0,0 +1,139 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfilePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + public class ProfilePage : LibraryPage + { + private ProfilePanel _profilePanel; + public static readonly string ProfilePageTemplate = "res://ZuneShellResources!Profile.uix#ProfileLibrary"; + public static readonly string ProfileBackgroundTemplate = "res://ZuneShellResources!Profile.uix#ProfileBackground"; + + public static ProfilePage CreateInstance(IDictionary args) + { + string zuneTag = args != null ? args[(object)"ZuneTag"] as string : (string)null; + return new ProfilePage(string.IsNullOrEmpty(zuneTag) || SignIn.Instance.IsSignedInUser(zuneTag) ? Shell.MainFrame.Social.Me : Shell.MainFrame.Social.Friends); + } + + public ProfilePage(Node pivotPreference) + { + this.PivotPreference = pivotPreference; + this.IsRootPage = pivotPreference == Shell.MainFrame.Social.Me; + this.UI = ProfilePage.ProfilePageTemplate; + this.UIPath = "Social\\Profile"; + this.BackgroundUI = ProfilePage.ProfileBackgroundTemplate; + this.TransportControlStyle = TransportControlStyle.Music; + this.PlaybackContext = PlaybackContext.Music; + SignIn.Instance.SignInStatusUpdatedEvent += new EventHandler(this.OnSignedInStatusChange); + } + + protected override void OnDispose(bool fDisposing) + { + if (fDisposing) + SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignedInStatusChange); + base.OnDispose(fDisposing); + } + + private void OnSignedInStatusChange(object sender, EventArgs args) + { + if (!SignIn.Instance.SignedIn || this.PivotPreference != Shell.MainFrame.Social.Me) + return; + this.CreateProfilePanel((string)null, ProfileCategories.RecentlyPlayed, Guid.Empty, 0, (string)null); + } + + protected override void OnNavigatedToWorker() + { + string zuneTag = this.NavigationArguments != null ? this.NavigationArguments[(object)"ZuneTag"] as string : (string)null; + string selectedFriendTag = this.NavigationArguments != null ? this.NavigationArguments[(object)"FriendTag"] as string : (string)null; + Category profilePivot = ProfileCategories.RecentlyPlayed; + object obj1 = this.NavigationArguments != null ? this.NavigationArguments[(object)"Pivot"] : (object)null; + if (obj1 != null) + profilePivot = (Category)obj1; + int chosenSortFriends = 0; + object obj2 = this.NavigationArguments != null ? this.NavigationArguments[(object)"ChosenIndexSortFriends"] : (object)null; + if (obj2 != null) + chosenSortFriends = (int)obj2; + Guid playlistTrack = Guid.Empty; + object obj3 = this.NavigationArguments != null ? this.NavigationArguments[(object)"PlaylistTrack"] : (object)null; + if (obj3 != null) + playlistTrack = (Guid)obj3; + this.CreateProfilePanel(zuneTag, profilePivot, playlistTrack, chosenSortFriends, selectedFriendTag); + base.OnNavigatedToWorker(); + } + + private void CreateProfilePanel( + string zuneTag, + Category profilePivot, + Guid playlistTrack, + int chosenSortFriends, + string selectedFriendTag) + { + if (this.PivotPreference == Shell.MainFrame.Social.Me) + { + zuneTag = (string)null; + if (this.NavigationArguments != null) + this.NavigationArguments.Remove((object)"ZuneTag"); + } + this.ProfilePanel = new ProfilePanel(this, zuneTag, profilePivot, playlistTrack, chosenSortFriends, selectedFriendTag); + } + + public ProfilePanel ProfilePanel + { + get => this._profilePanel; + set + { + if (this._profilePanel == value) + return; + this._profilePanel = value; + this.FirePropertyChanged(nameof(ProfilePanel)); + } + } + + public override void InvokeSettings() => Shell.SettingsFrame.Settings.Account.Invoke(); + + public override IPageState SaveAndRelease() + { + ProfilePageState profilePageState = new ProfilePageState(this); + this._profilePanel.Release(); + this.Dispose(); + return (IPageState)profilePageState; + } + + public static void NavigateTo( + string zuneTag, + Category profilePivot, + Guid track, + string serviceContext) + { + bool flag = false; + if (ZuneShell.DefaultInstance.CurrentPage is ProfilePage) + { + ProfilePage currentPage = (ProfilePage)ZuneShell.DefaultInstance.CurrentPage; + if (SignIn.TagsMatch(currentPage.ProfilePanel.ZuneTag, zuneTag)) + { + currentPage.ProfilePanel.SelectedPivot = profilePivot; + currentPage.ProfilePanel.SelectedPlaylistTrack = track; + currentPage.ProfilePanel.CanChangeSelectedItem = true; + flag = true; + } + } + if (flag) + return; + Hashtable hashtable = new Hashtable(); + hashtable.Add((object)"ZuneTag", (object)zuneTag); + if (profilePivot != null) + hashtable.Add((object)"Pivot", (object)profilePivot); + if (!GuidHelper.IsEmpty(track)) + hashtable.Add((object)"PlaylistTrack", (object)track); + if (!string.IsNullOrEmpty(serviceContext)) + hashtable.Add((object)"ServiceContext", (object)serviceContext); + ZuneShell.DefaultInstance.Execute("Social\\Profile", (IDictionary)hashtable); + } + } +} diff --git a/ZuneUI/ProfilePageState.cs b/ZuneUI/ProfilePageState.cs new file mode 100644 index 0000000..4c0cd00 --- /dev/null +++ b/ZuneUI/ProfilePageState.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfilePageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + public class ProfilePageState : IPageState + { + private string _zuneTag; + private Category _profilePivot; + private int _chosenIndexSortFriends; + private Node _pivotPreference; + private string _selectedFriendTag; + private Guid _selectedPlaylistTrack; + + public ProfilePageState(ProfilePage page) + { + this._zuneTag = page.ProfilePanel.ZuneTag; + this._profilePivot = page.ProfilePanel.SelectedPivot; + this._chosenIndexSortFriends = page.ProfilePanel.ChosenIndexSortFriends; + this._pivotPreference = page.PivotPreference; + this._selectedFriendTag = page.ProfilePanel.SelectedFriendTag; + this._selectedPlaylistTrack = page.ProfilePanel.SelectedPlaylistTrack; + } + + public ProfilePage Restore() + { + Hashtable hashtable = new Hashtable(); + hashtable[(object)"ZuneTag"] = (object)this._zuneTag; + hashtable[(object)"Pivot"] = (object)this._profilePivot; + hashtable[(object)"ChosenIndexSortFriends"] = (object)this._chosenIndexSortFriends; + hashtable[(object)"FriendTag"] = (object)this._selectedFriendTag; + hashtable[(object)"PlaylistTrack"] = (object)this._selectedPlaylistTrack; + ProfilePage profilePage = new ProfilePage(this._pivotPreference); + profilePage.NavigationArguments = (IDictionary)hashtable; + return profilePage; + } + + public IPage RestoreAndRelease() => (IPage)this.Restore(); + + public void Release() + { + } + + public bool CanBeTrimmed => true; + } +} diff --git a/ZuneUI/ProfilePanel.cs b/ZuneUI/ProfilePanel.cs new file mode 100644 index 0000000..2f774c2 --- /dev/null +++ b/ZuneUI/ProfilePanel.cs @@ -0,0 +1,221 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfilePanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class ProfilePanel : LibraryPanel + { + private string _zuneTag; + private UserRelationship _relationshipToSignedInUser; + private DataProviderObject _profileData; + private PropertyEditProfile _propertyEditProfile; + private IList _friends; + private IList _pivotData; + private Category _selectedPivot; + private Guid _selectedPlaylistTrack; + private int _chosenIndexSortFriends; + private string _selectedFriendTag; + private bool _canChangeSelectedItem; + private bool _loaded; + private bool _forceLoadStatus; + + internal ProfilePanel( + ProfilePage page, + string zuneTag, + Category profilePivot, + Guid playlistTrack, + int chosenSortFriends, + string selectedFriendTag) + : base((IModelItemOwner)page) + { + this._zuneTag = zuneTag; + this._selectedPivot = profilePivot; + this._relationshipToSignedInUser = UserRelationship.Unknown; + this._chosenIndexSortFriends = chosenSortFriends; + this._selectedFriendTag = selectedFriendTag; + this._selectedPlaylistTrack = playlistTrack; + this._canChangeSelectedItem = true; + } + + public string ZuneTag => string.IsNullOrEmpty(this._zuneTag) ? SignIn.Instance.ZuneTag : this._zuneTag; + + public Category SelectedPivot + { + get => this._selectedPivot; + set + { + if (this._selectedPivot == value) + return; + this._selectedPivot = value; + this.FirePropertyChanged(nameof(SelectedPivot)); + this.SelectedPlaylistTrack = Guid.Empty; + } + } + + public Guid SelectedPlaylistTrack + { + get => this._selectedPlaylistTrack; + set + { + if (!(this._selectedPlaylistTrack != value)) + return; + this._selectedPlaylistTrack = value; + this.FirePropertyChanged(nameof(SelectedPlaylistTrack)); + } + } + + public bool CanChangeSelectedItem + { + get => this._canChangeSelectedItem; + set + { + if (this._canChangeSelectedItem == value) + return; + this._canChangeSelectedItem = value; + this.FirePropertyChanged(nameof(CanChangeSelectedItem)); + } + } + + public string SelectedFriendTag + { + get => this._selectedFriendTag; + set + { + if (!(this._selectedFriendTag != value)) + return; + this._selectedFriendTag = value; + this.FirePropertyChanged(nameof(SelectedFriendTag)); + } + } + + public int ChosenIndexSortFriends + { + get => this._chosenIndexSortFriends; + set + { + if (this._chosenIndexSortFriends == value) + return; + this._chosenIndexSortFriends = value; + this.FirePropertyChanged(nameof(ChosenIndexSortFriends)); + } + } + + public bool IsSignedInUser => this.RelationshipToSignedInUser == UserRelationship.Self; + + public UserRelationship RelationshipToSignedInUser + { + get + { + if (this._relationshipToSignedInUser == UserRelationship.Unknown && SignIn.Instance.IsSignedInUser(this.ZuneTag)) + this.RelationshipToSignedInUser = UserRelationship.Self; + return this._relationshipToSignedInUser; + } + set + { + if (this._relationshipToSignedInUser == value) + return; + this._relationshipToSignedInUser = value; + this.FirePropertyChanged(nameof(RelationshipToSignedInUser)); + this.FirePropertyChanged("IsSignedInUser"); + } + } + + public DataProviderObject ProfileData + { + get => this._profileData; + set + { + if (this._profileData == value) + return; + this._profileData = value; + this._propertyEditProfile = (PropertyEditProfile)null; + this.FirePropertyChanged(nameof(ProfileData)); + this.FirePropertyChanged("PropertyEditProfile"); + } + } + + public PropertyEditProfile PropertyEditProfile + { + get + { + if (this._propertyEditProfile == null) + this._propertyEditProfile = new PropertyEditProfile(this._profileData); + return this._propertyEditProfile; + } + } + + public IList Friends + { + get => this._friends; + set + { + if (this._friends == value) + return; + this._friends = value; + this.FirePropertyChanged(nameof(Friends)); + } + } + + public IList PivotData + { + get => this._pivotData; + set + { + if (this._pivotData == value) + return; + this._pivotData = value; + this.FirePropertyChanged(nameof(PivotData)); + } + } + + public bool Loaded + { + get => this._loaded; + set + { + if (this._loaded == value) + return; + this._loaded = value; + this.FirePropertyChanged(nameof(Loaded)); + } + } + + public bool ForceLoadStatus + { + get => this._forceLoadStatus; + set + { + if (this._forceLoadStatus == value) + return; + this._forceLoadStatus = value; + this.FirePropertyChanged(nameof(ForceLoadStatus)); + } + } + + public int GetFriendIndexFromZuneTag(string tagToFind) + { + int num1 = -1; + int num2 = 0; + if (this._friends != null && !string.IsNullOrEmpty(tagToFind)) + { + foreach (object friend in (IEnumerable)this._friends) + { + if (friend is ProfileCardData profileCardData && SignIn.TagsMatch(profileCardData.ZuneTag, tagToFind)) + { + num1 = num2; + break; + } + ++num2; + } + } + return num1; + } + } +} diff --git a/ZuneUI/ProfilePropertyDescriptor.cs b/ZuneUI/ProfilePropertyDescriptor.cs new file mode 100644 index 0000000..4c1e580 --- /dev/null +++ b/ZuneUI/ProfilePropertyDescriptor.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfilePropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ProfilePropertyDescriptor : PropertyDescriptor + { + private string _serviceName; + private StringId _displayNameId; + + public ProfilePropertyDescriptor( + string name, + string serviceName, + StringId displayNameId, + int maxTextLength) + : base(name, string.Empty, string.Empty, maxTextLength) + { + this._serviceName = serviceName; + this._displayNameId = displayNameId; + } + + public string ServiceName => this._serviceName; + + public StringId DisplayNameId => this._displayNameId; + + public virtual string GetServiceValue(string value) => value; + } +} diff --git a/ZuneUI/ProfileTrack.cs b/ZuneUI/ProfileTrack.cs new file mode 100644 index 0000000..7cf1a67 --- /dev/null +++ b/ZuneUI/ProfileTrack.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProfileTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class ProfileTrack + { + private Category _category; + private DataProviderObject _track; + + public ProfileTrack(Category category, DataProviderObject track) + { + this._category = category; + this._track = track; + } + + public Category Category => this._category; + + public DataProviderObject Track => this._track; + } +} diff --git a/ZuneUI/ProgressCommand.cs b/ZuneUI/ProgressCommand.cs new file mode 100644 index 0000000..95b3ba3 --- /dev/null +++ b/ZuneUI/ProgressCommand.cs @@ -0,0 +1,177 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProgressCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using ZuneXml; + +namespace ZuneUI +{ + public class ProgressCommand : Command + { + private const int PlaybackBufferSecs = 200; + private const int PlaybackThresholdSecs = 10; + private bool m_allowPlayback = true; + private float m_progress; + private float m_progressivePlaybackPoint; + private int m_secondsToDownload = -1; + private int m_secondsToProgressivePlayback = -1; + private int m_secondsToPlaybackThreshold = 5; + private DownloadTask m_downloadTask; + + public ProgressCommand() + { + } + + public ProgressCommand(IModelItem owner) + : base((IModelItemOwner)owner) + { + } + + public ProgressCommand(DownloadTask downloadTask) => this.m_downloadTask = downloadTask; + + public bool AllowProgressivePlayback + { + get => this.m_allowPlayback; + set + { + if (this.m_allowPlayback == value) + return; + this.m_allowPlayback = value; + this.FirePropertyChanged(nameof(AllowProgressivePlayback)); + } + } + + public float Progress + { + get => this.m_progress; + set + { + if ((double)this.m_progress == (double)value) + return; + this.m_progress = value; + this.FirePropertyChanged(nameof(Progress)); + } + } + + public float ProgressivePlaybackPoint + { + get => this.m_progressivePlaybackPoint; + private set + { + if ((double)this.m_progressivePlaybackPoint == (double)value) + return; + this.m_progressivePlaybackPoint = value; + this.FirePropertyChanged(nameof(ProgressivePlaybackPoint)); + } + } + + public int SecondsToProgressivePlayback + { + get => this.m_secondsToProgressivePlayback; + private set + { + if (this.m_secondsToProgressivePlayback == value) + return; + this.m_secondsToProgressivePlayback = value; + this.FirePropertyChanged(nameof(SecondsToProgressivePlayback)); + } + } + + public int SecondsToDownload + { + get => this.m_secondsToDownload; + private set + { + if (this.m_secondsToDownload == value) + return; + this.m_secondsToDownload = value; + this.FirePropertyChanged(nameof(SecondsToDownload)); + } + } + + public string TimeToProgressivePlayback => TimeFormattingHelper.FormatSeconds(this.SecondsToProgressivePlayback); + + public string TimeToDownload => TimeFormattingHelper.FormatSeconds(this.SecondsToDownload); + + protected void UpdateProgress(Guid taskId, float percent) + { + if (this.m_downloadTask == null) + this.m_downloadTask = DownloadManager.Instance.GetTask(taskId.ToString()); + else if (taskId == Guid.Empty && (double)percent < 0.0) + this.m_downloadTask = (DownloadTask)null; + float num1 = 0.0f; + int num2 = -1; + int num3 = -1; + if (this.m_downloadTask != null) + { + num2 = this.m_downloadTask.GetDownloadSecondsRemaining(); + int propertyInt = this.m_downloadTask.GetPropertyInt("PlaybackDuration"); + if (propertyInt > 0) + { + int secondsRemaining = this.m_downloadTask.GetDownloadFileSecondsRemaining(0); + if (secondsRemaining >= 0) + { + int num4 = secondsRemaining - propertyInt; + long bytesDownloaded = (long)this.m_downloadTask.GetBytesDownloaded(); + long fileSizeForPlayback = (long)this.CalculateMinimumFileSizeForPlayback(this.m_downloadTask.GetFinalFileSize(0), propertyInt); + int num5 = this.m_downloadTask.GetDownloadBytesPerSecond(); + if (num5 <= 0) + num5 = 1; + if (this.AllowProgressivePlayback) + { + int num6 = (int)((fileSizeForPlayback - bytesDownloaded) / (long)num5); + num3 = (num4 > num6 ? num4 : num6) + this.m_secondsToPlaybackThreshold; + if (num3 > 0) + { + num1 = percent + (100f - percent) * (float)num3 / (float)num2; + this.m_secondsToPlaybackThreshold = 10; + } + else + { + num3 = 0; + this.m_secondsToPlaybackThreshold = 0; + } + } + } + } + } + this.Progress = percent / 100f; + this.ProgressivePlaybackPoint = num1 / 100f; + this.SecondsToProgressivePlayback = num3; + this.SecondsToDownload = num2; + } + + public void InvokeProgressivePlayback() + { + if (this.m_downloadTask == null || this.SecondsToProgressivePlayback != 0) + return; + string tempFileName = this.m_downloadTask.GetTempFileName(0); + if (string.IsNullOrEmpty(tempFileName)) + return; + int propertyInt = this.m_downloadTask.GetPropertyInt("PlaybackDuration"); + if (propertyInt == 0) + return; + ulong finalFileSize = this.m_downloadTask.GetFinalFileSize(0); + ulong bytesDownloaded = this.m_downloadTask.GetBytesDownloaded(); + if (finalFileSize <= 0UL || bytesDownloaded <= this.CalculateMinimumFileSizeForPlayback(finalFileSize, propertyInt)) + return; + string uri = string.Format("zuneprogdl://{0}?duration={1}&size={2}", (object)tempFileName, (object)propertyInt, (object)finalFileSize); + string property1 = this.m_downloadTask.GetProperty("Title"); + string property2 = this.m_downloadTask.GetProperty("Artist"); + SingletonModelItem.Instance.PlayItem((object)new VideoPlaybackTrack(new Guid(this.m_downloadTask.GetProperty("ServiceId")), property1, property2, uri, true, false, false, false, false, VideoDefinitionEnum.None), PlayNavigationOptions.NavigateToNowPlaying); + } + + private ulong CalculateMinimumFileSizeForPlayback(ulong finalSize, int finalDuration) + { + ulong num = 0; + if (this.m_downloadTask != null) + num = finalSize / (ulong)finalDuration * 200UL; + return num; + } + } +} diff --git a/ZuneUI/ProgressNotification.cs b/ZuneUI/ProgressNotification.cs new file mode 100644 index 0000000..f423fa3 --- /dev/null +++ b/ZuneUI/ProgressNotification.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProgressNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ProgressNotification : MessageNotification + { + private int _percentage; + + public ProgressNotification( + string message, + NotificationTask taskType, + NotificationState notificationType) + : base(message, taskType, notificationType) + { + } + + public ProgressNotification( + string message, + NotificationTask taskType, + NotificationState notificationType, + int percentage) + : base(message, taskType, notificationType) + { + this._percentage = percentage; + } + + public int Percentage + { + set + { + if (this._percentage == value) + return; + this._percentage = value; + this.FirePropertyChanged(nameof(Percentage)); + } + get => this._percentage; + } + } +} diff --git a/ZuneUI/PropertyDescriptor.cs b/ZuneUI/PropertyDescriptor.cs new file mode 100644 index 0000000..fa250c5 --- /dev/null +++ b/ZuneUI/PropertyDescriptor.cs @@ -0,0 +1,116 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class PropertyDescriptor + { + private string _name; + private string _unknownString; + private string _multiValueString; + private int _maxTextLength; + private bool _required; + private object _defaultValue; + + public PropertyDescriptor( + string name, + string multiValueString, + string unknownString, + int maxTextLength, + bool required, + object defaultValue) + { + this._name = name; + this._unknownString = unknownString; + this._multiValueString = multiValueString; + this._maxTextLength = maxTextLength; + this._required = required; + this._defaultValue = defaultValue; + } + + public PropertyDescriptor( + string name, + string multiValueString, + string unknownString, + int maxTextLength, + bool required) + : this(name, multiValueString, unknownString, maxTextLength, required, (object)null) + { + } + + public PropertyDescriptor( + string name, + string multiValueString, + string unknownString, + int maxTextLength) + : this(name, multiValueString, unknownString, maxTextLength, false, (object)null) + { + } + + public PropertyDescriptor(string name, string multiValueString, string unknownString) + : this(name, multiValueString, unknownString, 1000, false, (object)null) + { + } + + public PropertyDescriptor( + string name, + string multiValueString, + string unknownString, + bool required) + : this(name, multiValueString, unknownString, 1000, required, (object)null) + { + this._required = required; + } + + public virtual string ConvertToString(object value, object state) => this.ConvertToString(value); + + public virtual string ConvertToString(object value) => value?.ToString(); + + public virtual object ConvertFromString(string value, object state) => this.ConvertFromString(value); + + public virtual object ConvertFromString(string value) => value != null ? (object)value.Trim() : (object)null; + + public bool IsValid(string value, object state) + { + string str = value; + if (str != null) + str = str.Trim(); + return (!this._required || !string.IsNullOrEmpty(str) && !(str == this._unknownString)) && (str == null || str.Length <= this._maxTextLength) && this.IsValidInternal(str, state); + } + + public virtual bool IsValidInternal(string value, object state) => this.IsValidInternal(value); + + public virtual bool IsValidInternal(string value) => true; + + public bool IsRequired(object state) => this.IsRequiredInternal(state); + + public virtual bool IsRequiredInternal(object state) => this.IsRequiredInternal(); + + public virtual bool IsRequiredInternal() => this._required; + + public bool Required => this.IsRequiredInternal(); + + internal virtual string GetOverlayString(object state) => string.Empty; + + internal virtual string GetLabelString(object state) => string.Empty; + + public object DefaultValue + { + get => this._defaultValue; + protected set => this._defaultValue = value; + } + + public virtual string DefaultError => (string)null; + + public string DescriptorName => this._name; + + public string UnknownString => this._unknownString; + + public string MultiValueString => this._multiValueString; + + public int MaxTextLength => this._maxTextLength; + } +} diff --git a/ZuneUI/PropertyEditCreditCard.cs b/ZuneUI/PropertyEditCreditCard.cs new file mode 100644 index 0000000..9e7f94c --- /dev/null +++ b/ZuneUI/PropertyEditCreditCard.cs @@ -0,0 +1,90 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PropertyEditCreditCard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Collections; + +namespace ZuneUI +{ + public class PropertyEditCreditCard : MetadataEditMedia + { + private CreditCard _creditCard; + private static PropertyDescriptor[] s_dataProviderProperties; + public static CountryFieldValidationPropertyDescriptor s_Street1 = new CountryFieldValidationPropertyDescriptor(nameof(Street1), CountryFieldValidatorType.Street1); + public static CountryFieldValidationPropertyDescriptor s_Street2 = new CountryFieldValidationPropertyDescriptor(nameof(Street2), CountryFieldValidatorType.Street2); + public static CountryFieldValidationPropertyDescriptor s_City = new CountryFieldValidationPropertyDescriptor(nameof(City), CountryFieldValidatorType.City); + public static CountryFieldValidationPropertyDescriptor s_District = new CountryFieldValidationPropertyDescriptor(nameof(District), CountryFieldValidatorType.District); + public static StateDescriptor s_State = new StateDescriptor(nameof(State)); + public static PostalCodeDescriptor s_PostalCode = new PostalCodeDescriptor(nameof(PostalCode)); + public static PhoneNumberDescriptors s_PhoneNumber = new PhoneNumberDescriptors(nameof(PhoneNumber), CountryFieldValidatorType.PhoneNumber); + public static CreditCardNumberDescriptor s_PhoneExtension = new CreditCardNumberDescriptor(nameof(PhoneExtension), string.Empty, string.Empty, false, false); + public static CardTypePropertyDescriptor s_CardType = new CardTypePropertyDescriptor(nameof(CardType), string.Empty, Shell.LoadString(StringId.IDS_BILLING_EDIT_CC_CCTYPE_EMPTY), true); + public static CountryFieldValidationPropertyDescriptor s_AccountHolderName = new CountryFieldValidationPropertyDescriptor(nameof(AccountHolderName), CountryFieldValidatorType.AccountHolderName); + public static CreditCardNumberDescriptor s_AccountNumber = new CreditCardNumberDescriptor(nameof(AccountNumber), string.Empty, string.Empty, true, true); + public static CreditCardNumberDescriptor s_CcvNumber = new CreditCardNumberDescriptor(nameof(CcvNumber), string.Empty, string.Empty, true, false); + public static CreditCardExpirationDateDescriptor s_ExpirationDate = new CreditCardExpirationDateDescriptor(nameof(ExpirationDate), string.Empty, string.Empty, true); + + public PropertyEditCreditCard(CreditCard creditCard) + { + this._source = CreditCardPropertySource.Instance; + this.Initialize(creditCard); + } + + protected void Initialize(CreditCard creditCard) + { + this._creditCard = creditCard; + if (PropertyEditCreditCard.s_dataProviderProperties == null) + PropertyEditCreditCard.s_dataProviderProperties = new PropertyDescriptor[13] + { + (PropertyDescriptor) PropertyEditCreditCard.s_Street1, + (PropertyDescriptor) PropertyEditCreditCard.s_Street2, + (PropertyDescriptor) PropertyEditCreditCard.s_City, + (PropertyDescriptor) PropertyEditCreditCard.s_District, + (PropertyDescriptor) PropertyEditCreditCard.s_State, + (PropertyDescriptor) PropertyEditCreditCard.s_PostalCode, + (PropertyDescriptor) PropertyEditCreditCard.s_PhoneNumber, + (PropertyDescriptor) PropertyEditCreditCard.s_PhoneExtension, + (PropertyDescriptor) PropertyEditCreditCard.s_CardType, + (PropertyDescriptor) PropertyEditCreditCard.s_AccountHolderName, + (PropertyDescriptor) PropertyEditCreditCard.s_AccountNumber, + (PropertyDescriptor) PropertyEditCreditCard.s_CcvNumber, + (PropertyDescriptor) PropertyEditCreditCard.s_ExpirationDate + }; + this.Initialize((IList)new object[1] + { + (object) creditCard + }, PropertyEditCreditCard.s_dataProviderProperties); + } + + public CreditCard CreditCard => this._creditCard; + + public static PropertyDescriptor Street1 => (PropertyDescriptor)PropertyEditCreditCard.s_Street1; + + public static PropertyDescriptor Street2 => (PropertyDescriptor)PropertyEditCreditCard.s_Street2; + + public static PropertyDescriptor City => (PropertyDescriptor)PropertyEditCreditCard.s_City; + + public static PropertyDescriptor District => (PropertyDescriptor)PropertyEditCreditCard.s_District; + + public static PropertyDescriptor State => (PropertyDescriptor)PropertyEditCreditCard.s_State; + + public static PropertyDescriptor PostalCode => (PropertyDescriptor)PropertyEditCreditCard.s_PostalCode; + + public static PropertyDescriptor PhoneNumber => (PropertyDescriptor)PropertyEditCreditCard.s_PhoneNumber; + + public static PropertyDescriptor PhoneExtension => (PropertyDescriptor)PropertyEditCreditCard.s_PhoneExtension; + + public static PropertyDescriptor CardType => (PropertyDescriptor)PropertyEditCreditCard.s_CardType; + + public static PropertyDescriptor AccountHolderName => (PropertyDescriptor)PropertyEditCreditCard.s_AccountHolderName; + + public static PropertyDescriptor AccountNumber => (PropertyDescriptor)PropertyEditCreditCard.s_AccountNumber; + + public static PropertyDescriptor CcvNumber => (PropertyDescriptor)PropertyEditCreditCard.s_CcvNumber; + + public static PropertyDescriptor ExpirationDate => (PropertyDescriptor)PropertyEditCreditCard.s_ExpirationDate; + } +} diff --git a/ZuneUI/PropertyEditProfile.cs b/ZuneUI/PropertyEditProfile.cs new file mode 100644 index 0000000..66e8797 --- /dev/null +++ b/ZuneUI/PropertyEditProfile.cs @@ -0,0 +1,103 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PropertyEditProfile +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Messaging; +using System.Collections; + +namespace ZuneUI +{ + public class PropertyEditProfile : MetadataEditMedia + { + private DataProviderObject _profile; + private static PropertyDescriptor[] s_dataProviderProperties; + public static ProfileMultiLinePropertyDescriptor s_Biography = new ProfileMultiLinePropertyDescriptor(nameof(Biography), "bio", StringId.IDS_PROFILE_EDIT_BIO, 300); + public static ProfilePropertyDescriptor s_DisplayName = new ProfilePropertyDescriptor(nameof(DisplayName), "displayname", StringId.IDS_PROFILE_EDIT_DISPLAYNAME, 15); + public static ProfilePropertyDescriptor s_Location = new ProfilePropertyDescriptor(nameof(Location), "location", StringId.IDS_PROFILE_EDIT_LOCATION, 30); + public static ProfilePropertyDescriptor s_Status = new ProfilePropertyDescriptor(nameof(Status), "status", StringId.IDS_PROFILE_EDIT_STATUS, 60); + + public PropertyEditProfile(DataProviderObject profile) + { + this._source = DataProviderObjectPropertySource.Instance; + this.Initialize(profile); + } + + protected void Initialize(DataProviderObject profile) + { + this._profile = profile; + if (PropertyEditProfile.s_dataProviderProperties == null) + PropertyEditProfile.s_dataProviderProperties = new PropertyDescriptor[4] + { + (PropertyDescriptor) PropertyEditProfile.s_Biography, + (PropertyDescriptor) PropertyEditProfile.s_DisplayName, + (PropertyDescriptor) PropertyEditProfile.s_Location, + (PropertyDescriptor) PropertyEditProfile.s_Status + }; + this.Initialize((IList)new object[1] + { + (object) this._profile + }, PropertyEditProfile.s_dataProviderProperties); + } + + public override void Commit() + { + base.Commit(); + foreach (ProfilePropertyDescriptor providerProperty in PropertyEditProfile.s_dataProviderProperties) + { + MetadataEditProperty property = this.GetProperty((PropertyDescriptor)providerProperty); + if (property.Modified) + ComposerHelper.ManageProfile(providerProperty.ServiceName, providerProperty.GetServiceValue(property.Value), new MessagingCallback(this.OnCommitComplete), (object)property); + } + } + + public void Undo() + { + foreach (PropertyDescriptor providerProperty in PropertyEditProfile.s_dataProviderProperties) + { + MetadataEditProperty property = this.GetProperty(providerProperty); + property.Value = property.OriginalValue; + property.Modified = false; + } + } + + public DataProviderObject Profile => this._profile; + + private void OnCommitCompleteDeferred(object args) + { + HRESULT hresult = (HRESULT)((object[])args)[0]; + if (!(((object[])args)[1] is MetadataEditProperty metadataEditProperty)) + return; + if (hresult.IsSuccess) + { + metadataEditProperty.OriginalValue = metadataEditProperty.Value; + } + else + { + if (metadataEditProperty.Descriptor is ProfilePropertyDescriptor) + { + string title = Shell.LoadString(((ProfilePropertyDescriptor)metadataEditProperty.Descriptor).DisplayNameId); + ErrorDialogInfo.Show(hresult.Int, title); + } + metadataEditProperty.Value = metadataEditProperty.OriginalValue; + } + metadataEditProperty.Modified = false; + } + + private void OnCommitComplete(HRESULT hr, object state) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnCommitCompleteDeferred), (object)new object[2] + { + (object) hr, + state + }); + + public static ProfileMultiLinePropertyDescriptor Biography => PropertyEditProfile.s_Biography; + + public static ProfilePropertyDescriptor DisplayName => PropertyEditProfile.s_DisplayName; + + public static ProfilePropertyDescriptor Location => PropertyEditProfile.s_Location; + + public static ProfilePropertyDescriptor Status => PropertyEditProfile.s_Status; + } +} diff --git a/ZuneUI/PropertyEditProfileImage.cs b/ZuneUI/PropertyEditProfileImage.cs new file mode 100644 index 0000000..fc33a34 --- /dev/null +++ b/ZuneUI/PropertyEditProfileImage.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PropertyEditProfileImage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Messaging; +using System; + +namespace ZuneUI +{ + public class PropertyEditProfileImage : NotifyPropertyChangedImpl + { + private ProfileImage m_lastImage; + + public event EventHandler CommitComplete; + + public ProfileImage LastImage + { + get => this.m_lastImage; + private set + { + if (this.m_lastImage == value) + return; + this.m_lastImage = value; + this.FirePropertyChanged(nameof(LastImage)); + } + } + + public void Commit(ProfileImage image) + { + if (ComposerHelper.ManageProfileImage(image, new MessagingCallback(this.OnCommitComplete), (object)image)) + return; + this.OnCommitComplete(HRESULT._E_FAIL, (object)image); + } + + private void OnCommitCompleteDeferred(object args) + { + HRESULT hresult = (HRESULT)((object[])args)[0]; + ProfileImage profileImage = ((object[])args)[1] as ProfileImage; + if (this.CommitComplete != null) + this.CommitComplete((object)this, (EventArgs)null); + this.FirePropertyChanged("CommitComplete"); + if (hresult.IsError) + { + this.LastImage = (ProfileImage)null; + Shell.ShowErrorDialog(hresult.Int, Shell.LoadString(StringId.IDS_PROFILE_EDIT_IMAGE_FAIL_TITLE)); + } + else + this.LastImage = profileImage; + } + + private void OnCommitComplete(HRESULT hr, object state) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnCommitCompleteDeferred), (object)new object[2] + { + (object) hr, + state + }); + } +} diff --git a/ZuneUI/PropertySetAttachment.cs b/ZuneUI/PropertySetAttachment.cs new file mode 100644 index 0000000..2624f97 --- /dev/null +++ b/ZuneUI/PropertySetAttachment.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PropertySetAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Messaging; +using System; + +namespace ZuneUI +{ + public abstract class PropertySetAttachment : Attachment + { + public PropertySetAttachment(Guid id, string title, string subtitle, string imageUri) + : base(Guid.Empty, title, subtitle, imageUri) + { + } + + public abstract IPropertySetMessageData PropertySet { get; } + } +} diff --git a/ZuneUI/PropertySource.cs b/ZuneUI/PropertySource.cs new file mode 100644 index 0000000..7d52ca8 --- /dev/null +++ b/ZuneUI/PropertySource.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PropertySource +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class PropertySource + { + public abstract object Get(object media, PropertyDescriptor property); + + public abstract void Set(object media, PropertyDescriptor property, object value); + + public virtual void Commit(object media) + { + } + + public virtual bool NeedsCommit => false; + } +} diff --git a/ZuneUI/ProxyCredentials.cs b/ZuneUI/ProxyCredentials.cs new file mode 100644 index 0000000..21459a7 --- /dev/null +++ b/ZuneUI/ProxyCredentials.cs @@ -0,0 +1,104 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProxyCredentials +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.UserCredential; +using System; +using System.Threading; + +namespace ZuneUI +{ + public class ProxyCredentials : NetworkSignInCredentials + { + private const int _maxCancelCount = 3; + private const int _maxFailedCount = 3; + private UserCredentialRequestArguments _credentials; + private static ProxyCredentials _instance; + private ProxySignIn _inputDialog; + private string _lastUIPathPrompted; + private string _lastSignInTargetUrl; + + private ProxyCredentials() + { + } + + public static ProxyCredentials Instance + { + get + { + if (ProxyCredentials._instance == null) + ProxyCredentials._instance = new ProxyCredentials(); + return ProxyCredentials._instance; + } + } + + public static bool HasInstance => ProxyCredentials._instance != null; + + public void Reset() + { + this._lastUIPathPrompted = ""; + this._signInCount = 0U; + this._cancelCount = 0U; + } + + public override void Phase2Init() => UserCredentialManager.Instance.SetCredentialHandler(new UserCredentialHandler(this.GetCredentials)); + + private bool GetCredentials(UserCredentialRequestArguments args) + { + this._completed = false; + if (this.CancelCount >= 3U || this.SignInCount >= 3U || this._lastUIPathPrompted == ZuneShell.DefaultInstance.CurrentPage.UIPath && this._lastSignInTargetUrl != args.TargetUrl) + { + if (args != null && args.Credential != null) + { + args.Credential.UserName = string.Empty; + args.Credential.Password = string.Empty; + } + } + else if (!Application.IsApplicationThread && this._dialogClosed == null) + { + this._dialogClosed = new EventWaitHandle(false, EventResetMode.ManualReset); + Application.DeferredInvoke(new DeferredInvokeHandler(this.ShowDialog), (object)args); + this._dialogClosed.WaitOne(); + this._dialogClosed.Close(); + this._dialogClosed = (EventWaitHandle)null; + } + return this._completed; + } + + private void ShowDialog(object args) + { + if (!Application.IsApplicationThread || !(args is UserCredentialRequestArguments)) + return; + if (this._inputDialog != null) + { + this._inputDialog.Dispose(); + this._inputDialog = (ProxySignIn)null; + } + this._credentials = (UserCredentialRequestArguments)args; + this._inputDialog = new ProxySignIn(this._credentials, new EventHandler(((NetworkSignInCredentials)this).OnDialogSignIn), new EventHandler(((NetworkSignInCredentials)this).OnDialogCanceled)); + this._inputDialog.Show(); + this._lastUIPathPrompted = ZuneShell.DefaultInstance.CurrentPage.UIPath; + } + + protected override void OnDialogSignIn(object sender, EventArgs args) + { + if (this._credentials != null) + this._lastSignInTargetUrl = this._credentials.TargetUrl; + base.OnDialogSignIn(sender, args); + } + + public override void Dispose() + { + UserCredentialManager.Instance.SetCredentialHandler((UserCredentialHandler)null); + if (this._inputDialog != null) + { + this._inputDialog.Dispose(); + this._inputDialog = (ProxySignIn)null; + } + base.Dispose(); + } + } +} diff --git a/ZuneUI/ProxySettingDelegate.cs b/ZuneUI/ProxySettingDelegate.cs new file mode 100644 index 0000000..b80654f --- /dev/null +++ b/ZuneUI/ProxySettingDelegate.cs @@ -0,0 +1,10 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProxySettingDelegate +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public delegate void ProxySettingDelegate(object data); +} diff --git a/ZuneUI/ProxySignIn.cs b/ZuneUI/ProxySignIn.cs new file mode 100644 index 0000000..4ba1309 --- /dev/null +++ b/ZuneUI/ProxySignIn.cs @@ -0,0 +1,71 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ProxySignIn +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.UserCredential; +using System; +using System.Net; + +namespace ZuneUI +{ + public class ProxySignIn : NetworkSignInDialogHelper + { + private UserCredentialRequestArguments _credentials; + + public override string UserName + { + get => this._credentials.Credential.UserName; + set => this._credentials.Credential.UserName = value; + } + + public override string Password + { + get => this._credentials.Credential.Password; + set => this._credentials.Credential.Password = value; + } + + public ProxySignIn( + UserCredentialRequestArguments credentials, + EventHandler signInHandler, + EventHandler cancelHandler) + : base(signInHandler, cancelHandler, "res://ZuneShellResources!SignInDialog.uix#ProxySignInDialogUI") + { + this._credentials = credentials; + this.Cancel.Invoked += new EventHandler(this.CancelInvoked); + this._credentials.Credential = new NetworkCredential(); + this._credentials.Credential.UserName = this._credentials.LastUserName; + if (this._credentials.LastError < 0) + this._error = Shell.LoadString(StringId.IDS_PROXY_LOGIN_BAD_CREDENTIALS); + this._title = Shell.LoadString(StringId.IDS_PROXY_LOGIN_TITLE); + this._realmName = this._credentials.Realm; + this._hostName = this._credentials.Host; + this.SetWarning(credentials); + } + + private void CancelInvoked(object sender, EventArgs args) + { + this.UserName = string.Empty; + this.Password = string.Empty; + this.Hide(); + } + + protected override void OnInvoked(object sender, EventArgs args) + { + this._credentials.Save = this._rememberPassword.Value; + base.OnInvoked(sender, args); + } + + private void SetWarning(UserCredentialRequestArguments credentials) + { + string str = (string)null; + if (!credentials.IsAuthenticationSchemeSafe) + str = this.AuthSchemeToString(credentials.AuthScheme); + if (str != null) + this._warning = string.Format(Shell.LoadString(StringId.IDS_PODCAST_SIGN_IN_INSECURE_AUTH_WARNING), (object)str); + else + this._warning = (string)null; + } + } +} diff --git a/ZuneUI/Purchase.cs b/ZuneUI/Purchase.cs new file mode 100644 index 0000000..76e7ab2 --- /dev/null +++ b/ZuneUI/Purchase.cs @@ -0,0 +1,1228 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Purchase +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.ErrorMapperApi; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using ZuneXml; + +namespace ZuneUI +{ + public class Purchase : ModelItem + { + private AlbumOfferCollection m_albumOfferCollection; + private TrackOfferCollection m_trackOfferCollection; + private VideoOfferCollection m_videoOfferCollection; + private AppOfferCollection m_appOfferCollection; + private IList m_albumOffers; + private IList m_trackOffers; + private IList m_videoOffers; + private IList m_appOffers; + private bool m_fPurchaseHD; + private bool m_fMultipleResolutionOptions; + private bool m_fMultiplePlaybackOptions; + private bool m_fRentVideos; + private bool m_fStreamVideos; + private bool m_fPurchaseTrials; + private bool m_fPurchaseSeason; + private bool m_hasSubscriptionFreeTracks; + private int m_rentDeviceId = -1; + private DateTime _videoExpirationDate = DateTime.MaxValue; + private bool m_fInsufficientPoints; + private int m_pointsBalance = -1; + private int m_subscriptionFreeTrackBalance = -1; + private int m_totalPoints = -1; + private double m_totalCurrencyPrice = -1.0; + private int m_totalSubscriptionFreeTracks = -1; + private string m_displayPointsPrice; + private string m_displayCurrencyPrice; + private string m_errorMessage; + private string m_errorWebHelpUrl; + private string m_status; + private string m_additionalStatus; + private string m_rentDeviceName; + private string m_rentDeviceEndpointId; + private bool m_rentDeviceSupportsHD = true; + private bool m_fRequestingBalances; + private bool m_fIsBalanceUpdated; + private bool m_fRequestingPointsOffers; + private bool m_fPurchaseComplete; + private bool m_fSubscriptionFreeTracksOnly; + private bool m_authorizationRequired; + private ResumePurchaseData m_resumePurchaseData; + private bool m_fCanPurchase; + private bool m_fCanDownload; + private bool m_fPurchasingPoints; + private BillingOffer m_pointsOffer; + private BillingOfferCollection m_pointsOffers; + private BillingOfferHelper m_pointsHelper; + + internal static event EventHandler PurchaseEvent; + + public Purchase() => this.m_fPurchaseHD = ClientConfiguration.Service.PurchaseHD; + + public void GetOffers( + IList guidAlbumIds, + IList guidTrackIds, + IList guidVideoIds, + IList guidAppIds) + { + this.GetOffers(guidAlbumIds, guidTrackIds, guidVideoIds, guidAppIds, false, (IDictionary)null); + } + + public void GetOffers( + IList guidAlbumIds, + IList guidTrackIds, + IList guidVideoIds, + IList guidAppIds, + bool subscriptionFreeTracksOnly) + { + this.GetOffers(guidAlbumIds, guidTrackIds, guidVideoIds, guidAppIds, subscriptionFreeTracksOnly, (IDictionary)null); + } + + public void GetOffers( + IList guidAlbumIds, + IList guidTrackIds, + IList guidVideoIds, + IList guidAppIds, + bool subscriptionFreeTracksOnly, + IDictionary mapIdToContext) + { + this.SubscriptionFreeTracksOnly = subscriptionFreeTracksOnly; + string deviceEndpointId = string.Empty; + if (this.RentVideos) + deviceEndpointId = this.RentDeviceEndpointId; + if (mapIdToContext == null) + mapIdToContext = (IDictionary)new Hashtable(); + this.UpdateContextMap(guidAlbumIds, guidTrackIds, mapIdToContext); + Microsoft.Zune.Service.EGetOffersFlags eGetOffersFlags = Microsoft.Zune.Service.EGetOffersFlags.None; + if (this.PurchaseSeason) + eGetOffersFlags |= Microsoft.Zune.Service.EGetOffersFlags.SeasonPurchase; + if (subscriptionFreeTracksOnly) + eGetOffersFlags |= Microsoft.Zune.Service.EGetOffersFlags.SubscriptionFreeTracks; + ZuneApplication.Service.GetOffers(guidAlbumIds, guidTrackIds, guidVideoIds, guidAppIds, mapIdToContext, eGetOffersFlags, deviceEndpointId, new GetOffersCompleteCallback(this.OnGetOffersComplete), new GetOffersErrorCallback(this.OnGetOffersError)); + } + + private void UpdateContextMap( + IList guidAlbumIds, + IList guidTrackIds, + IDictionary mapIdToContext) + { + ZunePage currentPage = ZuneShell.DefaultInstance.CurrentPage; + if (currentPage.NavigationArguments == null || !currentPage.NavigationArguments.Contains((object)"ReferrerContext")) + return; + string navigationArgument = (string)currentPage.NavigationArguments[(object)"ReferrerContext"]; + Guid guid1 = Guid.Empty; + Guid guid2 = Guid.Empty; + Guid guid3 = Guid.Empty; + if (currentPage.NavigationArguments.Contains((object)"ReferrerTrackId")) + guid1 = (Guid)currentPage.NavigationArguments[(object)"ReferrerTrackId"]; + else if (currentPage.NavigationArguments.Contains((object)"ReferrerAlbumId")) + guid2 = (Guid)currentPage.NavigationArguments[(object)"ReferrerAlbumId"]; + else if (currentPage.NavigationArguments.Contains((object)"ReferrerArtistId")) + guid3 = (Guid)currentPage.NavigationArguments[(object)"ReferrerArtistId"]; + if (guidAlbumIds != null) + { + foreach (Guid guidAlbumId in (IEnumerable)guidAlbumIds) + { + if (!mapIdToContext.Contains((object)guidAlbumId) && (guid3 != Guid.Empty || guid1 != Guid.Empty || guid2 == guidAlbumId)) + mapIdToContext[(object)guidAlbumId] = (object)navigationArgument; + } + } + if (guidTrackIds == null) + return; + foreach (Guid guidTrackId in (IEnumerable)guidTrackIds) + { + if (!mapIdToContext.Contains((object)guidTrackId) && (guid3 != Guid.Empty || guid2 != Guid.Empty || guid1 == guidTrackId)) + mapIdToContext[(object)guidTrackId] = (object)navigationArgument; + } + } + + public void GetBalances() + { + if (!this.m_fRequestingBalances) + { + this.m_fRequestingBalances = true; + ZuneApplication.Service.GetBalances(new GetBalancesCompleteCallback(this.OnGetBalancesComplete), new GetBalancesErrorCallback(this.OnGetBalancesError)); + } + if (this.m_fRequestingPointsOffers || this.m_pointsOffers != null) + return; + this.m_fRequestingPointsOffers = true; + ZuneApplication.Service.GetPointsOffers(new GetBillingOffersCompleteCallback(this.OnGetPointsOffersComplete), new GetBillingOffersErrorCallback(this.OnGetPointsOffersError)); + } + + public void PurchaseOffers(PaymentInstrument payment) + { + this.ErrorMessage = (string)null; + this.ErrorWebHelpUrl = (string)null; + ZuneApplication.Service.PurchaseOffers(payment, this.m_albumOfferCollection, this.m_trackOfferCollection, this.m_videoOfferCollection, this.m_appOfferCollection, this.PurchaseOffersFlags, new PurchaseOffersCompleteHandler(this.OnPurchaseOffersComplete)); + if (this.RentVideos) + this.Status = ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_RENTAL_IN_PROGRESS); + else + this.Status = ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_IN_PROGRESS); + } + + public void ResumePurchase(string purchaseHandle, string token) => ZuneApplication.Service.ResumePurchase(purchaseHandle, token, new AsyncCompleteHandler(this.OnResumePurchaseComplete)); + + public void PurchaseBestPointsOffer(PaymentInstrument paymentInstrument) + { + if (this.m_pointsOffer == null) + return; + this.PurchasingPoints = true; + this.PointsHelper.Purchase(this.m_pointsOffer, paymentInstrument); + this.UpdateState(); + } + + public int PointsBalance + { + get => this.m_pointsBalance <= 0 ? 0 : this.m_pointsBalance; + private set + { + if (this.m_pointsBalance == value) + return; + this.m_pointsBalance = value; + this.FirePropertyChanged(nameof(PointsBalance)); + } + } + + public bool IsBalanceUpdated + { + get => this.m_fIsBalanceUpdated; + private set + { + this.m_fIsBalanceUpdated = value; + this.FirePropertyChanged(nameof(IsBalanceUpdated)); + } + } + + public int SubscriptionFreeTrackBalance + { + get => this.m_subscriptionFreeTrackBalance <= 0 ? 0 : this.m_subscriptionFreeTrackBalance; + private set + { + if (this.m_subscriptionFreeTrackBalance == value) + return; + this.m_subscriptionFreeTrackBalance = value; + this.FirePropertyChanged(nameof(SubscriptionFreeTrackBalance)); + } + } + + public IList AlbumOffers + { + get => this.m_albumOffers; + private set + { + if (this.m_albumOffers == value) + return; + this.m_albumOffers = value; + this.FirePropertyChanged(nameof(AlbumOffers)); + } + } + + public IList TrackOffers + { + get => this.m_trackOffers; + private set + { + if (this.m_trackOffers == value) + return; + this.m_trackOffers = value; + this.FirePropertyChanged(nameof(TrackOffers)); + } + } + + public IList VideoOffers + { + get => this.m_videoOffers; + private set + { + if (this.m_videoOffers == value) + return; + this.m_videoOffers = value; + this.FirePropertyChanged(nameof(VideoOffers)); + } + } + + public IList AppOffers + { + get => this.m_appOffers; + private set + { + if (this.m_appOffers == value) + return; + this.m_appOffers = value; + this.FirePropertyChanged(nameof(AppOffers)); + } + } + + public bool AuthenticationRequired + { + get => this.m_authorizationRequired; + set + { + if (this.m_authorizationRequired == value) + return; + this.m_authorizationRequired = value; + this.FirePropertyChanged(nameof(AuthenticationRequired)); + } + } + + public ResumePurchaseData ResumePurchaseData + { + get => this.m_resumePurchaseData; + set + { + if (this.m_resumePurchaseData != null && !this.m_resumePurchaseData.Equals(value)) + return; + this.m_resumePurchaseData = value; + this.FirePropertyChanged(nameof(ResumePurchaseData)); + } + } + + public string AdditionalStatus + { + get => this.m_additionalStatus; + set + { + if (!(this.m_additionalStatus != value)) + return; + this.m_additionalStatus = value; + this.FirePropertyChanged(nameof(AdditionalStatus)); + this.UpdateState(); + } + } + + public bool MultiplePlaybackOptions + { + get => this.m_fMultiplePlaybackOptions; + private set + { + if (this.m_fMultiplePlaybackOptions == value) + return; + this.m_fMultiplePlaybackOptions = value; + this.FirePropertyChanged(nameof(MultiplePlaybackOptions)); + } + } + + public bool MultipleResolutionOptions + { + get => this.m_fMultipleResolutionOptions; + private set + { + if (this.m_fMultipleResolutionOptions == value) + return; + this.m_fMultipleResolutionOptions = value; + this.FirePropertyChanged(nameof(MultipleResolutionOptions)); + } + } + + public bool PurchaseHD + { + get => this.m_fPurchaseHD; + set + { + if (this.m_fPurchaseHD == value) + return; + this.m_fPurchaseHD = value; + this.FirePropertyChanged(nameof(PurchaseHD)); + this.UpdateVideoOffers(); + this.CalculateTotal(); + this.UpdateState(); + } + } + + public bool RentVideos + { + get => this.m_fRentVideos; + set + { + if (this.m_fRentVideos == value) + return; + this.m_fRentVideos = value; + this.FirePropertyChanged(nameof(RentVideos)); + this.UpdateVideoOffers(); + this.CalculateTotal(); + this.UpdateState(); + } + } + + public bool StreamVideos + { + get => this.m_fStreamVideos; + set + { + if (this.m_fStreamVideos == value) + return; + this.m_fStreamVideos = value; + this.FirePropertyChanged(nameof(StreamVideos)); + this.UpdateVideoOffers(); + this.CalculateTotal(); + this.UpdateState(); + } + } + + public bool PurchaseTrials + { + get => this.m_fPurchaseTrials; + set + { + if (this.m_fPurchaseTrials == value) + return; + this.m_fPurchaseTrials = value; + this.FirePropertyChanged(nameof(PurchaseTrials)); + this.UpdateAppOffers(); + this.CalculateTotal(); + this.UpdateState(); + } + } + + public bool PurchaseSeason + { + get => this.m_fPurchaseSeason; + set + { + if (this.m_fPurchaseSeason == value) + return; + this.m_fPurchaseSeason = value; + this.FirePropertyChanged(nameof(PurchaseSeason)); + this.UpdateVideoOffers(); + this.CalculateTotal(); + this.UpdateState(); + } + } + + public int RentDeviceId + { + get => this.m_rentDeviceId; + set + { + if (this.m_rentDeviceId == value) + return; + this.m_rentDeviceId = value; + this.FirePropertyChanged(nameof(RentDeviceId)); + this.UpdateState(); + } + } + + public string RentDeviceName + { + get => this.m_rentDeviceName ?? string.Empty; + set + { + if (!(this.m_rentDeviceName != value)) + return; + this.m_rentDeviceName = value; + this.FirePropertyChanged(nameof(RentDeviceName)); + } + } + + public string RentDeviceEndpointId + { + get => this.m_rentDeviceEndpointId ?? string.Empty; + set + { + if (!(this.m_rentDeviceEndpointId != value)) + return; + this.m_rentDeviceEndpointId = value; + this.FirePropertyChanged(nameof(RentDeviceEndpointId)); + } + } + + public bool RentDeviceSupportsHD + { + get => this.m_rentDeviceSupportsHD; + set + { + if (this.m_rentDeviceSupportsHD == value) + return; + this.m_rentDeviceSupportsHD = value; + this.FirePropertyChanged(nameof(RentDeviceSupportsHD)); + } + } + + public void ChangeRentDevice( + int deviceId, + string deviceEndpointId, + string deviceName, + bool deviceSupportsHD) + { + if (deviceId == this.RentDeviceId) + return; + if (this.m_albumOfferCollection != null && this.m_albumOfferCollection.Items != null && (this.m_trackOfferCollection != null && this.m_trackOfferCollection.Items != null) && (this.m_videoOfferCollection != null && this.m_videoOfferCollection.Items != null && (this.m_appOfferCollection != null && this.m_appOfferCollection.Items != null))) + { + this.m_albumOfferCollection.Items.Clear(); + this.m_trackOfferCollection.Items.Clear(); + this.m_videoOfferCollection.Items.Clear(); + this.m_appOfferCollection.Items.Clear(); + this.UpdateOffers(this.m_albumOfferCollection, this.m_trackOfferCollection, this.m_videoOfferCollection, this.m_appOfferCollection, 0); + this.AlbumOffers = (IList)null; + this.TrackOffers = (IList)null; + this.VideoOffers = (IList)null; + this.AppOffers = (IList)null; + } + this.RentDeviceId = deviceId; + this.RentDeviceEndpointId = deviceEndpointId; + this.RentDeviceName = deviceName; + this.RentDeviceSupportsHD = deviceSupportsHD; + } + + public void RentDeviceCountMaxExceeded() => ShipAssert.Assert(false); + + public string DisplayPointsPrice + { + get => this.m_displayPointsPrice; + private set + { + if (!(value != this.m_displayPointsPrice)) + return; + this.m_displayPointsPrice = value; + this.FirePropertyChanged(nameof(DisplayPointsPrice)); + } + } + + public string DisplayCurrencyPrice + { + get => this.m_displayCurrencyPrice; + private set + { + if (!(value != this.m_displayCurrencyPrice)) + return; + this.m_displayCurrencyPrice = value; + this.FirePropertyChanged(nameof(DisplayCurrencyPrice)); + } + } + + public bool IsFree => this.HasPrice && !this.HasSubscriptionFreeTracks && this.TotalPoints == 0 && this.TotalCurrencyPrice == 0.0; + + private bool HasSubscriptionFreeTracks + { + get => this.m_hasSubscriptionFreeTracks; + set + { + if (this.m_hasSubscriptionFreeTracks == value) + return; + this.m_hasSubscriptionFreeTracks = value; + this.FirePropertyChanged(nameof(HasSubscriptionFreeTracks)); + this.FirePropertyChanged("IsFree"); + } + } + + private bool HasPrice => this.m_totalPoints >= 0 || this.m_totalCurrencyPrice >= 0.0; + + public int TotalPoints + { + get => this.m_totalPoints <= 0 ? 0 : this.m_totalPoints; + private set + { + if (this.m_totalPoints == value) + return; + this.m_totalPoints = value; + this.FirePropertyChanged(nameof(TotalPoints)); + this.FirePropertyChanged("IsFree"); + } + } + + public double TotalCurrencyPrice + { + get => this.m_totalCurrencyPrice <= 0.0 ? 0.0 : this.m_totalCurrencyPrice; + private set + { + if (this.m_totalCurrencyPrice == value) + return; + this.m_totalCurrencyPrice = value; + this.FirePropertyChanged(nameof(TotalCurrencyPrice)); + this.FirePropertyChanged("IsFree"); + } + } + + public int TotalSubscriptionFreeTracks + { + get => this.m_totalSubscriptionFreeTracks <= 0 ? 0 : this.m_totalSubscriptionFreeTracks; + private set + { + if (this.m_totalSubscriptionFreeTracks == value) + return; + this.m_totalSubscriptionFreeTracks = value; + this.FirePropertyChanged(nameof(TotalSubscriptionFreeTracks)); + } + } + + public bool InsufficientPoints + { + get => this.m_fInsufficientPoints; + private set + { + if (this.m_fInsufficientPoints == value) + return; + this.m_fInsufficientPoints = value; + this.FirePropertyChanged(nameof(InsufficientPoints)); + } + } + + public bool CanPurchase + { + get => this.m_fCanPurchase; + private set + { + if (this.m_fCanPurchase == value) + return; + this.m_fCanPurchase = value; + this.FirePropertyChanged(nameof(CanPurchase)); + } + } + + public bool CanDownload + { + get => this.m_fCanDownload; + private set + { + if (this.m_fCanDownload == value) + return; + this.m_fCanDownload = value; + this.FirePropertyChanged(nameof(CanDownload)); + } + } + + public string ErrorMessage + { + get => this.m_errorMessage ?? string.Empty; + set + { + if (!(this.m_errorMessage != value)) + return; + this.m_errorMessage = value; + this.FirePropertyChanged(nameof(ErrorMessage)); + } + } + + public string ErrorWebHelpUrl + { + get => this.m_errorWebHelpUrl ?? string.Empty; + set + { + if (!(this.m_errorWebHelpUrl != value)) + return; + this.m_errorWebHelpUrl = value; + this.FirePropertyChanged(nameof(ErrorWebHelpUrl)); + } + } + + public bool SubscriptionFreeTracksOnly + { + get => this.m_fSubscriptionFreeTracksOnly; + private set + { + if (this.m_fSubscriptionFreeTracksOnly == value) + return; + this.m_fSubscriptionFreeTracksOnly = value; + this.FirePropertyChanged(nameof(SubscriptionFreeTracksOnly)); + } + } + + public string Status + { + get => this.m_status ?? string.Empty; + set + { + if (!(this.m_status != value)) + return; + this.m_status = value; + this.FirePropertyChanged(nameof(Status)); + } + } + + public DateTime VideoExpirationDate + { + get => this._videoExpirationDate; + set + { + if (!(this._videoExpirationDate != value)) + return; + this._videoExpirationDate = value; + this.FirePropertyChanged("ExpirationDate"); + } + } + + public bool PurchaseComplete + { + get => this.m_fPurchaseComplete; + set + { + if (this.m_fPurchaseComplete == value) + return; + this.m_fPurchaseComplete = value; + this.FirePropertyChanged(nameof(PurchaseComplete)); + } + } + + public bool PurchasingPoints + { + get => this.m_fPurchasingPoints; + private set + { + if (this.m_fPurchasingPoints == value) + return; + this.m_fPurchasingPoints = value; + this.FirePropertyChanged(nameof(PurchasingPoints)); + } + } + + public BillingOffer BestPointsOffer + { + get => this.m_pointsOffer; + private set + { + if (this.m_pointsOffer == value) + return; + this.m_pointsOffer = value; + this.FirePropertyChanged(nameof(BestPointsOffer)); + } + } + + private BillingOfferHelper PointsHelper + { + get + { + if (this.m_pointsHelper == null) + { + this.m_pointsHelper = new BillingOfferHelper(); + EventHandler eventHandler = new EventHandler(this.OnPointsPurchaseCompletedOrFailed); + this.m_pointsHelper.PurchaseComplete += eventHandler; + this.m_pointsHelper.PurchaseFailed += eventHandler; + } + return this.m_pointsHelper; + } + } + + private void UpdateState() + { + this.InsufficientPoints = this.m_totalPoints >= 0 && this.m_pointsBalance >= 0 && this.m_totalPoints > this.m_pointsBalance; + if (this.AlbumOffers != null && this.TrackOffers != null && (this.VideoOffers != null && this.AppOffers != null)) + { + if (this.AlbumOffers.Count == 0 && this.TrackOffers.Count == 0 && (this.VideoOffers.Count == 0 && this.AppOffers.Count == 0)) + this.Status = ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_NO_ITEMS); + else if (this.PurchasingPoints) + this.Status = ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_POINTS_IN_PROGRESS); + else if (this.InsufficientPoints) + { + this.CalculateBestPointsOffer(); + this.Status = ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_INSUFFICIENT_POINTS); + } + else + this.Status = this.TotalSubscriptionFreeTracks <= 0 ? (!this.MultipleResolutionOptions ? this.ConditionsOfPurchase : string.Format(ZuneUI.Shell.LoadString(this.PurchaseHD ? StringId.IDS_PURCHASE_HD_DESC_AND_CONDITIONS : StringId.IDS_PURCHASE_SD_DESC_AND_CONDITIONS), (object)this.ConditionsOfPurchase)) : (!this.SubscriptionFreeTracksOnly ? string.Format(ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_FREE_TRACKS_AND_NO_REFUNDS), (object)this.TotalSubscriptionFreeTracks) : ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_SUGGESTED_SONGS_NOTICE)); + } + else + this.Status = ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_CALC_TOTAL); + bool flag1 = false; + bool flag2 = false; + if (this.AlbumOffers != null) + { + foreach (AlbumOffer albumOffer in (IEnumerable)this.AlbumOffers) + { + if (!albumOffer.InCollection) + { + if (!albumOffer.PreviouslyPurchased) + flag2 = true; + else + flag1 = true; + } + } + } + if (this.TrackOffers != null) + { + foreach (TrackOffer trackOffer in (IEnumerable)this.TrackOffers) + { + if (!trackOffer.InCollection) + { + if (!trackOffer.PreviouslyPurchased) + flag2 = true; + else + flag1 = true; + } + } + } + if (this.VideoOffers != null) + { + foreach (VideoOffer videoOffer in (IEnumerable)this.VideoOffers) + { + if (!videoOffer.InCollection) + { + if (!videoOffer.PreviouslyPurchased) + flag2 = true; + else + flag1 = true; + } + } + } + if (this.AppOffers != null) + { + foreach (AppOffer appOffer in (IEnumerable)this.AppOffers) + { + if (!appOffer.InCollection) + { + if (!appOffer.PreviouslyPurchased) + flag2 = true; + else + flag1 = true; + } + } + } + this.CanPurchase = flag2 && !this.InsufficientPoints; + this.CanDownload = flag1 && !flag2; + } + + private string ConditionsOfPurchase + { + get + { + string empty = string.Empty; + string str = this.VideoOffers.Count <= 0 || this.RentVideos ? ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_NO_REFUNDS) : ((this.VideoExpirationDate - DateTime.UtcNow).Days <= 365 ? string.Format(ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_NO_REFUNDS_KNOWN_BLACKOUT), (object)this.VideoExpirationDate.ToLocalTime().ToShortDateString()) : ZuneUI.Shell.LoadString(StringId.IDS_PURCHASE_NO_REFUNDS_UNKNOWN_BLACKOUT)); + return !string.IsNullOrEmpty(this.AdditionalStatus) ? string.Format("{0} {1}", (object)str, (object)this.AdditionalStatus) : str; + } + } + + private void CalculateBestPointsOffer() + { + BillingOffer billingOffer1 = (BillingOffer)null; + if (this.m_pointsOffers != null) + { + int num = this.TotalPoints - this.PointsBalance; + foreach (BillingOffer billingOffer2 in (IEnumerable)this.m_pointsOffers.Items) + { + if ((long)billingOffer2.Points >= (long)num && (billingOffer1 == null || billingOffer1.Points > billingOffer2.Points)) + billingOffer1 = billingOffer2; + } + } + this.BestPointsOffer = billingOffer1; + } + + private void SetError(HRESULT hrError) + { + ErrorMapperResult descriptionAndUrl = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hrError.Int, eErrorCondition.eEC_Purchase); + this.ErrorMessage = descriptionAndUrl.Description; + this.ErrorWebHelpUrl = descriptionAndUrl.WebHelpUrl; + this.CanPurchase = false; + this.CanDownload = false; + this.Status = (string)null; + } + + private void OnGetBalancesComplete(int pointsBalance, int freeTrackBalance) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetBalancesComplete), (object)new int[2] + { + pointsBalance, + freeTrackBalance + }); + + private void OnGetBalancesError(HRESULT hrError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetBalancesError), (object)hrError); + + private void OnGetPointsOffersComplete(BillingOfferCollection pointsOffers) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetPointsOffersComplete), (object)pointsOffers); + + private void OnGetPointsOffersError(HRESULT hrError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetPointsOffersError), (object)hrError); + + private void OnGetOffersComplete( + AlbumOfferCollection albumOffers, + TrackOfferCollection trackOffers, + VideoOfferCollection videoOffers, + AppOfferCollection appOffers, + int subscriptionFreeTracks) + { + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredGetOffersComplete), (object)new object[5] + { + (object) albumOffers, + (object) trackOffers, + (object) videoOffers, + (object) appOffers, + (object) subscriptionFreeTracks + }); + } + + private void OnGetOffersError(HRESULT hrError) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetError), (object)hrError); + + private void OnResumePurchaseComplete(HRESULT hr) => this.OnPurchaseOffersComplete(hr, (string)null, (string)null); + + private void OnPurchaseOffersComplete(HRESULT hr, string redirectUrl, string handle) + { + if (this.AlbumOffers == null || this.TrackOffers == null || (this.VideoOffers == null || this.AppOffers == null)) + return; + if (hr.IsSuccess) + { + ArrayList arrayList = new ArrayList(this.AlbumOffers.Count + this.TrackOffers.Count + this.VideoOffers.Count + this.AppOffers.Count); + VideoPlaybackTrack videoPlaybackTrack = (VideoPlaybackTrack)null; + foreach (AlbumOffer albumOffer in (IEnumerable)this.AlbumOffers) + arrayList.Add((object)albumOffer); + foreach (TrackOffer trackOffer in (IEnumerable)this.TrackOffers) + arrayList.Add((object)trackOffer); + foreach (VideoOffer videoOffer in (IEnumerable)this.VideoOffers) + { + arrayList.Add((object)videoOffer); + if (videoOffer.IsStream && videoPlaybackTrack == null) + videoPlaybackTrack = new VideoPlaybackTrack(videoOffer.Id, videoOffer.Title, (string)null, (string)null, false, true, false, false, false, videoOffer.IsHD ? VideoDefinitionEnum.HD : VideoDefinitionEnum.SD); + } + foreach (AppOffer appOffer in (IEnumerable)this.AppOffers) + arrayList.Add((object)appOffer); + if (this.StreamVideos && videoPlaybackTrack != null) + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredPlayPurchasedStreams), (object)videoPlaybackTrack); + Microsoft.Zune.Service.EDownloadFlags eDownloadFlags = Microsoft.Zune.Service.EDownloadFlags.None; + if (this.RentVideos) + { + eDownloadFlags |= Microsoft.Zune.Service.EDownloadFlags.Rental; + if (this.RentDeviceId > 0) + eDownloadFlags |= Microsoft.Zune.Service.EDownloadFlags.DeviceLicensed; + } + if (this.StreamVideos) + eDownloadFlags |= Microsoft.Zune.Service.EDownloadFlags.Stream; + if (this.PurchaseHD) + eDownloadFlags |= Microsoft.Zune.Service.EDownloadFlags.HD; + Download.Instance.DownloadContent((IList)arrayList, eDownloadFlags, this.RentDeviceEndpointId, new EventHandler(this.OnDownloadsAllPending)); + } + else + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetError), (object)hr); + } + + private void OnDownloadsAllPending(object sender, EventArgs e) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredDownloadsAllPending), (object)null); + + private void OnPointsPurchaseCompletedOrFailed(object sender, EventArgs args) + { + this.PurchasingPoints = false; + if (this.PointsHelper.ErrorCode.IsError) + { + this.SetError(this.PointsHelper.ErrorCode); + this.UpdateState(); + } + else + { + if (this.m_pointsOffer != null) + { + int num = this.m_pointsBalance + (int)this.m_pointsOffer.Points; + this.InsufficientPoints = this.m_totalPoints >= 0 && num >= 0 && this.m_totalPoints > num; + } + this.GetBalances(); + } + } + + private void DeferredGetOffersComplete(object args) + { + object[] objArray = (object[])args; + this.UpdateOffers((AlbumOfferCollection)objArray[0], (TrackOfferCollection)objArray[1], (VideoOfferCollection)objArray[2], (AppOfferCollection)objArray[3], (int)objArray[4]); + } + + public void UpdateOffers( + AlbumOfferCollection albums, + TrackOfferCollection tracks, + VideoOfferCollection videos, + AppOfferCollection apps, + int totalSubscriptionFreeTracks) + { + this.m_albumOfferCollection = albums; + this.m_trackOfferCollection = tracks; + this.m_videoOfferCollection = videos; + this.m_appOfferCollection = apps; + this.TotalSubscriptionFreeTracks = totalSubscriptionFreeTracks; + this.AlbumOffers = this.m_albumOfferCollection != null ? this.m_albumOfferCollection.Items : (IList)null; + this.TrackOffers = this.m_trackOfferCollection != null ? this.m_trackOfferCollection.Items : (IList)null; + this.UpdateAppOffers(); + this.UpdateVideoOffers(); + this.CalculateTotal(); + this.UpdateState(); + } + + private void UpdateAppOffers() + { + IList list = (IList)null; + if (this.m_appOfferCollection != null && this.m_appOfferCollection.Items != null) + { + list = (IList)new ArrayList(this.m_appOfferCollection.Items.Count); + if (this.PurchaseTrials) + { + foreach (AppOffer appOffer in (IEnumerable)this.m_appOfferCollection.Items) + { + if (appOffer.IsTrialPurchase) + list.Add((object)appOffer); + } + } + else + { + foreach (AppOffer appOffer in (IEnumerable)this.m_appOfferCollection.Items) + { + if (!appOffer.IsTrialPurchase) + list.Add((object)appOffer); + } + } + } + this.AppOffers = list; + } + + private void UpdateVideoOffers() + { + bool flag = false; + IList list1 = this.m_videoOfferCollection != null ? this.m_videoOfferCollection.Items : (IList)null; + if (list1 != null) + { + foreach (VideoOffer videoOffer in (IEnumerable)list1) + { + if (videoOffer.PreviouslyPurchased && !videoOffer.IsRental) + flag = true; + } + } + int num1 = 0; + int num2 = 0; + if (list1 != null) + { + foreach (VideoOffer videoOffer in (IEnumerable)list1) + { + if (videoOffer.IsRental == this.RentVideos && (!this.RentVideos || !flag)) + { + if (videoOffer.IsStream) + ++num1; + else + ++num2; + } + } + } + this.MultiplePlaybackOptions = num1 > 0 && num2 > 0; + if (!this.MultiplePlaybackOptions) + this.StreamVideos = num1 > 0; + int num3 = 0; + int num4 = 0; + if (list1 != null) + { + foreach (VideoOffer videoOffer in (IEnumerable)list1) + { + if (videoOffer.IsRental == this.RentVideos && videoOffer.IsStream == this.StreamVideos && (!this.RentVideos || !flag)) + { + if (videoOffer.IsHD) + ++num3; + else + ++num4; + } + } + } + this.MultipleResolutionOptions = num3 > 0 && num4 > 0; + if (!this.MultipleResolutionOptions && list1 != null) + this.PurchaseHD = num3 > 0; + IList list2 = (IList)null; + if (list1 != null) + { + list2 = (IList)new ArrayList(this.PurchaseHD ? num3 : num4); + foreach (VideoOffer videoOffer in (IEnumerable)list1) + { + if (videoOffer.IsRental == this.RentVideos && videoOffer.IsStream == this.StreamVideos && videoOffer.IsHD == this.PurchaseHD && (!this.RentVideos || !flag)) + list2.Add((object)videoOffer); + } + } + this.VideoExpirationDate = DateTime.MaxValue; + if (list2 != null) + { + foreach (VideoOffer videoOffer in (IEnumerable)list2) + { + DateTime? expirationDate = videoOffer.ExpirationDate; + DateTime? nullable = expirationDate; + DateTime videoExpirationDate = this.VideoExpirationDate; + if ((nullable.HasValue ? (nullable.GetValueOrDefault() < videoExpirationDate ? 1 : 0) : 0) != 0) + this.VideoExpirationDate = expirationDate.Value; + } + } + this.VideoOffers = list2; + } + + public int CalculateTotalPoints(bool isRental, bool isStream, bool isHD) + { + int num = 0; + if (this.m_videoOfferCollection != null) + { + foreach (VideoOffer videoOffer in (IEnumerable)this.m_videoOfferCollection.Items) + { + if (videoOffer.IsRental == isRental && videoOffer.IsStream == isStream && (videoOffer.IsHD == isHD && !videoOffer.InCollection) && !videoOffer.PreviouslyPurchased) + num += videoOffer.PriceInfo.PointsPrice; + } + } + return num; + } + + private void CalculateTotal() + { + int num = -1; + bool flag = false; + double price = -1.0; + string str1 = (string)null; + string str2 = (string)null; + string currencyCode = (string)null; + if (this.AlbumOffers != null) + { + foreach (AlbumOffer albumOffer in (IEnumerable)this.AlbumOffers) + { + if (!albumOffer.InCollection && !albumOffer.PreviouslyPurchased) + { + if (num < 0) + num = 0; + num += albumOffer.PriceInfo.PointsPrice; + } + } + } + if (this.TrackOffers != null) + { + foreach (TrackOffer trackOffer in (IEnumerable)this.TrackOffers) + { + if (!trackOffer.InCollection && !trackOffer.PreviouslyPurchased) + { + if (num < 0) + num = 0; + num += trackOffer.PriceInfo.PointsPrice; + flag |= trackOffer.SubscriptionFree; + } + } + } + if (this.VideoOffers != null) + { + foreach (VideoOffer videoOffer in (IEnumerable)this.VideoOffers) + { + if (!videoOffer.InCollection && !videoOffer.PreviouslyPurchased) + { + if (num < 0) + num = 0; + num += videoOffer.PriceInfo.PointsPrice; + } + } + } + if (this.AppOffers != null) + { + foreach (AppOffer appOffer in (IEnumerable)this.AppOffers) + { + if (!appOffer.InCollection && !appOffer.PreviouslyPurchased) + { + if (price < 0.0) + { + str2 = appOffer.PriceInfo.DisplayPrice; + price = 0.0; + } + else + str2 = (string)null; + price += appOffer.PriceInfo.CurrencyPrice; + if (currencyCode == null || currencyCode.Equals(appOffer.PriceInfo.CurrencyCode, StringComparison.InvariantCultureIgnoreCase)) + currencyCode = appOffer.PriceInfo.CurrencyCode; + } + } + } + if (num > -1) + str1 = string.Format(ZuneUI.Shell.LoadString(StringId.IDS_POINTS_TOTAL_FORMAT), (object)num); + if (price > -1.0 && str2 == null) + str2 = StringFormatHelper.FormatPrice(price, currencyCode); + if (price > 0.0 && !string.IsNullOrEmpty(str2)) + { + string taxString = FeatureEnablement.GetTaxString(); + if (!string.IsNullOrEmpty(taxString)) + str2 = string.Format(ZuneUI.Shell.LoadString(StringId.IDS_CURRENCY_WITH_TAX), (object)str2, (object)taxString); + } + this.TotalPoints = num; + this.TotalCurrencyPrice = price; + this.DisplayPointsPrice = str1; + this.DisplayCurrencyPrice = str2; + this.HasSubscriptionFreeTracks = flag; + } + + private void DeferredSetError(object args) => this.SetError((HRESULT)args); + + private void DeferredGetBalancesComplete(object arg) + { + int[] numArray = (int[])arg; + this.m_fRequestingBalances = false; + this.PointsBalance = numArray[0]; + this.SubscriptionFreeTrackBalance = numArray[1]; + this.IsBalanceUpdated = true; + this.UpdateState(); + } + + private void DeferredGetBalancesError(object args) + { + this.m_fRequestingBalances = false; + this.IsBalanceUpdated = false; + this.SetError((HRESULT)args); + } + + private void DeferredGetPointsOffersComplete(object args) + { + this.m_fRequestingPointsOffers = false; + this.m_pointsOffers = (BillingOfferCollection)args; + this.UpdateState(); + } + + private void DeferredGetPointsOffersError(object args) + { + this.m_fRequestingPointsOffers = false; + this.SetError((HRESULT)args); + } + + private void DeferredDownloadsAllPending(object args) + { + this.PurchaseComplete = true; + if (this.SubscriptionFreeTrackBalance > 0 && (this.TrackOffers != null && this.TrackOffers.Count > 0 || this.AlbumOffers != null && this.AlbumOffers.Count > 0)) + SignIn.Instance.UpdateSubscriptionFreeTrackBalance(); + ClientConfiguration.Service.PurchaseHD = this.PurchaseHD; + if (Purchase.PurchaseEvent == null) + return; + Purchase.PurchaseEvent((object)this, EventArgs.Empty); + } + + private void DeferredPlayPurchasedStreams(object args) => SingletonModelItem.Instance.PlayItem((object)(VideoPlaybackTrack)args); + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing) + return; + if (this.m_albumOfferCollection != null) + { + this.m_albumOfferCollection.Dispose(); + this.m_albumOfferCollection = (AlbumOfferCollection)null; + } + if (this.m_trackOfferCollection != null) + { + this.m_trackOfferCollection.Dispose(); + this.m_trackOfferCollection = (TrackOfferCollection)null; + } + if (this.m_videoOfferCollection != null) + { + this.m_videoOfferCollection.Dispose(); + this.m_videoOfferCollection = (VideoOfferCollection)null; + } + if (this.m_appOfferCollection != null) + { + this.m_appOfferCollection.Dispose(); + this.m_appOfferCollection = (AppOfferCollection)null; + } + if (this.m_pointsHelper != null) + { + this.m_pointsHelper.Dispose(); + this.m_pointsHelper = (BillingOfferHelper)null; + } + if (this.m_pointsOffers == null) + return; + this.m_pointsOffers.Dispose(); + this.m_pointsOffers = (BillingOfferCollection)null; + } + + private Microsoft.Zune.Service.EPurchaseOffersFlags PurchaseOffersFlags + { + get + { + Microsoft.Zune.Service.EPurchaseOffersFlags epurchaseOffersFlags = Microsoft.Zune.Service.EPurchaseOffersFlags.None; + if (this.PurchaseHD) + epurchaseOffersFlags |= Microsoft.Zune.Service.EPurchaseOffersFlags.PurchaseHD; + if (this.RentVideos) + epurchaseOffersFlags |= Microsoft.Zune.Service.EPurchaseOffersFlags.RentVideos; + if (this.StreamVideos) + epurchaseOffersFlags |= Microsoft.Zune.Service.EPurchaseOffersFlags.StreamVideos; + if (this.PurchaseTrials) + epurchaseOffersFlags |= Microsoft.Zune.Service.EPurchaseOffersFlags.PurchaseTrials; + return epurchaseOffersFlags; + } + } + } +} diff --git a/ZuneUI/PurchaseBillingOfferFinishStep.cs b/ZuneUI/PurchaseBillingOfferFinishStep.cs new file mode 100644 index 0000000..6226e19 --- /dev/null +++ b/ZuneUI/PurchaseBillingOfferFinishStep.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PurchaseBillingOfferFinishStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + public class PurchaseBillingOfferFinishStep : AccountManagementFinishStep + { + public PurchaseBillingOfferFinishStep(Wizard owner, AccountManagementWizardState state) + : base(owner, state, Shell.LoadString(StringId.IDS_ACCOUNT_FINISHED_DESCRIPTION)) + => this.RequireSignIn = true; + + protected override bool OnCommitChanges() => this.State.PurchaseBillingOffer(this.State.SelectBillingOfferStep.SelectedBillingOffer, this.State.SelectPaymentInstrumentStep.CommittedCreditCard != null ? (PaymentInstrument)this.State.SelectPaymentInstrumentStep.CommittedCreditCard : (PaymentInstrument)this.State.PaymentInstrumentStep.CommittedCreditCard); + } +} diff --git a/ZuneUI/PurchaseBillingOfferWizard.cs b/ZuneUI/PurchaseBillingOfferWizard.cs new file mode 100644 index 0000000..0829f1c --- /dev/null +++ b/ZuneUI/PurchaseBillingOfferWizard.cs @@ -0,0 +1,49 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PurchaseBillingOfferWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + public class PurchaseBillingOfferWizard : AccountManagementWizard + { + private AccountManagementFinishStep _finishStep; + private AccountManagementErrorPage _errorStep; + + public PurchaseBillingOfferWizard(EBillingOfferType offerTypes) + { + this.State.ContactInfoStep.LightWeightOnly = true; + this.State.SelectBillingOfferStep.ShowOffers = offerTypes; + this.State.ConfirmationStep.OfferType = offerTypes; + this._finishStep = (AccountManagementFinishStep)new PurchaseBillingOfferFinishStep((Wizard)this, this.State); + this._errorStep = new AccountManagementErrorPage((Wizard)this, Shell.LoadString(StringId.IDS_ACCOUNT_PURCHASE_ERROR_TITLE), Shell.LoadString(StringId.IDS_ACCOUNT_PURCHASE_ERROR_DESC)); + this.AddPage((WizardPage)this.State.SelectBillingOfferStep); + this.AddPage((WizardPage)this.State.ContactInfoStep); + this.AddPage((WizardPage)this.State.SelectPaymentInstrumentStep); + this.AddPage((WizardPage)this.State.PaymentInstrumentStep); + this.AddPage((WizardPage)this.State.ConfirmationStep); + this.AddPage((WizardPage)this._finishStep); + this.AddPage((WizardPage)this._errorStep); + } + + protected override void OnAsyncCommitCompleted(bool success) + { + base.OnAsyncCommitCompleted(success); + if (!success) + return; + BillingOffer selectedBillingOffer = this.State.SelectBillingOfferStep.SelectedBillingOffer; + if (selectedBillingOffer != null) + { + if (selectedBillingOffer.OfferType == EBillingOfferType.Points) + this._finishStep.ClosingMessage = string.Format(Shell.LoadString(StringId.IDS_BILLING_BUY_POINTS_SUCCESS), (object)selectedBillingOffer.Points); + else + this._finishStep.ClosingMessage = string.Format(Shell.LoadString(StringId.IDS_BILLING_BUY_PASS_SUCCESS), (object)selectedBillingOffer.OfferName); + } + else + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_ACCOUNT_PURCHASE_SUCCESS_DESC); + } + } +} diff --git a/ZuneUI/PurchaseOptionCommand.cs b/ZuneUI/PurchaseOptionCommand.cs new file mode 100644 index 0000000..794c442 --- /dev/null +++ b/ZuneUI/PurchaseOptionCommand.cs @@ -0,0 +1,40 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.PurchaseOptionCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class PurchaseOptionCommand : Command + { + private string _text = string.Empty; + private int _points; + + public string Text + { + get => this._text; + set + { + if (!(this._text != value)) + return; + this._text = value; + this.FirePropertyChanged(nameof(Text)); + } + } + + public int Points + { + get => this._points; + set + { + if (this._points == value) + return; + this._points = value; + this.FirePropertyChanged(nameof(Points)); + } + } + } +} diff --git a/ZuneUI/QueryHelper.cs b/ZuneUI/QueryHelper.cs new file mode 100644 index 0000000..194c490 --- /dev/null +++ b/ZuneUI/QueryHelper.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class QueryHelper + { + public static bool HasCompletedOrFailed(DataProviderQueryStatus status) => status == DataProviderQueryStatus.Complete || status == DataProviderQueryStatus.Error; + + public static bool HasFailed(DataProviderQueryStatus status) => status == DataProviderQueryStatus.Error; + + public static bool HasCompleted(DataProviderQueryStatus status) => status == DataProviderQueryStatus.Complete; + + public static bool IsBusy(DataProviderQueryStatus status) => status == DataProviderQueryStatus.ProcessingData || status == DataProviderQueryStatus.RequestingData; + } +} diff --git a/ZuneUI/QueryStatus.cs b/ZuneUI/QueryStatus.cs new file mode 100644 index 0000000..86f8dce --- /dev/null +++ b/ZuneUI/QueryStatus.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QueryStatus +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class QueryStatus + { + private string _name; + private DataProviderQueryStatus _status; + + public QueryStatus(string name, DataProviderQueryStatus status) + { + this._name = name; + this._status = status; + } + + public string Title => this._name; + + public DataProviderQueryStatus Status => this._status; + } +} diff --git a/ZuneUI/QueryTracker.cs b/ZuneUI/QueryTracker.cs new file mode 100644 index 0000000..459bd5c --- /dev/null +++ b/ZuneUI/QueryTracker.cs @@ -0,0 +1,235 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QueryTracker +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Net; +using ZuneXml; + +namespace ZuneUI +{ + public class QueryTracker : ModelItem + { + private List _listStatus; + private DataProviderQueryStatus _status; + private string _busyString; + private List _queries; + private Dictionary _statusPriority; + private Dictionary _statusCount; + private List _errorCodes; + private PropertyChangedEventHandler _handler; + private bool _deferredStatusCheck; + + public QueryTracker() + { + this._queries = new List(); + this._handler = new PropertyChangedEventHandler(this.QueryPropertyChanged); + this._statusPriority = new Dictionary(); + this._statusPriority[DataProviderQueryStatus.Error] = 0; + this._statusPriority[DataProviderQueryStatus.RequestingData] = 1; + this._statusPriority[DataProviderQueryStatus.ProcessingData] = 2; + this._statusPriority[DataProviderQueryStatus.Complete] = 3; + this._statusPriority[DataProviderQueryStatus.Idle] = 4; + this._statusCount = new Dictionary(); + } + + public DataProviderQueryStatus Status + { + get => this._status; + private set + { + if (this._status == value) + return; + this._status = value; + this.FirePropertyChanged(nameof(Status)); + } + } + + public string BusyString + { + get => this._busyString; + private set + { + if (!(this._busyString != value)) + return; + this._busyString = value; + this.FirePropertyChanged(nameof(BusyString)); + } + } + + public List ListStatus + { + get => this._listStatus; + private set + { + if (this._listStatus == value) + return; + this._listStatus = value; + this.FirePropertyChanged(nameof(ListStatus)); + } + } + + public List ErrorCodes + { + get => this._errorCodes; + private set + { + if (this._errorCodes == value) + return; + this._errorCodes = value; + this.FirePropertyChanged(nameof(ErrorCodes)); + } + } + + public int QueryCount => this._queries.Count; + + public int ErrorCount + { + get + { + int num; + this._statusCount.TryGetValue(DataProviderQueryStatus.Error, out num); + return num; + } + } + + public int CompleteCount + { + get + { + int num; + this._statusCount.TryGetValue(DataProviderQueryStatus.Complete, out num); + return num; + } + } + + public int IdleCount + { + get + { + int num; + this._statusCount.TryGetValue(DataProviderQueryStatus.Idle, out num); + return num; + } + } + + public void Register(string name, DataProviderQuery query) => this.Register(name, query, ""); + + public void Register(string name, DataProviderQuery query, string busyString) + { + INotifyPropertyChanged notifyPropertyChanged = (INotifyPropertyChanged)query; + if (notifyPropertyChanged != null) + notifyPropertyChanged.PropertyChanged += this._handler; + this._queries.Add(new QueryTracker.QueryReference(name, query, busyString)); + this.FirePropertyChanged("QueryCount"); + this.EnqueueStatusCheck(); + } + + private void QueryPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "Status")) + return; + this.EnqueueStatusCheck(); + } + + private void EnqueueStatusCheck() + { + if (this._deferredStatusCheck) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.CheckStatus), (object)null); + this._deferredStatusCheck = true; + } + + private void CheckStatus(object args) + { + this._deferredStatusCheck = false; + DataProviderQueryStatus key = DataProviderQueryStatus.Idle; + int num1 = this._statusPriority[key]; + this._statusCount = new Dictionary(); + List queryStatusList = new List(); + List queryReferenceList = new List(); + List objectList = (List)null; + string str = (string)null; + foreach (QueryTracker.QueryReference query1 in this._queries) + { + DataProviderQuery query2 = query1.Value; + if (query2 == null) + queryReferenceList.Add(query1); + else if (query2.IsDisposed) + { + queryReferenceList.Add(query1); + } + else + { + object errorCode = QueryTracker.GetErrorCode(query2); + if (errorCode != null) + { + if (objectList == null) + objectList = new List(); + objectList.Add(errorCode); + } + DataProviderQueryStatus providerQueryStatus = query2.Status; + if (query2 == null) + providerQueryStatus = DataProviderQueryStatus.Idle; + int num2 = this._statusPriority[providerQueryStatus]; + if (num2 < num1) + { + key = providerQueryStatus; + num1 = num2; + } + queryStatusList.Add(new QueryStatus(query1.Name, providerQueryStatus)); + int num3 = 0; + this._statusCount.TryGetValue(providerQueryStatus, out num3); + this._statusCount[providerQueryStatus] = num3 + 1; + if (QueryHelper.IsBusy(query2.Status)) + str = query1.BusyString; + } + } + foreach (QueryTracker.QueryReference queryReference in queryReferenceList) + { + this._queries.Remove(queryReference); + this.FirePropertyChanged("QueryCount"); + } + this.Status = key; + this.ListStatus = queryStatusList; + this.ErrorCodes = objectList; + this.BusyString = str; + this.FirePropertyChanged("ErrorCount"); + this.FirePropertyChanged("CompleteCount"); + this.FirePropertyChanged("IdleCount"); + } + + public static object GetErrorCode(DataProviderQuery query) => query is XmlDataProviderQuery dataProviderQuery ? dataProviderQuery.ErrorCode : (object)null; + + public static bool Is404(object errorCode) => errorCode is HttpStatusCode.NotFound; + + public static bool Is410(object errorCode) => errorCode is HttpStatusCode.Gone; + + public static bool Is407(object errorCode) => errorCode is HttpStatusCode.ProxyAuthenticationRequired; + + private struct QueryReference + { + private WeakReference _value; + private string _name; + private string _busyString; + + public QueryReference(string name, DataProviderQuery value, string busyString) + { + this._name = name; + this._value = new WeakReference((object)value); + this._busyString = busyString; + } + + public string Name => this._name; + + public DataProviderQuery Value => this._value.Target as DataProviderQuery; + + public string BusyString => this._busyString; + } + } +} diff --git a/ZuneUI/QuickMixNotification.cs b/ZuneUI/QuickMixNotification.cs new file mode 100644 index 0000000..c835d67 --- /dev/null +++ b/ZuneUI/QuickMixNotification.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QuickMixNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class QuickMixNotification : Notification + { + private readonly string _title; + private readonly string _text; + private readonly bool _showWebHelpLink; + + public QuickMixNotification( + string title, + string text, + NotificationState state, + bool showWebHelpLink, + int timeout) + : base(NotificationTask.QuickMix, state, timeout) + { + this._title = title; + this._text = text; + this._showWebHelpLink = showWebHelpLink; + } + + public string Title => this._title; + + public string Text => this._text; + + public bool ShowWebHelpLink => this._showWebHelpLink; + } +} diff --git a/ZuneUI/QuickMixPlaylistFactory.cs b/ZuneUI/QuickMixPlaylistFactory.cs new file mode 100644 index 0000000..14e6b41 --- /dev/null +++ b/ZuneUI/QuickMixPlaylistFactory.cs @@ -0,0 +1,162 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QuickMixPlaylistFactory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.PerfTrace; +using Microsoft.Zune.Playlist; +using Microsoft.Zune.QuickMix; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class QuickMixPlaylistFactory : PlaylistFactory + { + private const int _minimumSimilarArtistsRequired = 10; + private QuickMixSession _quickMixSession; + private bool _shouldDisposeSession; + private HRESULT _hrCreation = HRESULT._E_PENDING; + private EQuickMixMode _mode; + private List _similarArtistStrings; + + private QuickMixPlaylistFactory( + int mediaId, + MediaType mediaType, + EQuickMixMode mode, + out HRESULT hr) + : base(true) + { + TimeSpan maxBatchTimeout = TimeSpan.FromMilliseconds(5000.0); + int[] seedMediaIds = new int[1] { mediaId }; + this._mode = mode; + Microsoft.Zune.QuickMix.QuickMix instance = Microsoft.Zune.QuickMix.QuickMix.Instance; + hr = instance.CreateSession(this._mode, seedMediaIds, (EMediaTypes)mediaType, out this._quickMixSession); + if (!hr.IsSuccess) + return; + this._shouldDisposeSession = true; + if (this._mode != EQuickMixMode.eQuickMixModeSimilarArtists) + Microsoft.Zune.PerfTrace.PerfTrace.TraceUICollectionEvent(UICollectionEvent.QuickMixBegin, ""); + hr = this._quickMixSession.GetSimilarMedia((uint)ClientConfiguration.QuickMix.DefaultPlaylistLength, maxBatchTimeout, new SimilarMediaBatchHandler(this.SimilarBatchHandler), new Microsoft.Zune.QuickMix.BatchEndHandler(this.BatchEndHandler)); + } + + private QuickMixPlaylistFactory( + Guid serviceMediaId, + MediaType mediaType, + EQuickMixMode mode, + out HRESULT hr) + : base(true) + { + TimeSpan maxBatchTimeout = TimeSpan.FromMilliseconds(10000.0); + this._mode = mode; + Microsoft.Zune.QuickMix.QuickMix instance = Microsoft.Zune.QuickMix.QuickMix.Instance; + hr = instance.CreateSession(this._mode, serviceMediaId, (EMediaTypes)mediaType, (string)null, out this._quickMixSession); + if (!hr.IsSuccess) + return; + this._shouldDisposeSession = true; + hr = this._quickMixSession.GetSimilarMedia((uint)ClientConfiguration.QuickMix.DefaultPlaylistLength, maxBatchTimeout, new SimilarMediaBatchHandler(this.SimilarBatchHandler), new Microsoft.Zune.QuickMix.BatchEndHandler(this.BatchEndHandler)); + } + + private QuickMixPlaylistFactory(QuickMixSession quickMixSession) + : base(true) + { + this._quickMixSession = quickMixSession; + this._shouldDisposeSession = false; + this._hrCreation = HRESULT._S_OK; + this.Ready = true; + } + + public override void Dispose() + { + if (!this._shouldDisposeSession || this._quickMixSession == null) + return; + this._quickMixSession.Dispose(); + this._quickMixSession = (QuickMixSession)null; + } + + public static QuickMixPlaylistFactory CreateInstance( + int mediaId, + MediaType mediaType) + { + return QuickMixPlaylistFactory.CreateInstance(mediaId, EQuickMixMode.eQuickMixModePlaylist, mediaType); + } + + public static QuickMixPlaylistFactory CreateInstance( + int mediaId, + EQuickMixMode mode, + MediaType mediaType) + { + HRESULT hr; + QuickMixPlaylistFactory mixPlaylistFactory = new QuickMixPlaylistFactory(mediaId, mediaType, mode, out hr); + return hr.IsSuccess ? mixPlaylistFactory : (QuickMixPlaylistFactory)null; + } + + public static QuickMixPlaylistFactory CreateInstance( + Guid serviceMediaId, + EQuickMixMode mode, + MediaType mediaType) + { + HRESULT hr; + QuickMixPlaylistFactory mixPlaylistFactory = new QuickMixPlaylistFactory(serviceMediaId, mediaType, mode, out hr); + return hr.IsSuccess ? mixPlaylistFactory : (QuickMixPlaylistFactory)null; + } + + public static QuickMixPlaylistFactory CreateInstance( + QuickMixSession quickMixSession) + { + return new QuickMixPlaylistFactory(quickMixSession); + } + + public override string GetUniqueTitle() + { + string playlistTitle = ""; + this._quickMixSession.GetPlaylistTitle(out playlistTitle); + return playlistTitle; + } + + public override PlaylistResult CreatePlaylist( + string title, + CreatePlaylistOption option) + { + SQMLog.Log(SQMDataId.QuickMixPlaylistCreates, 1); + int playlistId = -1; + HRESULT hr = HRESULT._E_PENDING; + if (this.Ready) + { + hr = this._hrCreation; + if (hr.IsSuccess) + hr = this._quickMixSession.SaveAsPlaylist(title, option, out playlistId); + } + return new PlaylistResult(playlistId, hr); + } + + private void BatchEndHandler(HRESULT hrAsync) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this._hrCreation = hrAsync; + this.Ready = true; + if (this._mode == EQuickMixMode.eQuickMixModeSimilarArtists) + return; + Microsoft.Zune.PerfTrace.PerfTrace.TraceUICollectionEvent(UICollectionEvent.QuickMixComplete, ""); + }, (object)null); + + private void SimilarBatchHandler(IList itemList) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this._mode != EQuickMixMode.eQuickMixModeSimilarArtists) + return; + if (this._similarArtistStrings == null) + this._similarArtistStrings = new List(); + foreach (QuickMixItem quickMixItem in (IEnumerable)itemList) + this._similarArtistStrings.Add(quickMixItem.ArtistName); + if (this._similarArtistStrings.Count <= 10) + return; + this.Ready = true; + }, (object)null); + + public IList SimilarArtists => (IList)this._similarArtistStrings; + } +} diff --git a/ZuneUI/QuickMixProgress.cs b/ZuneUI/QuickMixProgress.cs new file mode 100644 index 0000000..f01c7b0 --- /dev/null +++ b/ZuneUI/QuickMixProgress.cs @@ -0,0 +1,59 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QuickMixProgress +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.QuickMix; +using System.ComponentModel; + +namespace ZuneUI +{ + public class QuickMixProgress : INotifyPropertyChanged + { + private float _progress; + private int _secondsLeft; + + public event PropertyChangedEventHandler PropertyChanged; + + public QuickMixProgress() => Microsoft.Zune.QuickMix.QuickMix.Instance.OnProgress += new QuickMixProgressHandler(this.UpdateProgress); + + protected void FirePropertyChanged(string propertyName) + { + if (this.PropertyChanged == null) + return; + this.PropertyChanged((object)this, new PropertyChangedEventArgs(propertyName)); + } + + private void UpdateProgress(float progress, int secondsLeft) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.Progress = progress; + this.SecondsLeft = secondsLeft; + }, (object)null); + + public float Progress + { + get => this._progress; + private set + { + if ((double)value == (double)this._progress) + return; + this._progress = value; + this.FirePropertyChanged(nameof(Progress)); + } + } + + public int SecondsLeft + { + get => this._secondsLeft; + private set + { + if (value == this._secondsLeft) + return; + this._secondsLeft = value; + this.FirePropertyChanged(nameof(SecondsLeft)); + } + } + } +} diff --git a/ZuneUI/QuickMixSessionManager.cs b/ZuneUI/QuickMixSessionManager.cs new file mode 100644 index 0000000..e155477 --- /dev/null +++ b/ZuneUI/QuickMixSessionManager.cs @@ -0,0 +1,66 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QuickMixSessionManager +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.QuickMix; +using System; + +namespace ZuneUI +{ + public class QuickMixSessionManager : ModelItem + { + private QuickMixSession _quickMixSession; + private bool _isRefreshing; + private int _playlistId; + + public QuickMixSessionManager(int playlistId) + { + this._playlistId = playlistId; + Microsoft.Zune.QuickMix.QuickMix.Instance.CreateSession(EQuickMixMode.eQuickMixModePlaylist, new int[1] + { + playlistId + }, EMediaTypes.eMediaTypePlaylist, out this._quickMixSession); + } + + public int PlaylistId => this._playlistId; + + internal QuickMixSession QuickMixSession => this._quickMixSession; + + public bool IsRefreshing + { + get => this._isRefreshing; + set + { + if (this._isRefreshing == value) + return; + this._isRefreshing = value; + this.FirePropertyChanged(nameof(IsRefreshing)); + } + } + + protected override void OnDispose(bool disposing) + { + if (this._quickMixSession != null) + { + this._quickMixSession.Dispose(); + this._quickMixSession = (QuickMixSession)null; + } + base.OnDispose(disposing); + } + + public void Refresh(bool deepRefresh) + { + if (this._quickMixSession == null || this.IsRefreshing || !this._quickMixSession.Refresh(TimeSpan.FromMilliseconds(5000.0), deepRefresh, (SimilarMediaBatchHandler)null, new BatchEndHandler(this.RefreshedHandler)).IsSuccess) + return; + this.IsRefreshing = true; + } + + private void RefreshedHandler(HRESULT hrAsync) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.IsRefreshing = false; + }, (object)null); + } +} diff --git a/ZuneUI/QuickMixSubTypeCommand.cs b/ZuneUI/QuickMixSubTypeCommand.cs new file mode 100644 index 0000000..6aeb371 --- /dev/null +++ b/ZuneUI/QuickMixSubTypeCommand.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QuickMixSubTypeCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.QuickMix; +using System; + +namespace ZuneUI +{ + public class QuickMixSubTypeCommand : Command + { + public QuickMixSubTypeCommand(string description, EQuickMixType type, QuickMixSession session) + : base((IModelItemOwner)null, description, (EventHandler)null) + => this.Available = session.GetQuickMixTypeAvailable(type); + } +} diff --git a/ZuneUI/QuickplayExperience.cs b/ZuneUI/QuickplayExperience.cs new file mode 100644 index 0000000..af5a2de --- /dev/null +++ b/ZuneUI/QuickplayExperience.cs @@ -0,0 +1,48 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QuickplayExperience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System.Collections; + +namespace ZuneUI +{ + public class QuickplayExperience : Experience + { + private ArrayListDataSet _nodes; + private Node _default; + + public QuickplayExperience(Frame frameOwner) + : base(frameOwner, StringId.IDS_QUICKPLAY_PIVOT, SQMDataId.Invalid) + { + } + + public override IList NodesList + { + get + { + if (this._nodes == null) + { + this._nodes = new ArrayListDataSet((IModelItemOwner)this); + this._nodes.Add((object)this.Default); + } + return (IList)this._nodes; + } + } + + public Node Default + { + get + { + if (this._default == null) + this._default = new Node((Experience)this, this.DefaultUIPath, SQMDataId.QuickPlayClicks); + return this._default; + } + } + + public override string DefaultUIPath => "Quickplay\\Default"; + } +} diff --git a/ZuneUI/QuickplayNavigationCommandHandler.cs b/ZuneUI/QuickplayNavigationCommandHandler.cs new file mode 100644 index 0000000..2c4c8f0 --- /dev/null +++ b/ZuneUI/QuickplayNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QuickplayNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class QuickplayNavigationCommandHandler : NavigationCommandHandlerBase + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new QuickplayPage(); + } +} diff --git a/ZuneUI/QuickplayPage.cs b/ZuneUI/QuickplayPage.cs new file mode 100644 index 0000000..6e8e465 --- /dev/null +++ b/ZuneUI/QuickplayPage.cs @@ -0,0 +1,142 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.QuickplayPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Subscription; +using Microsoft.Zune.Util; +using System; +using UIXControls; + +namespace ZuneUI +{ + public class QuickplayPage : ZunePage + { + private bool _startupPage; + private bool _userInteracted; + private static bool _showFUE; + private static bool _createdOnce; + private bool _hasNavigatedAway; + + public QuickplayPage() + { + this.PivotPreference = Shell.MainFrame.Quickplay.Default; + this.IsRootPage = true; + this.UI = "res://ZuneShellResources!Quickplay.uix#Quickplay"; + this.UIPath = "Quickplay\\Default"; + this.BackgroundUI = QuickplayPage.LandBackgroundUI; + this.ShowSearch = false; + if (QuickplayPage._createdOnce) + return; + QuickplayPage._createdOnce = true; + QuickplayPage._showFUE = ClientConfiguration.Quickplay.ShowFUE; + if (!(Shell.SessionStartupPath == Shell.MainFrame.Quickplay.DefaultUIPath)) + return; + SQMLog.Log(SQMDataId.QuickPlayAsDefaultStarts, 1); + this._startupPage = true; + } + + protected override void OnNavigatedAwayWorker(IPage destination) + { + if (!this._hasNavigatedAway && this._startupPage) + { + if (!this.UserInteracted && !(destination is NowPlayingLand)) + SQMLog.Log(SQMDataId.QuickPlayAsDefaultSkips, 1); + if (ClientConfiguration.Quickplay.CheckUseCount) + { + if (this.UserInteracted) + { + ClientConfiguration.Quickplay.UnusedCount = 0; + } + else + { + ZunePage zunePage = destination as ZunePage; + string str1 = ""; + if (zunePage != null && zunePage.PivotPreference != null) + { + string str2 = ""; + if (zunePage.PivotPreference.Experience is MarketplaceExperience || zunePage.PivotPreference.Experience is SocialExperience || zunePage.PivotPreference.Experience is CollectionExperience && !(zunePage.PivotPreference.Experience is DeviceExperience)) + str2 = zunePage.UIPath; + if (!string.IsNullOrEmpty(str2)) + { + str1 = str2; + int startIndex = str2.IndexOf('\\'); + if (startIndex != -1) + str1 = str2.Remove(startIndex); + } + } + if (!string.IsNullOrEmpty(str1)) + { + if (ClientConfiguration.Quickplay.FavoredExperience == str1) + { + ++ClientConfiguration.Quickplay.UnusedCount; + } + else + { + ClientConfiguration.Quickplay.FavoredExperience = str1; + ClientConfiguration.Quickplay.UnusedCount = 1; + } + if (ClientConfiguration.Quickplay.UnusedCount >= ClientConfiguration.Quickplay.MaxUnusedCount) + { + ClientConfiguration.Quickplay.CheckUseCount = false; + this.Prompt(zunePage.PivotPreference.Experience); + } + } + else + ClientConfiguration.Quickplay.UnusedCount = 0; + } + } + } + this._hasNavigatedAway = true; + base.OnNavigatedAwayWorker(destination); + } + + public void Prompt(Experience destinationExperience) + { + Command yesCommand = new Command((IModelItemOwner)null, Shell.LoadString(StringId.IDS_DIALOG_YES), (EventHandler)null); + yesCommand.Invoked += (EventHandler)((sender, args) => ClientConfiguration.Shell.StartupPage = destinationExperience.DefaultUIPath); + string message = (string)null; + if (destinationExperience is CollectionExperience) + message = Shell.LoadString(StringId.IDS_QP_CHANGESTARTUPPAGE_COLLECTION); + else if (destinationExperience is MarketplaceExperience) + message = Shell.LoadString(StringId.IDS_QP_CHANGESTARTUPPAGE_MARKETPLACE); + else if (destinationExperience is SocialExperience) + message = Shell.LoadString(StringId.IDS_QP_CHANGESTARTUPPAGE_SOCIAL); + if (string.IsNullOrEmpty(message)) + return; + MessageBox.ShowYesNo(Shell.LoadString(StringId.IDS_QP_CHANGESTARTUPPAGE_TITLE), message, yesCommand); + } + + public static void FUEComplete() + { + if (!QuickplayPage.ShowFUE) + return; + ClientConfiguration.Quickplay.ShowFUE = false; + } + + public static DateTime InvalidDate => DateTime.MinValue; + + public static bool PlayPodcastsNewestFirst(int seriesId) + { + uint keepEpisodes = (uint)ClientConfiguration.Series.PodcastDefaultKeepEpisodes; + ESeriesPlaybackOrder playbackOrder = (ESeriesPlaybackOrder)ClientConfiguration.Series.PodcastDefaultPlaybackOrder; + SubscriptionManager.Instance.GetManagementSettings(seriesId, out keepEpisodes, out playbackOrder); + return playbackOrder == ESeriesPlaybackOrder.eSeriesPlaybackOrderNewestFirst; + } + + public static bool ShowFUE => QuickplayPage._showFUE; + + public bool UserInteracted + { + get => this._userInteracted; + set => this._userInteracted = value; + } + + private static string LandBackgroundUI => "res://ZuneShellResources!Quickplay.uix#QuickplayBackground"; + + public static int PlaylistTypeMask => 163; + } +} diff --git a/ZuneUI/RECT.cs b/ZuneUI/RECT.cs new file mode 100644 index 0000000..f070b70 --- /dev/null +++ b/ZuneUI/RECT.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RECT +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal struct RECT + { + public int Left; + public int Top; + public int Right; + public int Bottom; + } +} diff --git a/ZuneUI/RadioNavigationCommandHandler.cs b/ZuneUI/RadioNavigationCommandHandler.cs new file mode 100644 index 0000000..e9e4efb --- /dev/null +++ b/ZuneUI/RadioNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RadioNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class RadioNavigationCommandHandler : NavigationCommandHandlerBase + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new RadioPage(); + } +} diff --git a/ZuneUI/RadioOptionWithSecondaryText.cs b/ZuneUI/RadioOptionWithSecondaryText.cs new file mode 100644 index 0000000..0b76458 --- /dev/null +++ b/ZuneUI/RadioOptionWithSecondaryText.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RadioOptionWithSecondaryText +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class RadioOptionWithSecondaryText : Command + { + private string _secondaryText; + + public RadioOptionWithSecondaryText(IModelItemOwner owner, string text, string secondaryText) + : base(owner, text, (EventHandler)null) + => this._secondaryText = secondaryText; + + public string SecondaryText => this._secondaryText; + } +} diff --git a/ZuneUI/RadioPage.cs b/ZuneUI/RadioPage.cs new file mode 100644 index 0000000..f5110b9 --- /dev/null +++ b/ZuneUI/RadioPage.cs @@ -0,0 +1,38 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RadioPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class RadioPage : LibraryPage + { + private const string _UI = "res://ZuneShellResources!RadioPanel.uix#RadioLibrary"; + private const string _UIPath = "Collection\\Radio"; + private CollectionRadioPanel m_radioPanel; + + public CollectionRadioPanel RadioPanel + { + get => this.m_radioPanel; + set + { + if (value == this.m_radioPanel) + return; + this.m_radioPanel = value; + this.FirePropertyChanged(nameof(RadioPanel)); + } + } + + public RadioPage() + { + this.PivotPreference = Shell.MainFrame.Collection.Radio; + this.IsRootPage = true; + this.UI = "res://ZuneShellResources!RadioPanel.uix#RadioLibrary"; + this.UIPath = "Collection\\Radio"; + this.TransportControlStyle = TransportControlStyle.Music; + this.PlaybackContext = PlaybackContext.Music; + this.RadioPanel = new CollectionRadioPanel(this); + } + } +} diff --git a/ZuneUI/RadioStation.cs b/ZuneUI/RadioStation.cs new file mode 100644 index 0000000..4c0c01a --- /dev/null +++ b/ZuneUI/RadioStation.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RadioStation +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class RadioStation + { + private string m_title; + private string m_sourceUrl; + private string m_image; + + public RadioStation(string Title, string SourceURL, string ImagePath) + { + this.m_title = Title; + this.m_sourceUrl = SourceURL; + this.m_image = ImagePath; + } + + public string Title + { + get => this.m_title; + private set + { + if (!(value != this.m_title)) + return; + this.m_title = value; + } + } + + public string SourceURL + { + get => this.m_sourceUrl; + private set + { + if (!(value != this.m_sourceUrl)) + return; + this.m_sourceUrl = value; + } + } + + public string ImagePath + { + get => this.m_image; + private set + { + if (!(value != this.m_image)) + return; + this.m_image = value; + } + } + } +} diff --git a/ZuneUI/RadioStationHelper.cs b/ZuneUI/RadioStationHelper.cs new file mode 100644 index 0000000..50b5c28 --- /dev/null +++ b/ZuneUI/RadioStationHelper.cs @@ -0,0 +1,90 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RadioStationHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Win32; +using Microsoft.Zune.Util; +using System.Collections; + +namespace ZuneUI +{ + public class RadioStationHelper : ModelItem + { + private const string _rootKeyPath = "Software\\Microsoft\\Zune\\Radio"; + private static RadioStationHelper _instance; + private ArrayList stationList; + + public static RadioStationHelper Instance + { + get + { + if (RadioStationHelper._instance == null) + RadioStationHelper._instance = new RadioStationHelper(); + return RadioStationHelper._instance; + } + } + + private RadioStationHelper() + { + } + + public ArrayList StationList + { + get + { + if (this.stationList == null) + this.RefreshStationList(); + return this.stationList; + } + private set + { + if (value == this.stationList) + return; + this.stationList = value; + } + } + + public void AddStation(string title, string sourceUrl, string image) + { + RadioStationProgressHandler radioStationProgressHandler = new RadioStationProgressHandler(this.RadioStationAsyncCallback); + RadioStationManager.Instance.AddStation(title, sourceUrl, image, radioStationProgressHandler); + } + + public void DeleteStation(string title) + { + RadioStationProgressHandler radioStationProgressHandler = new RadioStationProgressHandler(this.RadioStationAsyncCallback); + RadioStationManager.Instance.DeleteStation(title, radioStationProgressHandler); + } + + private void RadioStationAsyncCallback(HRESULT hr) + { + if (!hr.IsSuccess) + Shell.ShowErrorDialog(hr.Int, StringId.IDS_RADIO_ERROR); + this.RefreshStationList(); + } + + private void RefreshStationList() + { + this.stationList = new ArrayList(); + RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Zune\\Radio"); + if (registryKey == null) + { + Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Zune\\Radio"); + } + else + { + foreach (string subKeyName in registryKey.GetSubKeyNames()) + { + string keyName = "HKEY_CURRENT_USER\\Software\\Microsoft\\Zune\\Radio\\" + subKeyName; + string SourceURL = (string)Registry.GetValue(keyName, "SourceURL", (object)""); + string ImagePath = (string)Registry.GetValue(keyName, "Image", (object)""); + this.stationList.Add((object)new RadioStation(subKeyName, SourceURL, ImagePath)); + } + } + this.FirePropertyChanged("StationList"); + } + } +} diff --git a/ZuneUI/RateCommand.cs b/ZuneUI/RateCommand.cs new file mode 100644 index 0000000..cc50106 --- /dev/null +++ b/ZuneUI/RateCommand.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RateCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class RateCommand : UIXControls.MenuItemCommand + { + private int m_rating; + + public RateCommand() => this.Description = Shell.LoadString(StringId.IDS_LIBRARY_RATE_MENU_ITEM); + + public int Rating + { + get => this.m_rating; + set + { + this.m_rating = value; + this.FirePropertyChanged(nameof(Rating)); + } + } + } +} diff --git a/ZuneUI/RatingConstants.cs b/ZuneUI/RatingConstants.cs new file mode 100644 index 0000000..2b20e2d --- /dev/null +++ b/ZuneUI/RatingConstants.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RatingConstants +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum RatingConstants + { + Unrated = 0, + HateIt = 2, + MaxHateIt = 5, + LoveIt = 8, + MaxLoveIt = 10, // 0x0000000A + } +} diff --git a/ZuneUI/RatingSystem.cs b/ZuneUI/RatingSystem.cs new file mode 100644 index 0000000..c1481cd --- /dev/null +++ b/ZuneUI/RatingSystem.cs @@ -0,0 +1,64 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RatingSystem +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Globalization; + +namespace ZuneUI +{ + public class RatingSystem : RatingSystemBase + { + public RatingSystem(RatingSystemBase details) + : base(details.Name, details.Title, details.Description, details.BlockText, details.UseImages, details.ShowBlockUnrated, details.DefaultLanguage, details.Strings, details.Ratings) + { + } + + private string CurrentLanguage => CultureInfo.CurrentCulture.TwoLetterISOLanguageName.ToUpper(); + + private string GetString(string id) + { + if (string.IsNullOrEmpty(id)) + return (string)null; + return this.Strings.ContainsKey(this.CurrentLanguage) ? (this.Strings[this.CurrentLanguage].ContainsKey(id) ? this.Strings[this.CurrentLanguage][id] : (string)null) : (this.Strings[this.DefaultLanguage].ContainsKey(id) ? this.Strings[this.DefaultLanguage][id] : (string)null); + } + + public string GetRatingName(int order) + { + for (int index = 0; index < this.Ratings.Length; ++index) + { + if (this.Ratings[index].Order == order) + return this.GetString(this.Ratings[index].TextId); + } + return (string)null; + } + + public string GetRatingDescription(int order) + { + for (int index = 0; index < this.Ratings.Length; ++index) + { + if (this.Ratings[index].Order == order) + return this.GetString(this.Ratings[index].DescriptionId); + } + return (string)null; + } + + public string GetRatingToolTip(int order) + { + for (int index = 0; index < this.Ratings.Length; ++index) + { + if (this.Ratings[index].Order == order) + return this.GetString(this.Ratings[index].ToolTipId); + } + return (string)null; + } + + public new string Title => this.GetString(base.Title); + + public new string Description => this.GetString(base.Description); + + public new string BlockText => this.GetString(base.BlockText); + } +} diff --git a/ZuneUI/RatingSystemList.cs b/ZuneUI/RatingSystemList.cs new file mode 100644 index 0000000..7cc34ff --- /dev/null +++ b/ZuneUI/RatingSystemList.cs @@ -0,0 +1,87 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RatingSystemList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using System.Collections; +using System.Collections.Generic; +using System.Threading; + +namespace ZuneUI +{ + public class RatingSystemList : NotifyPropertyChangedImpl + { + private static RatingSystemList s_instance; + private IDictionary _ratings; + + private RatingSystemList() + { + } + + public static RatingSystemList Instance + { + get + { + if (RatingSystemList.s_instance == null) + RatingSystemList.s_instance = new RatingSystemList(); + return RatingSystemList.s_instance; + } + } + + public IList RatingSystems + { + get + { + string[] array = (string[])null; + if (this._ratings != null) + { + array = new string[this._ratings.Keys.Count]; + this._ratings.Keys.CopyTo(array, 0); + } + return (IList)array; + } + } + + public RatingSystem GetRatingSystem(string system) => this._ratings[system]; + + public bool Loaded => this._ratings != null; + + public void LoadData() => ThreadPool.QueueUserWorkItem(new WaitCallback(this.LoadDataOnWorkerThread)); + + private void LoadDataOnWorkerThread(object state) => this.LoadDataOnWorkerThread(); + + internal bool LoadDataOnWorkerThread() + { + bool flag = true; + if (this._ratings == null) + { + RatingSystemBase[] ratingSystems = Microsoft.Zune.Service.Service.Instance.GetRatingSystems(); + if (ratingSystems != null && ratingSystems.Length > 0) + { + Dictionary dictionary = new Dictionary(ratingSystems.Length); + foreach (RatingSystemBase details in ratingSystems) + { + if (!string.IsNullOrEmpty(details.Description)) + dictionary.Add(details.Name, new RatingSystem(details)); + } + if (dictionary == null || dictionary.Count == 0) + flag = false; + else + this._ratings = (IDictionary)dictionary; + } + } + if (flag) + Application.DeferredInvoke(new DeferredInvokeHandler(this.NotifyLoaded), (object)null); + return flag; + } + + private void NotifyLoaded(object args) + { + this.FirePropertyChanged("RatingSystems"); + this.FirePropertyChanged("Loaded"); + } + } +} diff --git a/ZuneUI/RecipientHelper.cs b/ZuneUI/RecipientHelper.cs new file mode 100644 index 0000000..b846c0c --- /dev/null +++ b/ZuneUI/RecipientHelper.cs @@ -0,0 +1,78 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RecipientHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.Collections.Generic; +using System.Text; + +namespace ZuneUI +{ + public class RecipientHelper : AutoCompleteHelper + { + private List _validRecipients; + private string _errorMessage; + + public RecipientHelper() => this._validRecipients = new List(); + + public void ClearState() + { + this._validRecipients = new List(); + this.Entry = string.Empty; + this.ErrorMessage = (string)null; + } + + public static bool ValidZuneTag(string tag) => ZuneTagHelper.IsValid(tag); + + public static bool ValidEmail(string email) => EmailHelper.IsValid(email); + + public bool ValidateAll(bool allowEmailRecipients) => this.Validate(this.Entry, allowEmailRecipients); + + public string ErrorMessage + { + get => this._errorMessage; + private set + { + if (!(this._errorMessage != value)) + return; + this._errorMessage = value; + this.FirePropertyChanged(nameof(ErrorMessage)); + } + } + + public IList ValidRecipients => (IList)this._validRecipients; + + private bool Validate(string entry, bool allowEmailRecipients) + { + bool flag = true; + StringBuilder stringBuilder = new StringBuilder(); + this._validRecipients.Clear(); + if (entry != null) + { + string[] strArray = entry.Split(AutoCompleteHelper.s_entrySeparators); + for (int index = 0; index < strArray.Length; ++index) + { + string str = strArray[index].Trim(); + if (str.Length != 0) + { + if (!RecipientHelper.ValidZuneTag(str) && (!allowEmailRecipients || !RecipientHelper.ValidEmail(str))) + { + flag = false; + if (index != 0) + stringBuilder.Append(' '); + stringBuilder.Append(str); + } + else + this._validRecipients.Add(str); + } + } + } + this.ErrorMessage = flag ? (string)null : string.Format(Shell.LoadString(allowEmailRecipients ? StringId.IDS_COMPOSE_MESSAGE_ERROR_FRIENDS : StringId.IDS_COMPOSE_MESSAGE_ERROR_FRIENDS_NO_EMAIL), (object)stringBuilder.ToString()); + return flag; + } + + public static IList MakeStringList() => (IList)new List(); + } +} diff --git a/ZuneUI/RecommendationsHelper.cs b/ZuneUI/RecommendationsHelper.cs new file mode 100644 index 0000000..7829510 --- /dev/null +++ b/ZuneUI/RecommendationsHelper.cs @@ -0,0 +1,207 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RecommendationsHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Win32; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Collections; +using System.Collections.Generic; +using ZuneXml; + +namespace ZuneUI +{ + public class RecommendationsHelper + { + private static List _uploadedArtistList; + private static int _maxSongsForYouTrackCount; + + public static bool IncludeTrackCollection( + ICollection tracks, + TrackCollectionFilterType filterType) + { + bool flag1 = false; + if (tracks != null) + { + foreach (Track track in (IEnumerable)tracks) + { + if (!(track.Id == Guid.Empty)) + { + bool flag2 = ZuneApplication.Service.InVisibleCollection(track.Id, EContentType.MusicTrack); + if (filterType == TrackCollectionFilterType.IncludeIfAnyTrackNotInCollection) + { + if (!flag2) + { + flag1 = true; + break; + } + } + else + { + if (flag2) + { + flag1 = false; + break; + } + flag1 = true; + } + } + } + } + return flag1; + } + + public static bool IsArtistInCollection(Guid artistId) + { + bool flag = false; + if (artistId != Guid.Empty) + flag = ZuneApplication.Service.InVisibleCollection(artistId, EContentType.Artist); + return flag; + } + + public static object GetKeyValue(IDictionary dictionary, object key) + { + object obj = (object)null; + if (dictionary != null && dictionary.Contains(key)) + obj = dictionary[key]; + return obj; + } + + public static int GetKeyValueInt(IDictionary dictionary, object key, int defaultValue) + { + num = defaultValue; + if (dictionary == null || !dictionary.Contains(key) || !(dictionary[key] is int num)) + ; + return num; + } + + public static DateTime RecommendationsDate + { + get => RecommendationsHelper.ServiceUserGuidConfiguration.RecommendationsDate.ToUniversalTime(); + set => RecommendationsHelper.ServiceUserGuidConfiguration.RecommendationsDate = value; + } + + public static DateTime LastRecommendationsShuffleDate + { + get => RecommendationsHelper.ServiceUserGuidConfiguration.RecommendationsRefreshDate.ToUniversalTime(); + set => RecommendationsHelper.ServiceUserGuidConfiguration.RecommendationsRefreshDate = value; + } + + public static TimeSpan RefreshPeriod => new TimeSpan(24, 0, 0); + + public static int ShuffleSeed + { + get => RecommendationsHelper.ServiceUserGuidConfiguration.Seed; + set => RecommendationsHelper.ServiceUserGuidConfiguration.Seed = value; + } + + public static int MaxSongsForYouTrackCount + { + get + { + if (RecommendationsHelper._maxSongsForYouTrackCount == 0) + RecommendationsHelper._maxSongsForYouTrackCount = ClientConfiguration.Service.RecommendationsMaxTrackCount; + return RecommendationsHelper._maxSongsForYouTrackCount; + } + } + + public static ServiceUserGuidConfiguration ServiceUserGuidConfiguration => new ServiceUserGuidConfiguration(RegistryHive.CurrentUser, ClientConfiguration.Service.ConfigurationPath, string.Format("{0}", (object)ClientConfiguration.Service.LastSignedInUserGuid)); + + public static int GetUserRating(DataProviderObject item) + { + int num = 0; + if (item is Track) + { + Guid id = ((MiniMedia)item).Id; + if (id != Guid.Empty) + { + int piRating = 0; + if (ZuneApplication.Service.GetUserRating(SignIn.Instance.LastSignedInUserId, id, EContentType.MusicTrack, ref piRating)) + num = piRating; + } + } + return num; + } + + public static bool SetUserRating(DataProviderObject item, string propertyName, int rating) + { + bool flag = false; + if (item is Track) + { + Track track = (Track)item; + flag = ZuneApplication.Service.SetUserTrackRating(SignIn.Instance.LastSignedInUserId, rating, track.Id, track.AlbumId, track.TrackNumber, track.Title, track.Duration.Milliseconds, track.AlbumTitle, track.Artist, track.PrimaryGenre.Title, (string)track.GetProperty("ReferrerContext")); + if (flag) + track.UserRating = rating; + } + return flag; + } + + public static bool SetArtistUserRating(Guid id, string name, int rating) => ZuneApplication.Service.SetUserArtistRating(SignIn.Instance.LastSignedInUserId, rating, id, name); + + public static string GetRecommendationsEndpoint() => Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_Recommendations); + + private static List GetUploadedArtistUserList() + { + if (RecommendationsHelper._uploadedArtistList != null) + return RecommendationsHelper._uploadedArtistList; + string haveUploadedArtists = ClientConfiguration.Picks.UsersWhoHaveUploadedArtists; + if (!string.IsNullOrEmpty(haveUploadedArtists)) + { + string[] strArray = haveUploadedArtists.Split(','); + RecommendationsHelper._uploadedArtistList = new List(strArray.Length); + foreach (string str in strArray) + { + int result; + if (!string.IsNullOrEmpty(str) && int.TryParse(str.Trim(), out result)) + RecommendationsHelper._uploadedArtistList.Add(result); + } + } + return RecommendationsHelper._uploadedArtistList; + } + + private static void AddUserToArtistUploadList(int userId) + { + if (RecommendationsHelper._uploadedArtistList == null) + RecommendationsHelper._uploadedArtistList = new List(); + foreach (int uploadedArtist in RecommendationsHelper._uploadedArtistList) + { + if (uploadedArtist == userId) + return; + } + RecommendationsHelper._uploadedArtistList.Add(userId); + } + + private static void SaveArtistUserListToRegistry() + { + string str = string.Empty; + foreach (int uploadedArtist in RecommendationsHelper._uploadedArtistList) + str = !string.IsNullOrEmpty(str) ? string.Format("{0},{1}", (object)str, (object)uploadedArtist.ToString()) : uploadedArtist.ToString(); + ClientConfiguration.Picks.UsersWhoHaveUploadedArtists = str; + } + + public static bool HasUserUploadedArtists(int userId) + { + List uploadedArtistUserList = RecommendationsHelper.GetUploadedArtistUserList(); + if (uploadedArtistUserList != null) + { + foreach (int num in uploadedArtistUserList) + { + if (num == userId) + return true; + } + } + return false; + } + + public static void UserHasUploadArtists(int userId) + { + RecommendationsHelper.AddUserToArtistUploadList(userId); + RecommendationsHelper.SaveArtistUserListToRegistry(); + } + } +} diff --git a/ZuneUI/RecordModeOption.cs b/ZuneUI/RecordModeOption.cs new file mode 100644 index 0000000..3efef92 --- /dev/null +++ b/ZuneUI/RecordModeOption.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RecordModeOption +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + internal class RecordModeOption : NamedIntOption + { + private Choice _rateChoice; + + public RecordModeOption( + IModelItemOwner owner, + string description, + int value, + Choice rateChoice) + : base(owner, description, value) + { + this._rateChoice = rateChoice; + } + + public Choice BitRate => this._rateChoice; + } +} diff --git a/ZuneUI/RedeemCodeFinishStep.cs b/ZuneUI/RedeemCodeFinishStep.cs new file mode 100644 index 0000000..7f4d970 --- /dev/null +++ b/ZuneUI/RedeemCodeFinishStep.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RedeemCodeFinishStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class RedeemCodeFinishStep : AccountManagementFinishStep + { + public RedeemCodeFinishStep(Wizard owner, AccountManagementWizardState state) + : base(owner, state, Shell.LoadString(StringId.IDS_ACCOUNT_FINISHED_DESCRIPTION)) + { + } + + protected override bool OnCommitChanges() => this.State.RedeemCode(); + } +} diff --git a/ZuneUI/RedeemCodePropertyEditor.cs b/ZuneUI/RedeemCodePropertyEditor.cs new file mode 100644 index 0000000..cd4c09a --- /dev/null +++ b/ZuneUI/RedeemCodePropertyEditor.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RedeemCodePropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class RedeemCodePropertyEditor : WizardPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static PrepaidCodePropertyDescriptor s_code = new PrepaidCodePropertyDescriptor(nameof(Code), string.Empty, string.Empty, true); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (RedeemCodePropertyEditor.s_dataProviderProperties == null) + RedeemCodePropertyEditor.s_dataProviderProperties = new PropertyDescriptor[1] + { + (PropertyDescriptor) RedeemCodePropertyEditor.s_code + }; + return RedeemCodePropertyEditor.s_dataProviderProperties; + } + } + + public static PropertyDescriptor Code => (PropertyDescriptor)RedeemCodePropertyEditor.s_code; + } +} diff --git a/ZuneUI/RedeemCodeStep.cs b/ZuneUI/RedeemCodeStep.cs new file mode 100644 index 0000000..ef6e31c --- /dev/null +++ b/ZuneUI/RedeemCodeStep.cs @@ -0,0 +1,386 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RedeemCodeStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class RedeemCodeStep : AccountManagementStep + { + private TokenDetails _tokenDetails; + private TokenDetails _confirmedTokenDetails; + private EClientTypeFlags _tokenClientTypes; + private bool _tokenExpired; + private bool _tokenInvalid; + private Command _redeemMediaCommand; + private AlbumOfferCollection _albumOffers; + private TrackOfferCollection _trackOffers; + private VideoOfferCollection _videoOffers; + private AppOfferCollection _appOffers; + + public RedeemCodeStep(Wizard owner, AccountManagementWizardState state) + : base(owner, state, false) + { + this.Description = Shell.LoadString(StringId.IDS_BILLING_PREPAID_CODE_TITLE); + this.DetailDescription = Shell.LoadString(StringId.IDS_BILLING_PREPAID_CODE_HEADER); + WizardPropertyEditor wizardPropertyEditor = (WizardPropertyEditor)new RedeemCodePropertyEditor(); + this._redeemMediaCommand = new Command(); + this.Initialize(wizardPropertyEditor); + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#RedeemCodeStep"; + + public TokenDetails TokenDetails + { + get => this._tokenDetails; + private set + { + if (this._tokenDetails == value) + return; + this._tokenDetails = value; + this.FirePropertyChanged(nameof(TokenDetails)); + this.FirePropertyChanged("TokenSupported"); + this.FirePropertyChanged("MatchingBillingOffer"); + } + } + + public TokenDetails ConfirmedTokenDetails + { + get => this._confirmedTokenDetails; + private set + { + if (this._confirmedTokenDetails == value) + return; + this._confirmedTokenDetails = value; + this.FirePropertyChanged(nameof(ConfirmedTokenDetails)); + } + } + + public bool TokenSupported + { + get + { + if (this._tokenDetails != null) + { + switch (this._tokenDetails.TokenType) + { + case ETokenType.Media: + if (!this.TokenClientTypesSupported) + return false; + return this._tokenDetails.PurchaseOfferType == EPurchaseOfferType.TVEpisode || this._tokenDetails.PurchaseOfferType == EPurchaseOfferType.Movie; + case ETokenType.Points: + case ETokenType.Subscription: + return true; + } + } + return false; + } + } + + public EClientTypeFlags TokenClientTypes + { + get => this._tokenClientTypes; + private set + { + if (this._tokenClientTypes == value) + return; + this._tokenClientTypes = value; + this.FirePropertyChanged(nameof(TokenClientTypes)); + } + } + + private bool TokenClientTypesSupported => this._tokenClientTypes == EClientTypeFlags.None || (this._tokenClientTypes & EClientTypeFlags.PC) == EClientTypeFlags.PC; + + public bool TokenInvalid + { + get => this._tokenInvalid; + private set + { + if (this._tokenInvalid == value) + return; + this._tokenInvalid = value; + this.FirePropertyChanged(nameof(TokenInvalid)); + } + } + + public bool TokenExpired + { + get => this._tokenExpired; + private set + { + if (this._tokenExpired == value) + return; + this._tokenExpired = value; + this.FirePropertyChanged(nameof(TokenExpired)); + } + } + + public BillingOffer MatchingBillingOffer + { + get + { + BillingOffer billingOffer = (BillingOffer)null; + if (this.TokenDetails != null) + { + if (this.TokenDetails.TokenType == ETokenType.Points) + billingOffer = new BillingOffer(this.TokenDetails.BillingOfferId, EBillingOfferType.Points, this.TokenDetails.OfferName); + else if (this.TokenDetails.TokenType == ETokenType.Subscription) + billingOffer = new BillingOffer(this.TokenDetails.BillingOfferId, EBillingOfferType.Subscription, this.TokenDetails.OfferName); + } + return billingOffer; + } + } + + public AlbumOfferCollection AlbumOffers + { + get => this._albumOffers; + private set + { + if (this._albumOffers == value) + return; + this._albumOffers = value; + this.FirePropertyChanged(nameof(AlbumOffers)); + } + } + + public TrackOfferCollection TrackOffers + { + get => this._trackOffers; + private set + { + if (this._trackOffers == value) + return; + this._trackOffers = value; + this.FirePropertyChanged(nameof(TrackOffers)); + } + } + + public VideoOfferCollection VideoOffers + { + get => this._videoOffers; + private set + { + if (this._videoOffers == value) + return; + this._videoOffers = value; + this.FirePropertyChanged(nameof(VideoOffers)); + } + } + + public AppOfferCollection AppOffers + { + get => this._appOffers; + private set + { + if (this._appOffers == value) + return; + this._appOffers = value; + this.FirePropertyChanged(nameof(AppOffers)); + } + } + + public Command RedeemMediaCommand => this._redeemMediaCommand; + + public string MediaTitle => this._videoOffers != null && this._videoOffers.Items.Count > 0 ? ((Offer)this._videoOffers.Items[0]).Title : (string)null; + + public bool IsMediaRental => this._videoOffers != null && this.VideoOffers.Items.Count > 0 && ((VideoOffer)this.VideoOffers.Items[0]).IsRental; + + public bool IsMediaSD + { + get + { + if (this._videoOffers != null) + { + foreach (VideoOffer videoOffer in (IEnumerable)this._videoOffers.Items) + { + if (!videoOffer.IsHD) + return true; + } + } + return false; + } + } + + public bool IsMediaHD + { + get + { + if (this._videoOffers != null) + { + foreach (VideoOffer videoOffer in (IEnumerable)this._videoOffers.Items) + { + if (videoOffer.IsHD) + return true; + } + } + return false; + } + } + + public string CreateRedeemCodeUrl(bool returnArguments) + { + string endPointUri = Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_AccountManagement); + string urlPath = endPointUri + "/client/RedeemCode.ashx"; + string str1; + if (returnArguments) + { + string str2 = Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_ZuneNet) + "/social/articles/backtosoftware.htm"; + str1 = UrlHelper.MakeUrl(endPointUri + "/client/RedeemCode.ashx", "ru", str2, "aru", str2); + } + else + str1 = UrlHelper.MakeUrl(urlPath); + return str1; + } + + protected override void OnActivate() + { + base.OnActivate(); + this.ServiceDeactivationRequestsDone = this.TokenDetails != null; + } + + internal override bool OnMovingNext() + { + string uncommittedValue = this.GetUncommittedValue(RedeemCodePropertyEditor.Code) as string; + string committedValue = this.GetCommittedValue(RedeemCodePropertyEditor.Code) as string; + if (!uncommittedValue.Equals(committedValue, StringComparison.InvariantCultureIgnoreCase)) + { + this.TokenDetails = (TokenDetails)null; + this.TokenExpired = false; + this.TokenClientTypes = EClientTypeFlags.None; + this.ConfirmedTokenDetails = (TokenDetails)null; + this.ServiceDeactivationRequestsDone = false; + this.AlbumOffers = (AlbumOfferCollection)null; + this.TrackOffers = (TrackOfferCollection)null; + this.VideoOffers = (VideoOfferCollection)null; + this.AppOffers = (AppOfferCollection)null; + } + if (this.ServiceDeactivationRequestsDone) + { + if (this.ConfirmedTokenDetails != null) + { + if (!this.TokenSupported) + { + ZuneShell.DefaultInstance.Execute("Web\\" + this.CreateRedeemCodeUrl(true), (IDictionary)null); + this._owner.Cancel(); + return false; + } + if (this.AlbumOffers == null && this.TrackOffers == null && (this.VideoOffers == null && this.AppOffers == null)) + return base.OnMovingNext(); + this._redeemMediaCommand.Invoke(InvokePolicy.Synchronous); + return false; + } + bool flag1 = this.TokenDetails != null && (this.TokenDetails.TokenType == ETokenType.Points || this.TokenDetails.TokenType == ETokenType.Subscription); + bool flag2 = !this.TokenExpired && this.TokenClientTypes != EClientTypeFlags.None; + if (flag1 || flag2) + this.ConfirmedTokenDetails = this.TokenDetails; + return false; + } + this.StartDeactivationRequests((object)uncommittedValue); + this.WizardPropertyEditor.Commit(); + return false; + } + + protected override void OnStartDeactivationRequests(object state) + { + RedeemCodeStep.ServiceData serviceData = this.VerifyToken(state as string); + if (!serviceData.TokenInvalid && serviceData.TokenDetails.TokenType == ETokenType.Media) + Microsoft.Zune.Service.Service.Instance.GetOfferDetails(serviceData.TokenDetails.MediaOfferId, new GetOfferDetailsCompleteCallback(this.OnGetOfferDetailsSuccess), new GetOfferDetailsErrorCallback(this.OnGetOfferDetailsError), (object)serviceData); + else + this.EndDeactivationRequests((object)serviceData); + } + + protected override void OnEndDeactivationRequests(object args) + { + RedeemCodeStep.ServiceData serviceData = (RedeemCodeStep.ServiceData)args; + this.TokenClientTypes = serviceData.TokenClientTypes; + this.TokenDetails = serviceData.TokenDetails; + this.TokenInvalid = serviceData.TokenInvalid; + this.TokenExpired = serviceData.TokenExpired; + this.AlbumOffers = serviceData.AlbumOffers; + this.TrackOffers = serviceData.TrackOffers; + this.VideoOffers = serviceData.VideoOffers; + this.AppOffers = serviceData.AppOffers; + } + + private RedeemCodeStep.ServiceData VerifyToken(string token) + { + RedeemCodeStep.ServiceData serviceData = new RedeemCodeStep.ServiceData(); + if (((HRESULT)Microsoft.Zune.Service.Service.Instance.VerifyToken(token, out serviceData.TokenDetails)).IsError) + serviceData.TokenInvalid = true; + return serviceData; + } + + private void OnGetOfferDetailsSuccess( + AlbumOfferCollection albums, + TrackOfferCollection tracks, + VideoOfferCollection videos, + EClientTypeFlags clientTypes, + object state) + { + if (albums == null || tracks == null || videos == null) + { + this.OnGetOfferDetailsError(HRESULT._E_UNEXPECTED, state); + } + else + { + RedeemCodeStep.ServiceData serviceData = (RedeemCodeStep.ServiceData)state; + this.ZeroOfferPoints((IEnumerable)albums.Items); + this.ZeroOfferPoints((IEnumerable)tracks.Items); + this.ZeroOfferPoints((IEnumerable)videos.Items); + serviceData.AlbumOffers = albums; + serviceData.TrackOffers = tracks; + serviceData.VideoOffers = videos; + serviceData.TokenClientTypes = clientTypes; + serviceData.TokenExpired = this.IsTokenExpired(albums.Items, tracks.Items, videos.Items); + serviceData.AppOffers = Microsoft.Zune.Service.Service.Instance.CreateEmptyAppCollection(); + this.EndDeactivationRequests((object)serviceData); + } + } + + private bool IsTokenExpired(IList albums, IList tracks, IList videos) + { + if (albums != null && albums.Count > 0 || tracks != null && tracks.Count > 0 || (videos == null || videos.Count <= 0)) + return false; + foreach (VideoOffer video in (IEnumerable)videos) + { + if (!video.ExpirationDate.HasValue || video.ExpirationDate.Value > DateTime.UtcNow) + return false; + } + return true; + } + + private void OnGetOfferDetailsError(HRESULT hr, object state) + { + RedeemCodeStep.ServiceData serviceData = (RedeemCodeStep.ServiceData)state; + if (hr.IsError) + serviceData.TokenInvalid = true; + this.EndDeactivationRequests((object)serviceData); + } + + private void ZeroOfferPoints(IEnumerable offers) + { + if (offers == null) + return; + foreach (Offer offer in offers) + offer.PriceInfo.MakeFree(); + } + + private class ServiceData + { + public TokenDetails TokenDetails; + public EClientTypeFlags TokenClientTypes; + public bool TokenInvalid; + public bool TokenExpired; + public AlbumOfferCollection AlbumOffers; + public TrackOfferCollection TrackOffers; + public VideoOfferCollection VideoOffers; + public AppOfferCollection AppOffers; + } + } +} diff --git a/ZuneUI/RedeemCodeWizard.cs b/ZuneUI/RedeemCodeWizard.cs new file mode 100644 index 0000000..e3ad9f7 --- /dev/null +++ b/ZuneUI/RedeemCodeWizard.cs @@ -0,0 +1,46 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RedeemCodeWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + public class RedeemCodeWizard : AccountManagementWizard + { + private RedeemCodeFinishStep _finishStep; + private AccountManagementErrorPage _errorStep; + + public RedeemCodeWizard() + { + this.State.ContactInfoStep.LightWeightOnly = true; + this._finishStep = new RedeemCodeFinishStep((Wizard)this, this.State); + this._errorStep = new AccountManagementErrorPage((Wizard)this, Shell.LoadString(StringId.IDS_BILLING_PREPAID_CODE_ERROR_TITLE), Shell.LoadString(StringId.IDS_BILLING_PREPAID_CODE_ERROR_DESC)); + this.AddPage((WizardPage)this.State.RedeemCodeStep); + this.AddPage((WizardPage)this.State.ContactInfoStep); + this.AddPage((WizardPage)this._finishStep); + this.AddPage((WizardPage)this._errorStep); + } + + protected override void OnAsyncCommitCompleted(bool success) + { + base.OnAsyncCommitCompleted(success); + if (!success) + return; + switch (this.State.RedeemCodeStep.ConfirmedTokenDetails != null ? this.State.RedeemCodeStep.ConfirmedTokenDetails.TokenType : ETokenType.Unknown) + { + case ETokenType.Points: + this._finishStep.ClosingMessage = string.Format(Shell.LoadString(StringId.IDS_BILLING_PREPAID_CODE_POINTS_SUCCESS), (object)this.State.RedeemCodeStep.ConfirmedTokenDetails.OfferName); + break; + case ETokenType.Subscription: + this._finishStep.ClosingMessage = string.Format(Shell.LoadString(StringId.IDS_BILLING_PREPAID_CODE_PASS_SUCCESS), (object)this.State.RedeemCodeStep.ConfirmedTokenDetails.OfferName); + break; + default: + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_BILLING_PREPAID_CODE_DEFAULT_SUCCESS); + break; + } + } + } +} diff --git a/ZuneUI/RegionInfoStep.cs b/ZuneUI/RegionInfoStep.cs new file mode 100644 index 0000000..c1f4704 --- /dev/null +++ b/ZuneUI/RegionInfoStep.cs @@ -0,0 +1,406 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RegionInfoStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; + +namespace ZuneUI +{ + public abstract class RegionInfoStep : AccountManagementStep + { + private static IList _supportedCountries; + private IList _supportedLanguages; + private IList _supportedStates; + private bool _loadStates; + private bool _loadLanguages; + private bool _initializeOnce; + + public RegionInfoStep(Wizard owner, AccountManagementWizardState state, bool parentAccount) + : base(owner, state, parentAccount) + { + RegionInfoStep._supportedCountries = (IList)null; + this._supportedLanguages = (IList)null; + this._supportedStates = (IList)null; + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + if (this.CountryDescriptor != null) + this.WizardPropertyEditor.GetProperty(this.CountryDescriptor).PropertyChanged -= new PropertyChangedEventHandler(this.OnCountryPropertyChanged); + if (this.LanguageDescriptor != null) + this.WizardPropertyEditor.GetProperty(this.LanguageDescriptor).PropertyChanged -= new PropertyChangedEventHandler(this.OnLanguagePropertyChanged); + } + base.OnDispose(disposing); + } + + protected bool LoadStates + { + get => this._loadStates; + set + { + if (this._loadStates == value) + return; + this._loadStates = value; + this.FirePropertyChanged(nameof(LoadStates)); + } + } + + protected bool LoadLanguages + { + get => this._loadLanguages; + set + { + if (this._loadLanguages == value) + return; + this._loadLanguages = value; + this.FirePropertyChanged(nameof(LoadLanguages)); + } + } + + public string SelectedLocale + { + get + { + string str = string.Empty; + string selectedCountry = this.SelectedCountry; + string selectedLanguage = this.SelectedLanguage; + if (!string.IsNullOrEmpty(selectedCountry) && !string.IsNullOrEmpty(selectedLanguage)) + str = string.Format("{0}-{1}", (object)selectedLanguage, (object)selectedCountry); + return str; + } + set + { + if (value == null) + return; + string language; + string country; + RegionInfoStep.GetLanguageAndCountry(value, out language, out country); + this.SelectedLanguage = language; + this.SelectedCountry = country; + } + } + + public string SelectedCountry + { + get => this.CountryDescriptor != null ? this.GetUncommittedValue(this.CountryDescriptor) as string : (string)null; + set + { + if (this.CountryDescriptor == null || !(this.GetCommittedValue(this.CountryDescriptor) as string != value)) + return; + this.SetCommittedValue(this.CountryDescriptor, (object)value); + } + } + + public string SelectedLanguage + { + get => this.LanguageDescriptor != null ? this.GetUncommittedValue(this.LanguageDescriptor) as string : (string)null; + set + { + if (this.LanguageDescriptor == null) + return; + this.SetCommittedValue(this.LanguageDescriptor, (object)value); + } + } + + public string SelectedState + { + get => this.StateDescriptor != null ? this.GetUncommittedValue(this.StateDescriptor) as string : (string)null; + set + { + bool flag = this.SupportedStates == null || this.SupportedStates.Count == 0 || this.SupportedStates.Contains((object)value); + if (this.StateDescriptor == null || !flag) + return; + this.SetCommittedValue(this.StateDescriptor, (object)value); + } + } + + protected virtual PropertyDescriptor CountryDescriptor => (PropertyDescriptor)null; + + protected virtual PropertyDescriptor LanguageDescriptor => (PropertyDescriptor)null; + + protected virtual PropertyDescriptor StateDescriptor => (PropertyDescriptor)null; + + public IList SupportedCountries + { + get => RegionInfoStep._supportedCountries; + protected set + { + if (RegionInfoStep._supportedCountries == value) + return; + RegionInfoStep._supportedCountries = value; + string str = this.SelectBestCountry(RegionInfoStep._supportedCountries, this.SelectedCountry); + if (str != null) + this.SelectedCountry = str; + this.FirePropertyChanged(nameof(SupportedCountries)); + } + } + + public IList SupportedLanguages + { + get => this._supportedLanguages; + protected set + { + if (this._supportedLanguages == value) + return; + this._supportedLanguages = value; + string str = this.SelectBestLanguage(this._supportedLanguages, this.SelectedLanguage); + if (str != null) + this.SelectedLanguage = str; + this.FirePropertyChanged(nameof(SupportedLanguages)); + } + } + + public IList SupportedStates + { + get => this._supportedStates; + protected set + { + if (this._supportedStates == value) + return; + this._supportedStates = value; + string str = (string)null; + if (this._supportedStates != null && this._supportedStates.Count > 0) + str = !this._supportedStates.Contains((object)this.SelectedState) ? this._supportedStates[0] as string : this.SelectedState; + if (str != null) + this.SelectedState = str; + this.FirePropertyChanged(nameof(SupportedStates)); + } + } + + public IList GetCountryDisplayNames() + { + List stringList = (List)null; + if (RegionInfoStep._supportedCountries != null) + { + stringList = new List(RegionInfoStep._supportedCountries.Count); + foreach (string supportedCountry in (IEnumerable)RegionInfoStep._supportedCountries) + stringList.Add(CountryHelper.GetDisplayName(supportedCountry)); + } + return (IList)stringList; + } + + public IList GetLanguageDisplayNames() + { + List stringList = (List)null; + if (this._supportedLanguages != null) + { + stringList = new List(this._supportedLanguages.Count); + foreach (string supportedLanguage in (IEnumerable)this._supportedLanguages) + stringList.Add(LanguageHelper.GetDisplayName(supportedLanguage)); + } + return (IList)stringList; + } + + public IList GetStateDisplayNames() + { + IList list = (IList)null; + AccountCountry country = AccountCountryList.Instance.GetCountry(this.SelectedCountry); + if (country != null) + list = country.States; + return list; + } + + internal static void GetLanguageAndCountry( + string locale, + out string language, + out string country) + { + language = (string)null; + country = (string)null; + if (string.IsNullOrEmpty(locale)) + return; + try + { + CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(locale); + while (!cultureInfo.IsNeutralCulture && cultureInfo.LCID != 1044) + cultureInfo = cultureInfo.Parent; + language = cultureInfo.Name; + string name = locale; + string[] strArray = locale.Split('-'); + if (strArray.Length >= 2) + name = strArray[strArray.Length - 1]; + RegionInfo regionInfo = new RegionInfo(name); + country = regionInfo.TwoLetterISORegionName; + } + catch (ArgumentException ex) + { + } + } + + protected override void OnActivate() + { + this.IntializeOnce(); + RegionInfoStep.RegionServiceData regionServiceData = new RegionInfoStep.RegionServiceData(); + regionServiceData.SelectedCountry = this.SelectedCountry; + regionServiceData.SelectedLanguage = this.SelectedLanguage; + regionServiceData.SupportedStates = this._loadStates ? this.SupportedStates : (IList)new ArrayList(0); + regionServiceData.SupportedLanguages = this._loadLanguages ? this.SupportedLanguages : (IList)new ArrayList(0); + if (!string.IsNullOrEmpty(regionServiceData.SelectedCountry)) + regionServiceData.SupportedCountries = this.SupportedCountries; + this.ServiceActivationRequestsDone = this.ServiceActivationRequestsDone && regionServiceData.SupportedStates != null && regionServiceData.SupportedLanguages != null && regionServiceData.SupportedCountries != null; + if (this.ServiceActivationRequestsDone) + return; + this.StartActivationRequests((object)regionServiceData); + } + + private void IntializeOnce() + { + if (this._initializeOnce) + return; + this._initializeOnce = true; + if (SignIn.Instance.SignedIn) + this.SelectedCountry = SignIn.Instance.CountryCode; + if (this.WizardPropertyEditor != null) + { + if (this.CountryDescriptor != null) + this.WizardPropertyEditor.GetProperty(this.CountryDescriptor).PropertyChanged += new PropertyChangedEventHandler(this.OnCountryPropertyChanged); + if (this.LanguageDescriptor != null) + this.WizardPropertyEditor.GetProperty(this.LanguageDescriptor).PropertyChanged += new PropertyChangedEventHandler(this.OnLanguagePropertyChanged); + } + this.OnCountryChangedInternal(false); + this.OnLanguageChangedInternal(); + } + + private void OnCountryPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "Value")) + return; + this.OnCountryChangedInternal(true); + } + + private void OnLanguagePropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "Value")) + return; + this.OnLanguageChangedInternal(); + } + + private void OnCountryChangedInternal(bool refreshLanguagesStates) + { + this.FirePropertyChanged("SelectedLocale"); + if (refreshLanguagesStates) + this.RefreshLanguagesStates(); + if (this.WizardPropertyEditor != null && this.StateDescriptor != null) + this.WizardPropertyEditor.SetPropertyState(this.StateDescriptor, (object)this.SelectedCountry); + this.OnCountryChanged(); + } + + private void OnLanguageChangedInternal() + { + this.FirePropertyChanged("SelectedLocale"); + this.OnLanguageChanged(); + } + + protected virtual void OnCountryChanged() + { + } + + protected virtual void OnLanguageChanged() + { + } + + protected void RefreshLanguagesStates() + { + if (this.WizardPropertyEditor != null && this.StateDescriptor != null) + this.WizardPropertyEditor.SetPropertyState(this.StateDescriptor, (object)this.SelectedCountry); + if (!this.ServiceActivationRequestsDone) + return; + this.SupportedLanguages = (IList)null; + this.SupportedStates = (IList)null; + this.Activate(); + } + + protected override void OnStartActivationRequests(object state) + { + RegionInfoStep.RegionServiceData regionServiceData = (RegionInfoStep.RegionServiceData)state; + if (regionServiceData.SupportedCountries == null) + { + regionServiceData.SupportedCountries = this.ObtainSupportedCountries(); + regionServiceData.SelectedCountry = regionServiceData.SupportedCountries == null || regionServiceData.SupportedCountries.Count == 0 ? (string)null : this.SelectBestCountry(regionServiceData.SupportedCountries, regionServiceData.SelectedCountry); + } + if (regionServiceData.SupportedLanguages == null) + { + regionServiceData.SupportedLanguages = this.ObtainSupportedLanguages(regionServiceData.SelectedCountry); + regionServiceData.SelectedLanguage = this.SelectBestLanguage(regionServiceData.SupportedLanguages, regionServiceData.SelectedLanguage); + } + if (regionServiceData.SupportedStates == null) + regionServiceData.SupportedStates = this.ObtainSupportedStates(regionServiceData.SelectedCountry); + this.EndActivationRequests((object)regionServiceData); + } + + protected override void OnEndActivationRequests(object args) + { + RegionInfoStep.RegionServiceData regionServiceData = (RegionInfoStep.RegionServiceData)args; + if (regionServiceData.SupportedCountries != null) + this.SupportedCountries = regionServiceData.SupportedCountries; + if (regionServiceData.SupportedLanguages != null) + this.SupportedLanguages = regionServiceData.SupportedLanguages; + if (regionServiceData.SupportedStates != null) + this.SupportedStates = regionServiceData.SupportedStates; + if (regionServiceData.SupportedCountries != null && (regionServiceData.SupportedLanguages != null || !this.LoadLanguages)) + return; + this.SetError(HRESULT._E_FAIL, (ServiceError)null); + this.NavigateToErrorHandler(); + } + + private IList ObtainSupportedCountries() => AccountCountryList.Instance.LoadDataOnWorkerThread() ? AccountCountryList.Instance.CountryAbbreviations : (IList)null; + + private IList ObtainSupportedLanguages(string country) + { + AccountCountry country1 = AccountCountryList.Instance.GetCountry(country); + return country1 == null || country1.LanguageAbbreviations == null ? (IList)new ArrayList(0) : (IList)country1.LanguageAbbreviations; + } + + private IList ObtainSupportedStates(string country) + { + AccountCountry country1 = AccountCountryList.Instance.GetCountry(country); + return country1 == null || country1.StatesAbbreviations == null ? (IList)new List(0) : country1.StatesAbbreviations; + } + + private string SelectBestCountry(IList supportedCountries, string currentCountry) + { + string str = (string)null; + if (supportedCountries != null && supportedCountries.Count > 0) + { + str = currentCountry; + if (string.IsNullOrEmpty(str)) + str = CultureHelper.GetDefaultCountry(); + if (!supportedCountries.Contains((object)str)) + str = supportedCountries[0] as string; + } + return str; + } + + private string SelectBestLanguage(IList supportedLanguage, string currentLanguage) + { + string str = (string)null; + if (supportedLanguage != null && supportedLanguage.Count > 0) + { + str = currentLanguage; + if (string.IsNullOrEmpty(str)) + str = CultureHelper.GetDefaultLanguage(); + if (!supportedLanguage.Contains((object)str)) + str = supportedLanguage[0] as string; + } + return str; + } + + protected class RegionServiceData + { + public IList SupportedCountries; + public IList SupportedLanguages; + public IList SupportedStates; + public string SelectedCountry; + public string SelectedLanguage; + } + } +} diff --git a/ZuneUI/ReleaseYearComparer.cs b/ZuneUI/ReleaseYearComparer.cs new file mode 100644 index 0000000..3f45a96 --- /dev/null +++ b/ZuneUI/ReleaseYearComparer.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ReleaseYearComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class ReleaseYearComparer : IComparer + { + public int Compare(object x, object y) + { + DataProviderObject dataProviderObject1 = x as DataProviderObject; + DataProviderObject dataProviderObject2 = y as DataProviderObject; + return dataProviderObject1 != null && dataProviderObject2 != null ? ((DateTime)dataProviderObject1.GetProperty("ReleaseDate")).Year.CompareTo(((DateTime)dataProviderObject2.GetProperty("ReleaseDate")).Year) : 1; + } + } +} diff --git a/ZuneUI/ResumePurchaseData.cs b/ZuneUI/ResumePurchaseData.cs new file mode 100644 index 0000000..3c1b48e --- /dev/null +++ b/ZuneUI/ResumePurchaseData.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ResumePurchaseData +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class ResumePurchaseData : IEquatable + { + public ResumePurchaseData(string purchaseHandle, string redirectUrl) + { + this.PurchaseHandle = purchaseHandle; + this.UserRedirectUrl = redirectUrl; + } + + public bool Equals(ResumePurchaseData other) => string.CompareOrdinal(this.PurchaseHandle, other.PurchaseHandle) == 0 && string.CompareOrdinal(this.UserRedirectUrl, other.UserRedirectUrl) == 0; + + public string PurchaseHandle { get; private set; } + + public string UserRedirectUrl { get; private set; } + } +} diff --git a/ZuneUI/RichLayoutCommand.cs b/ZuneUI/RichLayoutCommand.cs new file mode 100644 index 0000000..2739b28 --- /dev/null +++ b/ZuneUI/RichLayoutCommand.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RichLayoutCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class RichLayoutCommand : Command + { + private bool _hasRichLayout; + + public RichLayoutCommand(IModelItemOwner owner, string description, bool hasRichLayout) + : base(owner, description, (EventHandler)null) + => this._hasRichLayout = hasRichLayout; + + public bool HasRichLayout => this._hasRichLayout; + } +} diff --git a/ZuneUI/RipState.cs b/ZuneUI/RipState.cs new file mode 100644 index 0000000..a911603 --- /dev/null +++ b/ZuneUI/RipState.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.RipState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum RipState + { + InLibrary, + NotInLibrary, + Pending, + Incomplete, + InProgress, + Error, + } +} diff --git a/ZuneUI/SchemaSyncGroup.cs b/ZuneUI/SchemaSyncGroup.cs new file mode 100644 index 0000000..d3ee8f2 --- /dev/null +++ b/ZuneUI/SchemaSyncGroup.cs @@ -0,0 +1,96 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SchemaSyncGroup +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public abstract class SchemaSyncGroup : SyncGroup + { + private SyncCategory _type; + private bool _expanded; + + public SchemaSyncGroup(SyncGroupList list, SyncCategory type) + : base(list) + => this._type = type; + + public override string Title + { + get + { + switch (this.Type) + { + case SyncCategory.Music: + return Shell.LoadString(StringId.IDS_ALL_MUSIC_SYNC_GROUP); + case SyncCategory.Video: + return Shell.LoadString(StringId.IDS_ALL_VIDEO_SYNC_GROUP); + case SyncCategory.Photo: + return Shell.LoadString(StringId.IDS_ALL_PHOTOS_SYNC_GROUP); + case SyncCategory.Podcast: + return Shell.LoadString(StringId.IDS_ALL_PODCASTS_SYNC_GROUP); + case SyncCategory.Friend: + return Shell.LoadString(StringId.IDS_ALL_FRIENDS_SYNC_GROUP); + case SyncCategory.Audiobook: + return Shell.LoadString(StringId.IDS_ALL_AUDIOBOOKS_SYNC_GROUP); + case SyncCategory.Channel: + return Shell.LoadString(StringId.IDS_ALL_CHANNELS_SYNC_GROUP); + case SyncCategory.Application: + return Shell.LoadString(StringId.IDS_ALL_APPLICATIONS_SYNC_GROUP); + case SyncCategory.Guest: + return Shell.LoadString(StringId.IDS_ALL_GUEST_SYNC_GROUP); + default: + return Shell.LoadString(StringId.IDS_GENERIC_ERROR); + } + } + } + + public override int ID => -1; + + public override SyncCategory Type => this._type; + + public string TypeName + { + get + { + switch (this.Type) + { + case SyncCategory.Music: + return Shell.LoadString(StringId.IDS_MUSIC); + case SyncCategory.Video: + return Shell.LoadString(StringId.IDS_VIDEOS); + case SyncCategory.Photo: + return Shell.LoadString(StringId.IDS_PICTURES); + case SyncCategory.Podcast: + return Shell.LoadString(StringId.IDS_PODCASTS); + case SyncCategory.Friend: + return Shell.LoadString(StringId.IDS_FRIENDS); + case SyncCategory.Channel: + return Shell.LoadString(StringId.IDS_CHANNELS); + case SyncCategory.Application: + return Shell.LoadString(StringId.IDS_APPLICATIONS); + default: + return Shell.LoadString(StringId.IDS_GENERIC_ERROR); + } + } + } + + public override bool IsComplex => false; + + public bool IsExpanded + { + get => this._expanded; + set + { + if (this._expanded == value) + return; + this._expanded = value; + this.FirePropertyChanged(nameof(IsExpanded)); + } + } + + public override void DataEdited() + { + } + } +} diff --git a/ZuneUI/ScreenGraphics.cs b/ZuneUI/ScreenGraphics.cs new file mode 100644 index 0000000..979d921 --- /dev/null +++ b/ZuneUI/ScreenGraphics.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ScreenGraphics +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum ScreenGraphics + { + Basic, + Advanced, + AdvancedWithAnimation, + Premium, + } +} diff --git a/ZuneUI/Search.cs b/ZuneUI/Search.cs new file mode 100644 index 0000000..fa28904 --- /dev/null +++ b/ZuneUI/Search.cs @@ -0,0 +1,497 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Search +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Security; +using System.Text; + +namespace ZuneUI +{ + public class Search : ModelItem + { + private string _keywords = ""; + private string[] _processedKeywords; + private static Search _singletonInstance; + private bool _ignoreAccented; + private Dictionary _accentTable; + private Command _executeCommand; + private Hashtable _keywordLinkTable; + private Command _searchFocusHotkey; + private Choice _filterList; + private SearchResultFilterType _selectedFilter; + private SearchResultContextType _usersContextType = SearchResultContextType.Undefined; + private SearchHintHelper _hintHelper; + private static List _searchResultFilterCommandTypes; + + public static Search Instance + { + get + { + if (Search._singletonInstance == null) + Search._singletonInstance = new Search(); + return Search._singletonInstance; + } + } + + internal static bool HasInstance => Search._singletonInstance != null; + + private Search() + { + this._executeCommand = new Command(); + this._ignoreAccented = string.Compare(CultureInfo.CurrentCulture.TwoLetterISOLanguageName, "en", true) == 0; + this._accentTable = new Dictionary(); + this._accentTable.Add('À', 'A'); + this._accentTable.Add('Á', 'A'); + this._accentTable.Add('Â', 'A'); + this._accentTable.Add('Ã', 'A'); + this._accentTable.Add('Ä', 'A'); + this._accentTable.Add('Å', 'A'); + this._accentTable.Add('à', 'a'); + this._accentTable.Add('á', 'a'); + this._accentTable.Add('â', 'a'); + this._accentTable.Add('ã', 'a'); + this._accentTable.Add('ä', 'a'); + this._accentTable.Add('å', 'a'); + this._accentTable.Add('È', 'E'); + this._accentTable.Add('É', 'E'); + this._accentTable.Add('Ê', 'E'); + this._accentTable.Add('Ë', 'E'); + this._accentTable.Add('è', 'e'); + this._accentTable.Add('é', 'e'); + this._accentTable.Add('ê', 'e'); + this._accentTable.Add('ë', 'e'); + this._accentTable.Add('Ì', 'I'); + this._accentTable.Add('Í', 'I'); + this._accentTable.Add('Î', 'I'); + this._accentTable.Add('Ï', 'I'); + this._accentTable.Add('ì', 'i'); + this._accentTable.Add('í', 'i'); + this._accentTable.Add('î', 'i'); + this._accentTable.Add('ï', 'i'); + this._accentTable.Add('Ò', 'O'); + this._accentTable.Add('Ó', 'O'); + this._accentTable.Add('Ô', 'O'); + this._accentTable.Add('Õ', 'O'); + this._accentTable.Add('Ö', 'O'); + this._accentTable.Add('ò', 'o'); + this._accentTable.Add('ó', 'o'); + this._accentTable.Add('ô', 'o'); + this._accentTable.Add('õ', 'o'); + this._accentTable.Add('ö', 'o'); + this._accentTable.Add('Ù', 'U'); + this._accentTable.Add('Ú', 'U'); + this._accentTable.Add('Û', 'U'); + this._accentTable.Add('Ü', 'U'); + this._accentTable.Add('ù', 'u'); + this._accentTable.Add('ú', 'u'); + this._accentTable.Add('û', 'u'); + this._accentTable.Add('ü', 'u'); + } + + protected override void OnDispose(bool disposing) + { + if (disposing && this._filterList != null) + this._filterList.ChosenChanged -= new EventHandler(this.FilterListChosenChanged); + base.OnDispose(disposing); + } + + public Choice FilterList + { + get + { + if (this._filterList == null) + { + this._filterList = new Choice((IModelItemOwner)this); + this._filterList.Options = (IList)new ArrayListDataSet(); + this._filterList.ChosenChanged += new EventHandler(this.FilterListChosenChanged); + this.UpdateFiltersList(); + } + this._filterList.ChosenIndex = 0; + return this._filterList; + } + } + + private void FilterListChosenChanged(object sender, EventArgs args) + { + if (this._filterList == null) + return; + SearchResultFilterCommand chosenValue = (SearchResultFilterCommand)this._filterList.ChosenValue; + if (chosenValue == null) + return; + this.SelectedFilterType = chosenValue.Type; + } + + public void UpdateFiltersList() + { + if (this._filterList == null) + return; + if (Search._searchResultFilterCommandTypes == null) + { + Search._searchResultFilterCommandTypes = new List(); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.All); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.Artists); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.Albums); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.Tracks); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.MusicVideos); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.TVShows); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.Movies); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.OtherVideo); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.Podcasts); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.Playlists); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.Channels); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.WindowsPhoneApps); + Search._searchResultFilterCommandTypes.Add(SearchResultFilter.Profile); + } + this._filterList.Options.Clear(); + for (int index = 0; index < Search._searchResultFilterCommandTypes.Count; ++index) + { + SearchResultFilterCommand filterCommandType = Search._searchResultFilterCommandTypes[index]; + if (filterCommandType.HasResults) + this._filterList.Options.Add((object)filterCommandType); + } + } + + public void Navigate(string command, IDictionary commandArguments) + { + if (string.IsNullOrEmpty(command)) + return; + if (command.Contains("Marketplace\\")) + SQMLog.Log(SQMDataId.SearchMarketplaceResultsCount, 1); + else if (command.Contains("Collection\\")) + SQMLog.Log(SQMDataId.SearchCollectionResultsCount, 1); + ZuneShell.DefaultInstance.Execute(command, commandArguments); + } + + public void RecordContextMenuType(SearchResultContextMenuType type) => SQMLog.LogToStream(SQMDataId.SearchContextMenuAction, (uint)type); + + public SearchResultFilterType SelectedFilterType + { + get => this._selectedFilter; + set + { + if (this._selectedFilter == value) + return; + this._selectedFilter = value; + this.FirePropertyChanged(nameof(SelectedFilterType)); + SQMLog.Log(SQMDataId.SearchFiltersCount, 1); + SQMLog.LogToStream(SQMDataId.SearchFiltersSelection, (uint)this._selectedFilter); + } + } + + public SearchResultContextType UsersContextType + { + get => this._usersContextType; + set + { + if (this._usersContextType == value) + return; + this._usersContextType = value; + this.FirePropertyChanged(nameof(UsersContextType)); + } + } + + public SearchHintHelper HintHelper + { + get + { + if (this._hintHelper == null) + this._hintHelper = new SearchHintHelper(); + return this._hintHelper; + } + } + + public Command SearchFocusHotkey + { + get + { + if (this._searchFocusHotkey == null) + this._searchFocusHotkey = new Command((IModelItemOwner)this); + return this._searchFocusHotkey; + } + } + + public string Keywords + { + get => this._keywords.Trim(); + private set + { + if (!(this._keywords != value) || string.IsNullOrEmpty(value)) + return; + this._keywords = value; + this._processedKeywords = (string[])null; + this.FirePropertyChanged(nameof(Keywords)); + } + } + + public void Execute(string keywords) + { + this.Keywords = keywords; + if (this._executeCommand == null) + return; + this._executeCommand.Invoke(); + } + + public Command Executed => this._executeCommand; + + public SearchKeywordLink KeywordLink => (SearchKeywordLink)this.KeywordLinkTable[(object)this.Keywords.ToLower()]; + + private Hashtable KeywordLinkTable + { + get + { + if (this._keywordLinkTable == null) + { + this._keywordLinkTable = new Hashtable(); + foreach (SearchKeywordLink searchKeywordLink in new SearchKeywordLink[1] + { + new SearchKeywordLink(StringId.IDS_APPLICATIONS, StringId.IDS_SEARCH_MARKETPLACE_GAMES_LINK, StringId.IDS_SEARCH_MARKETPLACE_GAMES_KEYWORDS, "Marketplace\\Apps\\Home") + }) + { + for (int index = 0; index < searchKeywordLink.Keywords.Length; ++index) + this._keywordLinkTable[(object)searchKeywordLink.Keywords[index].ToLower().Trim()] = (object)searchKeywordLink; + } + } + return this._keywordLinkTable; + } + } + + public bool IsValidKeyword(string keywords) + { + if (string.IsNullOrEmpty(keywords)) + return false; + string str = keywords.Trim(); + return !string.IsNullOrEmpty(str) && (str.Length > 1 || this.IsValidCjkCharacter(str[0])); + } + + private bool IsValidCjkCharacter(char c) + { + ushort num = (ushort)c; + return num >= (ushort)12352 && (num > (ushort)12351 && num < (ushort)12544 || num > (ushort)13311 && num < (ushort)19904 || (num > (ushort)19967 && num < (ushort)40960 || num > (ushort)44031 && num < (ushort)55216)); + } + + public string FormatResult(string keywordStyle, string item0, string item1) + { + List list = new List(); + this.AddResult(keywordStyle, list, item0); + this.AddResult(keywordStyle, list, item1); + return this.FormatResult(list); + } + + public string FormatResult(string keywordStyle, string item0, string item1, string item2) + { + List list = new List(); + this.AddResult(keywordStyle, list, item0); + this.AddResult(keywordStyle, list, item1); + this.AddResult(keywordStyle, list, item2); + return this.FormatResult(list); + } + + private void AddResult(string keywordStyle, List list, string item) + { + if (string.IsNullOrEmpty(item)) + return; + if (keywordStyle != null) + list.Add(this.HighlightKeywords(item, keywordStyle)); + else + list.Add(item); + } + + private string FormatResult(List list) + { + switch (list.Count) + { + case 1: + return list[0]; + case 2: + return string.Format(Shell.LoadString(StringId.IDS_FOUND_ITEM_BUTTON1), (object)list[0], (object)list[1]); + case 3: + return string.Format(Shell.LoadString(StringId.IDS_FOUND_ITEM_BUTTON2), (object)list[0], (object)list[1], (object)list[2]); + default: + return ""; + } + } + + public string HighlightKeywords(string target, string styleName) + { + int startIndex = 0; + if (target == null) + return ""; + StringBuilder stringBuilder = new StringBuilder(target.Length + styleName.Length * 4 + 10); + List keywords = this.FindKeywords(this.ProcessKeywords(), target); + for (int index = 0; index < keywords.Count; ++index) + { + Search.IndexRange indexRange = keywords[index]; + if (indexRange.indexStart > startIndex) + { + string str = target.Substring(startIndex, indexRange.indexStart - startIndex); + stringBuilder.Append(SecurityElement.Escape(str)); + } + string str1 = target.Substring(indexRange.indexStart, indexRange.indexEnd - indexRange.indexStart); + stringBuilder.Append(string.Format("<{0}>{1}", (object)styleName, (object)SecurityElement.Escape(str1))); + startIndex = indexRange.indexEnd; + } + if (startIndex < target.Length) + { + string str = target.Substring(startIndex); + stringBuilder.Append(SecurityElement.Escape(str)); + } + return stringBuilder.ToString(); + } + + private List FindKeywords(string[] keywords, string text) + { + StringBuilder stringBuilder = new StringBuilder(text.Length); + for (int index = 0; index < text.Length; ++index) + stringBuilder.Append(this.MapAccentedChar(text[index])); + string str = stringBuilder.ToString(); + List rangeList = new List(); + foreach (string keyword in keywords) + { + int startIndex = 0; + while (true) + { + int num = str.IndexOf(keyword, startIndex, StringComparison.OrdinalIgnoreCase); + if (num >= 0) + { + char c1 = num > 0 ? str[num - 1] : ' '; + char c2 = num + keyword.Length < str.Length ? str[num + keyword.Length] : ' '; + if (!char.IsLetterOrDigit(c1) && (keyword.Length >= 2 || !char.IsLetterOrDigit(c2))) + { + Search.IndexRange keyRange; + keyRange.indexStart = num; + keyRange.indexEnd = num + keyword.Length; + this.AddRange(keyRange, rangeList); + } + startIndex = num + keyword.Length; + } + else + break; + } + } + this.CollapseRanges(rangeList); + return rangeList; + } + + private void CollapseRanges(List rangeList) + { + for (int index1 = 0; index1 < rangeList.Count; ++index1) + { + int index2 = index1 + 1; + while (index2 < rangeList.Count) + { + Search.IndexRange range1 = rangeList[index1]; + Search.IndexRange range2 = rangeList[index2]; + if (range1.indexEnd > range2.indexStart) + { + if (range1.indexEnd >= range2.indexEnd) + { + rangeList.RemoveAt(index2); + } + else + { + range1.indexEnd = range2.indexEnd; + rangeList[index1] = range1; + rangeList.RemoveAt(index2); + } + } + else + break; + } + } + } + + private void AddRange(Search.IndexRange keyRange, List rangeList) + { + int index; + for (index = 0; index < rangeList.Count; ++index) + { + Search.IndexRange range = rangeList[index]; + if (keyRange.indexStart <= range.indexStart) + break; + } + rangeList.Insert(index, keyRange); + } + + private string[] ProcessKeywords() + { + if (this._processedKeywords == null) + { + StringBuilder stringBuilder = new StringBuilder(this._keywords.Length); + bool flag = false; + for (int index = 0; index < this._keywords.Length; ++index) + { + char keyword = this._keywords[index]; + switch (keyword) + { + case '\t': + case '\n': + case '\r': + case '!': + case '"': + case '%': + case '&': + case '(': + case ')': + case '+': + case '-': + case ';': + case '<': + case '>': + case '{': + case '}': + stringBuilder.Append(' '); + flag = true; + break; + case '\'': + char c1 = index > 0 ? this._keywords[index - 1] : ' '; + char c2 = index + 1 < this._keywords.Length ? this._keywords[index + 1] : ' '; + if (char.IsLetterOrDigit(c1) && char.IsLetterOrDigit(c2)) + { + stringBuilder.Append(keyword); + break; + } + stringBuilder.Append(' '); + flag = true; + break; + default: + stringBuilder.Append(this.MapAccentedChar(keyword)); + break; + } + } + this._processedKeywords = stringBuilder.ToString().Split(new char[1] + { + ' ' + }, StringSplitOptions.RemoveEmptyEntries); + if (flag) + { + Array.Resize(ref this._processedKeywords, this._processedKeywords.Length + 1); + this._processedKeywords[this._processedKeywords.Length - 1] = this._keywords; + } + } + return this._processedKeywords; + } + + private char MapAccentedChar(char original) + { + char key = original; + char ch; + if (this._ignoreAccented && this._accentTable.TryGetValue(key, out ch)) + key = ch; + return key; + } + + private struct IndexRange + { + public int indexStart; + public int indexEnd; + } + } +} diff --git a/ZuneUI/SearchHintHelper.cs b/ZuneUI/SearchHintHelper.cs new file mode 100644 index 0000000..068752b --- /dev/null +++ b/ZuneUI/SearchHintHelper.cs @@ -0,0 +1,117 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchHintHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class SearchHintHelper : AutoCompleteHelper + { + private int _resultsQueueCount; + private Hashtable _resultsCache = new Hashtable(); + private DataProviderTitleList _mergedTitles; + private Timer _updateTimer; + private bool _blockResults = true; + private bool _filterForKeyword; + + public SearchHintHelper() + { + this.UseEntrySeparator = false; + this.Applyfilter = false; + this._updateTimer = new Timer(); + this._updateTimer.AutoRepeat = false; + this._updateTimer.Interval = 150; + this._updateTimer.Tick += new EventHandler(this.OnUpdateTimerTick); + } + + public bool BlockResults + { + get => this._blockResults; + set + { + if (this._blockResults == value) + return; + this._blockResults = value; + } + } + + public bool FilterForKeyword + { + get => this._filterForKeyword; + set + { + if (this._filterForKeyword == value) + return; + this._filterForKeyword = value; + } + } + + public void ClearResultsByType(SearchHintResultType resultType) => this._resultsCache[(object)resultType] = (object)new List(); + + public virtual void MergeResults(IList queryResults, SearchHintResultType resultType) + { + if (queryResults == null) + return; + DataProviderTitleList providerTitleList = new DataProviderTitleList(); + for (int index = 0; index < queryResults.Count; ++index) + { + DataProviderObject queryResult = queryResults[index] as DataProviderObject; + string property = (string)queryResult.GetProperty("Title"); + if (!string.IsNullOrEmpty(property) && !providerTitleList.Contains((object)property) && (!this.FilterForKeyword || this.ContainsKeyword(property))) + providerTitleList.DataProviders.Add((object)queryResult); + } + this._resultsCache[(object)resultType] = (object)providerTitleList; + ++this._resultsQueueCount; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.HandleResultsQueue(); + }, (object)null); + } + + private bool ContainsKeyword(string title) + { + title = title.ToLower(); + string[] strArray = this.Entry.Split(' '); + bool flag = false; + for (int index = 0; index < strArray.Length; ++index) + { + string lower = strArray[index].ToLower(); + if (!string.IsNullOrEmpty(lower) && title.Contains(lower)) + { + flag = true; + break; + } + } + return flag; + } + + public object MergeSearchResultDataDelegate(object item1, object item2) => item1 == null || item2 is LibraryDataProviderListItem ? item2 : item1; + + private void HandleResultsQueue() + { + if (this._resultsQueueCount == 0) + return; + --this._resultsQueueCount; + this._mergedTitles = new DataProviderTitleList(); + foreach (DictionaryEntry dictionaryEntry in this._resultsCache) + { + DataProviderTitleList providerTitleList = dictionaryEntry.Value as DataProviderTitleList; + this._mergedTitles.InitializeDataProviders(ListHelper.Merge(this._mergedTitles.DataProviders, providerTitleList == null ? (IList)null : providerTitleList.DataProviders, false, (IComparer)new SearchResultDataComparer(), new ListHelper.MergeObjects(this.MergeSearchResultDataDelegate))); + } + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.HandleResultsQueue(); + }, (object)null); + this._updateTimer.Enabled = true; + } + + private void OnUpdateTimerTick(object sender, EventArgs args) => this.Options = (IList)this._mergedTitles; + } +} diff --git a/ZuneUI/SearchHintResultType.cs b/ZuneUI/SearchHintResultType.cs new file mode 100644 index 0000000..cecafc7 --- /dev/null +++ b/ZuneUI/SearchHintResultType.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchHintResultType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum SearchHintResultType + { + CollectionArtist, + CollectionAlbum, + CollectionTrack, + MarketplaceAll, + } +} diff --git a/ZuneUI/SearchKeywordLink.cs b/ZuneUI/SearchKeywordLink.cs new file mode 100644 index 0000000..d6d1703 --- /dev/null +++ b/ZuneUI/SearchKeywordLink.cs @@ -0,0 +1,39 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchKeywordLink +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class SearchKeywordLink : ShellCommand + { + private string _header; + private string[] _keywords; + private StringId _idsKeywords; + + public SearchKeywordLink( + StringId idsHeader, + StringId idsDescription, + StringId idsKeywords, + string command) + { + this._header = Shell.LoadString(idsHeader); + this.Description = Shell.LoadString(idsDescription); + this.Command = command; + this._idsKeywords = idsKeywords; + } + + public string Header => this._header; + + public string[] Keywords + { + get + { + if (this._keywords == null) + this._keywords = Shell.LoadString(this._idsKeywords).Split(','); + return this._keywords; + } + } + } +} diff --git a/ZuneUI/SearchResultContextMenuType.cs b/ZuneUI/SearchResultContextMenuType.cs new file mode 100644 index 0000000..bd626c9 --- /dev/null +++ b/ZuneUI/SearchResultContextMenuType.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchResultContextMenuType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum SearchResultContextMenuType + { + Play, + CollectionNavigate, + MarketplaceNavigate, + } +} diff --git a/ZuneUI/SearchResultContextType.cs b/ZuneUI/SearchResultContextType.cs new file mode 100644 index 0000000..d80b14f --- /dev/null +++ b/ZuneUI/SearchResultContextType.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchResultContextType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum SearchResultContextType + { + Music, + Video, + Podcast, + Social, + Channel, + App, + Undefined, + } +} diff --git a/ZuneUI/SearchResultDataComparer.cs b/ZuneUI/SearchResultDataComparer.cs new file mode 100644 index 0000000..b0e4a35 --- /dev/null +++ b/ZuneUI/SearchResultDataComparer.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchResultDataComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class SearchResultDataComparer : IComparer + { + private string GetStringOrDataProviderTitle(object value) => value is DataProviderObject ? (string)((DataProviderObject)value).GetProperty("Title") : value as string; + + public int Compare(object x, object y) + { + string dataProviderTitle1 = this.GetStringOrDataProviderTitle(x); + string dataProviderTitle2 = this.GetStringOrDataProviderTitle(y); + return dataProviderTitle1 != null && dataProviderTitle2 != null ? dataProviderTitle1.CompareTo(dataProviderTitle2) : 1; + } + } +} diff --git a/ZuneUI/SearchResultFilter.cs b/ZuneUI/SearchResultFilter.cs new file mode 100644 index 0000000..58e2927 --- /dev/null +++ b/ZuneUI/SearchResultFilter.cs @@ -0,0 +1,167 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchResultFilter +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class SearchResultFilter + { + private static SearchResultFilterCommand _all; + private static SearchResultFilterCommand _artists; + private static SearchResultFilterCommand _albums; + private static SearchResultFilterCommand _tracks; + private static SearchResultFilterCommand _musicVideos; + private static SearchResultFilterCommand _tvShows; + private static SearchResultFilterCommand _movies; + private static SearchResultFilterCommand _otherVideo; + private static SearchResultFilterCommand _podcasts; + private static SearchResultFilterCommand _playlists; + private static SearchResultFilterCommand _channels; + private static SearchResultFilterCommand _profile; + private static SearchResultFilterCommand _windowsPhoneApps; + + public static SearchResultFilterCommand All + { + get + { + if (SearchResultFilter._all == null) + { + SearchResultFilter._all = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_ALL), SearchResultFilterType.All); + SearchResultFilter._all.HasResults = true; + } + return SearchResultFilter._all; + } + } + + public static SearchResultFilterCommand Artists + { + get + { + if (SearchResultFilter._artists == null) + SearchResultFilter._artists = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_ARTISTS), SearchResultFilterType.Artist); + return SearchResultFilter._artists; + } + } + + public static SearchResultFilterCommand Albums + { + get + { + if (SearchResultFilter._albums == null) + SearchResultFilter._albums = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_ALBUMS), SearchResultFilterType.Album); + return SearchResultFilter._albums; + } + } + + public static SearchResultFilterCommand Tracks + { + get + { + if (SearchResultFilter._tracks == null) + SearchResultFilter._tracks = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_SONGS), SearchResultFilterType.Track); + return SearchResultFilter._tracks; + } + } + + public static SearchResultFilterCommand MusicVideos + { + get + { + if (SearchResultFilter._musicVideos == null) + SearchResultFilter._musicVideos = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_MUSIC_VIDEOS), SearchResultFilterType.MusicVideo); + return SearchResultFilter._musicVideos; + } + } + + public static SearchResultFilterCommand TVShows + { + get + { + if (SearchResultFilter._tvShows == null) + SearchResultFilter._tvShows = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_TV_SHOWS), SearchResultFilterType.TV); + return SearchResultFilter._tvShows; + } + } + + public static SearchResultFilterCommand Movies + { + get + { + if (SearchResultFilter._movies == null) + SearchResultFilter._movies = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_MOVIES), SearchResultFilterType.Movie); + return SearchResultFilter._movies; + } + } + + public static SearchResultFilterCommand OtherVideo + { + get + { + if (SearchResultFilter._otherVideo == null) + SearchResultFilter._otherVideo = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_OTHER_VIDEO), SearchResultFilterType.OtherVideo); + return SearchResultFilter._otherVideo; + } + } + + public static SearchResultFilterCommand Podcasts + { + get + { + if (SearchResultFilter._podcasts == null) + SearchResultFilter._podcasts = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_PODCASTS), SearchResultFilterType.Podcast); + return SearchResultFilter._podcasts; + } + } + + public static SearchResultFilterCommand Playlists + { + get + { + if (SearchResultFilter._playlists == null) + SearchResultFilter._playlists = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_PLAYLISTS), SearchResultFilterType.Playlist); + return SearchResultFilter._playlists; + } + } + + public static SearchResultFilterCommand Channels + { + get + { + if (SearchResultFilter._channels == null) + SearchResultFilter._channels = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_CHANNELS), SearchResultFilterType.Channel); + return SearchResultFilter._channels; + } + } + + public static SearchResultFilterCommand Profile + { + get + { + if (SearchResultFilter._profile == null) + SearchResultFilter._profile = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_SOCIAL_USERS), SearchResultFilterType.Profile); + return SearchResultFilter._profile; + } + } + + public static SearchResultFilterCommand WindowsPhoneApps + { + get + { + if (SearchResultFilter._windowsPhoneApps == null) + SearchResultFilter._windowsPhoneApps = SearchResultFilter.CreateSearchResultFilterCommand(Shell.LoadString(StringId.IDS_SEARCH_FILTER_WINDOWS_PHONE_APPS), SearchResultFilterType.WindowsPhoneApp); + return SearchResultFilter._windowsPhoneApps; + } + } + + private static SearchResultFilterCommand CreateSearchResultFilterCommand( + string description, + SearchResultFilterType type) + { + return new SearchResultFilterCommand((ModelItem)Search.Instance, description, type); + } + } +} diff --git a/ZuneUI/SearchResultFilterCommand.cs b/ZuneUI/SearchResultFilterCommand.cs new file mode 100644 index 0000000..e1f7f4d --- /dev/null +++ b/ZuneUI/SearchResultFilterCommand.cs @@ -0,0 +1,40 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchResultFilterCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class SearchResultFilterCommand : Command + { + private SearchResultFilterType _type = SearchResultFilterType.Undefined; + private bool _hasResults; + + internal SearchResultFilterCommand( + ModelItem owner, + string description, + SearchResultFilterType type) + : base((IModelItemOwner)owner, description, (EventHandler)null) + { + this._type = type; + } + + public SearchResultFilterType Type => this._type; + + public bool HasResults + { + get => this._hasResults; + set + { + if (this._hasResults == value) + return; + this._hasResults = value; + this.FirePropertyChanged(nameof(HasResults)); + } + } + } +} diff --git a/ZuneUI/SearchResultFilterType.cs b/ZuneUI/SearchResultFilterType.cs new file mode 100644 index 0000000..a1dea45 --- /dev/null +++ b/ZuneUI/SearchResultFilterType.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchResultFilterType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum SearchResultFilterType + { + Undefined = -1, // 0xFFFFFFFF + All = 0, + Artist = 1, + Album = 2, + Track = 3, + MusicVideo = 4, + TV = 5, + Movie = 6, + OtherVideo = 7, + Podcast = 8, + Playlist = 9, + Channel = 10, // 0x0000000A + Profile = 11, // 0x0000000B + WindowsPhoneApp = 12, // 0x0000000C + } +} diff --git a/ZuneUI/SearchableAggregateList.cs b/ZuneUI/SearchableAggregateList.cs new file mode 100644 index 0000000..9f82370 --- /dev/null +++ b/ZuneUI/SearchableAggregateList.cs @@ -0,0 +1,39 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchableAggregateList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class SearchableAggregateList : AggregateList, ISearchableList + { + private IList[] _lists; + private int _searchListIndex; + + public SearchableAggregateList(IList list1, IList list2, int searchListIndex) + : base(list1, list2) + { + this._lists = new IList[2] { list1, list2 }; + this._searchListIndex = searchListIndex; + } + + int ISearchableList.SearchForString(string str) + { + int num = -1; + if (this._lists[this._searchListIndex] is ISearchableList list) + { + num = list.SearchForString(str); + if (num >= 0) + { + for (int index = 0; index < this._searchListIndex; ++index) + num += this._lists[index].Count; + } + } + return num; + } + } +} diff --git a/ZuneUI/SearchableArrayList.cs b/ZuneUI/SearchableArrayList.cs new file mode 100644 index 0000000..466ccf8 --- /dev/null +++ b/ZuneUI/SearchableArrayList.cs @@ -0,0 +1,42 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchableArrayList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class SearchableArrayList : ArrayListDataSet, ISearchableList + { + public int SearchForString(string str) + { + int num = -1; + if (this.Source is ISearchableList) + num = ((ISearchableList)this.Source).SearchForString(str); + else if (this.Source is ArrayList) + { + num = ((ArrayList)this.Source).BinarySearch((object)str, ToStringCaseInsensitiveComparer.Instance); + if (num < 0) + num = ~num; + } + else if (this.Source is Array) + { + num = Array.BinarySearch((Array)this.Source, (object)str, ToStringCaseInsensitiveComparer.Instance); + if (num < 0) + num = ~num; + } + else if (this.Source is List) + { + num = ((List)this.Source).BinarySearch(str, StringCaseInsensitiveComparer.Instance); + if (num < 0) + num = ~num; + } + return num; + } + } +} diff --git a/ZuneUI/SearchableGroupedList.cs b/ZuneUI/SearchableGroupedList.cs new file mode 100644 index 0000000..b0ffb86 --- /dev/null +++ b/ZuneUI/SearchableGroupedList.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SearchableGroupedList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class SearchableGroupedList : GroupedList, ISearchableList + { + public SearchableGroupedList(IList source, IComparer comparer, int count) + : base(source, comparer, count) + { + } + + int ISearchableList.SearchForString(string str) + { + int num = -1; + if (this.Source is ISearchableList source) + num = source.SearchForString(str); + return num; + } + } +} diff --git a/ZuneUI/SelectBillingOfferStep.cs b/ZuneUI/SelectBillingOfferStep.cs new file mode 100644 index 0000000..6731a39 --- /dev/null +++ b/ZuneUI/SelectBillingOfferStep.cs @@ -0,0 +1,168 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SelectBillingOfferStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public class SelectBillingOfferStep : AccountManagementStep + { + private EBillingOfferType _offerTypes; + private BillingOffer _selectedBillingOffer; + private BillingOfferHelper _helper; + + public SelectBillingOfferStep(Wizard owner, AccountManagementWizardState state) + : base(owner, state, false) + { + this._helper = new BillingOfferHelper(); + this._helper.PropertyChanged += new PropertyChangedEventHandler(this.HelperPropertyChanged); + this._offerTypes = EBillingOfferType.Unknown; + this.SetDescription(); + this.RequireSignIn = true; + this.Initialize((WizardPropertyEditor)null); + } + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (this._helper == null || !disposing) + return; + this._helper.PropertyChanged -= new PropertyChangedEventHandler(this.HelperPropertyChanged); + this._helper.Dispose(); + this._helper = (BillingOfferHelper)null; + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#SelectBillingOfferStep"; + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled; + if (flag) + flag = this._owner.CurrentPage != this || this.Subscriptions != null && this.SubscriptionsOnly || this.PointsOffers != null && this.PointsOffersOnly; + return flag; + } + } + + public bool TrialOnly => this._offerTypes == EBillingOfferType.Trial; + + public bool SubscriptionsOnly => this._offerTypes == EBillingOfferType.Subscription || this._offerTypes == EBillingOfferType.Trial || this._offerTypes == EBillingOfferType.Renewal; + + public bool PointsOffersOnly => this._offerTypes == EBillingOfferType.Points; + + public EBillingOfferType ShowOffers + { + get => this._offerTypes; + set + { + if (this._offerTypes == value) + return; + this._offerTypes = value; + this.SetDescription(); + this.FirePropertyChanged(nameof(ShowOffers)); + this.FirePropertyChanged("TrialOnly"); + this.FirePropertyChanged("SubscriptionsOnly"); + this.FirePropertyChanged("PointsOffersOnly"); + this.FirePropertyChanged("IsEnabled"); + } + } + + public BillingOffer TrialOffer + { + get + { + BillingOffer billingOffer = (BillingOffer)null; + if (this._helper.Subscriptions != null) + { + foreach (BillingOffer subscription in (IEnumerable)this._helper.Subscriptions) + { + if (subscription.Trial) + { + billingOffer = subscription; + break; + } + } + } + return billingOffer; + } + } + + public IList Subscriptions => this._helper.Subscriptions; + + public IList PointsOffers => this._helper.PointsOffers; + + public BillingOffer SelectedBillingOffer + { + get => this._selectedBillingOffer; + set + { + if (this._selectedBillingOffer == value) + return; + this._selectedBillingOffer = value; + this.FirePropertyChanged(nameof(SelectedBillingOffer)); + } + } + + protected override void OnActivate() + { + base.OnActivate(); + if (this.Subscriptions == null && this.SubscriptionsOnly) + { + this._helper.GetSubscriptionOffers(); + } + else + { + if (this.PointsOffers != null || !this.PointsOffersOnly) + return; + this._helper.GetPointsOffers(); + } + } + + private void HelperPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (this.IsDisposed || this._helper == null) + return; + if (args.PropertyName == "Subscriptions") + { + if (this.TrialOnly) + { + this.SelectedBillingOffer = this.TrialOffer; + if (this.SelectedBillingOffer == null) + this.ShowOffers = EBillingOfferType.Subscription; + } + this.FirePropertyChanged("TrialOffer"); + this.FirePropertyChanged("Subscriptions"); + this.FirePropertyChanged("IsEnabled"); + } + else if (args.PropertyName == "PointsOffers") + { + this.FirePropertyChanged("PointsOffers"); + this.FirePropertyChanged("IsEnabled"); + } + else + { + if (!(args.PropertyName == "ErrorCode") || !this._helper.ErrorCode.IsError) + return; + this.SetError(this._helper.ErrorCode, (ServiceError)null); + } + } + + private void SetDescription() + { + if (this._offerTypes == EBillingOfferType.Trial) + this.Description = Shell.LoadString(StringId.IDS_BILLING_TRIAL_TITLE); + else if (this._offerTypes == EBillingOfferType.Subscription) + this.Description = Shell.LoadString(StringId.IDS_BILLING_ZUNE_PASS_HEADER); + else if (this._offerTypes == EBillingOfferType.Points) + this.Description = Shell.LoadString(StringId.IDS_BILLING_PURCHASE_POINTS_HEADER); + else + this.Description = (string)null; + } + } +} diff --git a/ZuneUI/SelectCreditCardFinishStep.cs b/ZuneUI/SelectCreditCardFinishStep.cs new file mode 100644 index 0000000..6a32abc --- /dev/null +++ b/ZuneUI/SelectCreditCardFinishStep.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SelectCreditCardFinishStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class SelectCreditCardFinishStep : AccountManagementFinishStep + { + public SelectCreditCardFinishStep( + Wizard owner, + AccountManagementWizardState state, + string description) + : base(owner, state, description, (string)null) + { + } + + public override string UI => "res://ZuneShellResources!AccountCreation.uix#SelectCreditCardFinishStep"; + } +} diff --git a/ZuneUI/SelectCreditCardWizard.cs b/ZuneUI/SelectCreditCardWizard.cs new file mode 100644 index 0000000..fdf59e8 --- /dev/null +++ b/ZuneUI/SelectCreditCardWizard.cs @@ -0,0 +1,63 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SelectCreditCardWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneUI +{ + public class SelectCreditCardWizard : AccountManagementWizard + { + private AccountManagementFinishStep _finishStep; + private AccountManagementErrorPage _errorStep; + private CreditCard _selectedCreditCard; + + public SelectCreditCardWizard() + { + this.State.ContactInfoStep.LightWeightOnly = true; + this._finishStep = (AccountManagementFinishStep)new SelectCreditCardFinishStep((Wizard)this, this.State, Shell.LoadString(StringId.IDS_ACCOUNT_FINISHED_DESCRIPTION)); + this._errorStep = new AccountManagementErrorPage((Wizard)this, Shell.LoadString(StringId.IDS_ACCOUNT_ADD_CC_TO_ACCOUNT_ERROR_TITLE), Shell.LoadString(StringId.IDS_ACCOUNT_ADD_CC_TO_ACCOUNT_ERROR_DESC)); + this._finishStep.FinishTextOverride = Shell.LoadString(StringId.IDS_PURCHASE_BUTTON); + PaymentInstrumentStep paymentInstrumentStep = this.State.PaymentInstrumentStep; + paymentInstrumentStep.NextTextOverride = Shell.LoadString(StringId.IDS_OK_BUTTON); + this.AddPage((WizardPage)this.State.ContactInfoStep); + this.AddPage((WizardPage)this.State.SelectPaymentInstrumentStep); + this.AddPage((WizardPage)paymentInstrumentStep); + this.AddPage((WizardPage)this._finishStep); + this.AddPage((WizardPage)this._errorStep); + } + + public CreditCard SelectedCreditCard + { + get => this._selectedCreditCard; + private set + { + if (this._selectedCreditCard == value) + return; + this._selectedCreditCard = value; + this.FirePropertyChanged(nameof(SelectedCreditCard)); + } + } + + protected override void OnAsyncCommitCompleted(bool success) + { + base.OnAsyncCommitCompleted(success); + if (!success) + return; + if (this.State.PaymentInstrumentStep.CommittedCreditCard != null) + { + this.SelectedCreditCard = this.State.PaymentInstrumentStep.CommittedCreditCard; + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_PURCHASE_PAYMENT_METHOD_ADDED); + } + else + { + if (this.State.SelectPaymentInstrumentStep.CommittedCreditCard == null) + return; + this.SelectedCreditCard = this.State.SelectPaymentInstrumentStep.CommittedCreditCard; + this._finishStep.ClosingMessage = string.Format(Shell.LoadString(StringId.IDS_PURCHASE_SELECTED_PAYMENT_METHOD), (object)this.State.SelectPaymentInstrumentStep.CommittedCreditCard.ToString()); + } + } + } +} diff --git a/ZuneUI/SelectPaymentInstrumentStep.cs b/ZuneUI/SelectPaymentInstrumentStep.cs new file mode 100644 index 0000000..10e195c --- /dev/null +++ b/ZuneUI/SelectPaymentInstrumentStep.cs @@ -0,0 +1,112 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SelectPaymentInstrumentStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public class SelectPaymentInstrumentStep : AccountManagementStep + { + private PaymentInstrumentHelper _helper; + private bool _loadedCreditCards; + private CreditCard _committedCreditCard; + + public SelectPaymentInstrumentStep( + Wizard owner, + AccountManagementWizardState state, + bool parent) + : base(owner, state, parent) + { + this.Description = Shell.LoadString(StringId.IDS_BILLING_EDIT_CC_EDIT_HEADER); + this._helper = new PaymentInstrumentHelper(); + this._helper.PropertyChanged += new PropertyChangedEventHandler(this.HelperPropertyChanged); + this.RequireSignIn = true; + } + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (this._helper == null || !disposing) + return; + this._helper.PropertyChanged -= new PropertyChangedEventHandler(this.HelperPropertyChanged); + this._helper.Dispose(); + this._helper = (PaymentInstrumentHelper)null; + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#SelectPaymentInstrumentStep"; + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled; + if (flag) + flag = this._owner.CurrentPage == this ? this._loadedCreditCards : !this._loadedCreditCards || this.CreditCards != null && this.CreditCards.Count > 0; + return flag; + } + } + + public CreditCard CommittedCreditCard + { + get => this._committedCreditCard; + set + { + if (this._committedCreditCard == value) + return; + this._committedCreditCard = value; + this.ResetNextTextOverride(); + this.FirePropertyChanged(nameof(CommittedCreditCard)); + } + } + + protected virtual void ResetNextTextOverride() + { + if (this._committedCreditCard != null && this.State.SelectBillingOfferStep.SubscriptionsOnly && !this.State.IsPurchaseConfirmationNeeded) + this.NextTextOverride = Shell.LoadString(StringId.IDS_BILLING_SIGN_UP); + else if (this._committedCreditCard != null && this.State.SelectBillingOfferStep.PointsOffersOnly) + this.NextTextOverride = Shell.LoadString(StringId.IDS_BILLING_BUY_BTN); + else + this.NextTextOverride = (string)null; + } + + public IList CreditCards => this._helper.CreditCards; + + protected override void OnActivate() + { + base.OnActivate(); + if (this._loadedCreditCards || this.CreditCards != null && this.CreditCards.Count != 0) + return; + this._helper.GetPaymentInstruments(); + } + + private void HelperPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (this.IsDisposed || this._helper == null) + return; + if (args.PropertyName == "CreditCards") + { + this._loadedCreditCards = true; + this.FirePropertyChanged("PaymentInstruments"); + this.FirePropertyChanged("IsEnabled"); + if (this._helper.CreditCards != null && this._helper.CreditCards.Count != 0) + return; + this._owner.MoveNext(); + } + else if (args.PropertyName == "Default") + { + this.CommittedCreditCard = this._helper.Default as CreditCard; + } + else + { + if (!(args.PropertyName == "ErrorCode") || !this._helper.ErrorCode.IsError) + return; + this.SetError(this._helper.ErrorCode, (ServiceError)null); + } + } + } +} diff --git a/ZuneUI/SeriesSettings.cs b/ZuneUI/SeriesSettings.cs new file mode 100644 index 0000000..b6dd12f --- /dev/null +++ b/ZuneUI/SeriesSettings.cs @@ -0,0 +1,89 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SeriesSettings +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Subscription; +using System.Collections; + +namespace ZuneUI +{ + public class SeriesSettings : ModelItem + { + private Choice m_playbackChoice; + private Choice m_keepEpisodesChoice; + private Choice m_syncChoice; + private Choice m_keepEpisodesChoicePerPhone; + private SubscriptionManager m_subscriptionManager; + private int m_seriesId; + private UIDevice m_device; + private uint keepEpisodesOriginalValue; + private ESeriesPlaybackOrder playbackOrderOriginalValue; + private PodcastSyncLimit syncRuleOriginalValue; + private int keepEpisodesPerPhoneOriginalValue; + + public SeriesSettings(SubscriptionManager subscriptionManager, int seriesId) + { + this.m_subscriptionManager = subscriptionManager; + this.m_seriesId = seriesId; + this.m_device = SyncControls.Instance.CurrentDevice; + this.keepEpisodesOriginalValue = (uint)ClientConfiguration.Series.PodcastDefaultKeepEpisodes; + this.playbackOrderOriginalValue = (ESeriesPlaybackOrder)ClientConfiguration.Series.PodcastDefaultPlaybackOrder; + this.m_subscriptionManager.GetManagementSettings(this.m_seriesId, out this.keepEpisodesOriginalValue, out this.playbackOrderOriginalValue); + this.m_keepEpisodesChoice = new Choice((IModelItemOwner)this); + this.m_keepEpisodesChoice.Options = (IList)NamedIntOption.PodcastKeepOptions; + NamedIntOption.SelectOptionByValue(this.m_keepEpisodesChoice, (int)this.keepEpisodesOriginalValue); + this.m_playbackChoice = new Choice((IModelItemOwner)this); + this.m_playbackChoice.Options = (IList)NamedIntOption.PodcastPlaybackOptions; + NamedIntOption.SelectOptionByValue(this.m_playbackChoice, (int)this.playbackOrderOriginalValue); + this.m_syncChoice = new Choice((IModelItemOwner)this); + this.m_syncChoice.Options = (IList)NamedIntOption.PodcastSyncOptions; + if (this.m_device.IsValid) + { + this.syncRuleOriginalValue = this.m_device.GetPodcastSyncLimit(this.m_seriesId); + NamedIntOption.SelectOptionByValue(this.m_syncChoice, (int)this.syncRuleOriginalValue); + } + this.m_keepEpisodesChoicePerPhone = new Choice((IModelItemOwner)this); + this.m_keepEpisodesChoicePerPhone.Options = (IList)NamedIntOption.PodcastKeepOptions; + if (!this.m_device.IsValid) + return; + this.keepEpisodesPerPhoneOriginalValue = this.m_device.GetPodcastSyncLimitWithValue(this.m_seriesId); + NamedIntOption.SelectOptionByValue(this.m_keepEpisodesChoicePerPhone, this.keepEpisodesPerPhoneOriginalValue); + } + + public Choice PlaybackChoice => this.m_playbackChoice; + + public Choice KeepEpisodesChoice => this.m_keepEpisodesChoice; + + public Choice SyncChoice => this.m_syncChoice; + + public Choice KeepEpisodesChoicePerPhone => this.m_keepEpisodesChoicePerPhone; + + public void Apply() + { + bool flag = false; + uint keepEpisodes = (uint)((NamedIntOption)this.m_keepEpisodesChoice.ChosenValue).Value; + ESeriesPlaybackOrder playbackOrder = (ESeriesPlaybackOrder)((NamedIntOption)this.m_playbackChoice.ChosenValue).Value; + if ((int)keepEpisodes != (int)this.keepEpisodesOriginalValue || playbackOrder != this.playbackOrderOriginalValue) + { + this.m_subscriptionManager.SetManagementSettings(this.m_seriesId, keepEpisodes, playbackOrder); + flag = true; + } + if (this.m_device.IsValid) + { + PodcastSyncLimit limit = (PodcastSyncLimit)((NamedIntOption)this.m_syncChoice.ChosenValue).Value; + if (limit != this.syncRuleOriginalValue) + { + this.m_device.SetPodcastSyncLimit(this.m_seriesId, limit); + flag = true; + } + } + if (!flag) + return; + SyncControls.Instance.CurrentDevice.BeginSync(true, false); + } + } +} diff --git a/ZuneUI/SettingCategories.cs b/ZuneUI/SettingCategories.cs new file mode 100644 index 0000000..149184e --- /dev/null +++ b/ZuneUI/SettingCategories.cs @@ -0,0 +1,388 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SettingCategories +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class SettingCategories + { + private static Category _accountLinks; + private static Category _burn; + private static Category _display; + private static Category _collection; + private static Category _devices; + private static Category _filetype; + private static Category _firmwareUpdate; + private static Category _general; + private static Category _nameDevice; + private static Category _deviceMarketplace; + private static Category _devicePrivacy; + private static Category _photo; + private static Category _podcast; + private static Category _privacy; + private static Category _purchaseHistory; + private static Category _metadata; + private static Category _rentalHistory; + private static Category _rip; + private static Category _sharing; + private static Category _pictureVideo; + private static Category _moreOneWeb; + private static Category _spaceReservation; + private static Category _subscriptionHistory; + private static Category _syncGroups; + private static Category _syncOptions; + private static Category _transcoding; + private static Category _wirelessSetup; + private static Category _wirelessSetupMobile; + private static Category _wirelessSetupDevice; + private static Category _wirelessSetupComplete; + private static Category _wirelessSetupManual; + private static Category _wirelessSetupNotConfigured; + private static Category _wirelessSetupCurrentConfig; + private static Category _wirelessSetupDeviceBusy; + + public static Category AccountLinks + { + get + { + if (SettingCategories._accountLinks == null) + SettingCategories._accountLinks = new Category(StringId.IDS_ACCOUNT_MENU_ITEM, "res://ZuneShellResources!ManagementAccount.uix"); + return SettingCategories._accountLinks; + } + } + + public static Category Burn + { + get + { + if (SettingCategories._burn == null) + SettingCategories._burn = new Category(StringId.IDS_BURN_MENU_ITEM, "res://ZuneShellResources!ManagementBurn.uix"); + return SettingCategories._burn; + } + } + + public static Category Display + { + get + { + if (SettingCategories._display == null) + SettingCategories._display = new Category(StringId.IDS_DISPLAY_MENU_ITEM, "res://ZuneShellResources!ManagementDisplay.uix"); + return SettingCategories._display; + } + } + + public static Category Collection + { + get + { + if (SettingCategories._collection == null) + SettingCategories._collection = new Category(StringId.IDS_COLLECTION_MENU_ITEM, "res://ZuneShellResources!ManagementCollection.uix"); + return SettingCategories._collection; + } + } + + public static Category Devices + { + get + { + if (SettingCategories._devices == null) + SettingCategories._devices = new Category(StringId.IDS_MARKETPLACE_MENU_ITEM, "res://ZuneShellResources!ManagementDevices.uix"); + return SettingCategories._devices; + } + } + + public static Category Filetype + { + get + { + if (SettingCategories._filetype == null) + SettingCategories._filetype = new Category(StringId.IDS_FILE_TYPE_MENU_ITEM, "res://ZuneShellResources!ManagementFileTypes.uix"); + return SettingCategories._filetype; + } + } + + public static Category FirmwareUpdate + { + get + { + if (SettingCategories._firmwareUpdate == null) + SettingCategories._firmwareUpdate = new Category(StringId.IDS_FIRMWARE_UPDATE_HEADER, "res://ZuneShellResources!DeviceFirmware.uix#Default"); + return SettingCategories._firmwareUpdate; + } + } + + public static Category General + { + get + { + if (SettingCategories._general == null) + SettingCategories._general = new Category(StringId.IDS_GENERAL_MENU_ITEM, "res://ZuneShellResources!ManagementGeneral.uix"); + return SettingCategories._general; + } + } + + public static Category NameDevice + { + get + { + if (SettingCategories._nameDevice == null) + SettingCategories._nameDevice = new Category(StringId.IDS_NAME_ZUNE_HEADER, "res://ZuneShellResources!DeviceName.uix#Default"); + return SettingCategories._nameDevice; + } + } + + public static Category DeviceMarketplace + { + get + { + if (SettingCategories._deviceMarketplace == null) + SettingCategories._deviceMarketplace = new Category(StringId.IDS_ENABLE_MARKETPLACE_ON_DEVICE_HEADER, "res://ZuneShellResources!DeviceMarketplace.uix#Default"); + return SettingCategories._deviceMarketplace; + } + } + + public static Category Photo + { + get + { + if (SettingCategories._photo == null) + SettingCategories._photo = new Category(StringId.IDS_PHOTO_MENU_ITEM, "res://ZuneShellResources!ManagementPhoto.uix"); + return SettingCategories._photo; + } + } + + public static Category Podcast + { + get + { + if (SettingCategories._podcast == null) + SettingCategories._podcast = new Category(StringId.IDS_PODCAST_MENU_ITEM, "res://ZuneShellResources!ManagementPodcast.uix"); + return SettingCategories._podcast; + } + } + + public static Category PurchaseHistory + { + get + { + if (SettingCategories._purchaseHistory == null) + SettingCategories._purchaseHistory = new Category(StringId.IDS_BILLING_PURCHASE_HISTORY_HEADER, "res://ZuneShellResources!ManagementPurchases.uix", false); + return SettingCategories._purchaseHistory; + } + } + + public static Category Privacy + { + get + { + if (SettingCategories._privacy == null) + SettingCategories._privacy = new Category(StringId.IDS_PRIVACY_MENU_ITEM, "res://ZuneShellResources!ManagementPrivacy.uix"); + return SettingCategories._privacy; + } + } + + public static Category RentalHistory + { + get + { + if (SettingCategories._rentalHistory == null) + SettingCategories._rentalHistory = new Category(StringId.IDS_BILLING_RENTAL_HISTORY_HEADER, "res://ZuneShellResources!ManagementRentals.uix", false); + return SettingCategories._rentalHistory; + } + } + + public static Category Rip + { + get + { + if (SettingCategories._rip == null) + SettingCategories._rip = new Category(StringId.IDS_RIP_MENU_ITEM, "res://ZuneShellResources!ManagementRip.uix"); + return SettingCategories._rip; + } + } + + public static Category Metadata + { + get + { + if (SettingCategories._metadata == null) + SettingCategories._metadata = new Category(FeatureEnablement.IsFeatureEnabled(Features.eSocial) ? StringId.IDS_METADATA_AND_RATINGS_MENU_ITEM : StringId.IDS_METADATA_MENU_ITEM, "res://ZuneShellResources!ManagementMetadata.uix"); + return SettingCategories._metadata; + } + } + + public static Category Sharing + { + get + { + if (SettingCategories._sharing == null) + SettingCategories._sharing = new Category(StringId.IDS_SHARING_MENU_ITEM, "res://ZuneShellResources!ManagementSharing.uix"); + return SettingCategories._sharing; + } + } + + public static Category PictureVideo + { + get + { + if (SettingCategories._pictureVideo == null) + SettingCategories._pictureVideo = new Category(StringId.IDS_DEVICE_SETTINGS_PICTURES, "res://ZuneShellResources!DevicePictureVideo.uix#Default"); + return SettingCategories._pictureVideo; + } + } + + public static Category MoreOnWeb + { + get + { + if (SettingCategories._moreOneWeb == null) + SettingCategories._moreOneWeb = new Category(StringId.IDS_DEVICE_SETTINGS_MORE_ON_WEB, "res://ZuneShellResources!DeviceMoreOnWeb.uix#Default"); + return SettingCategories._moreOneWeb; + } + } + + public static Category SpaceReservation + { + get + { + if (SettingCategories._spaceReservation == null) + SettingCategories._spaceReservation = new Category(StringId.IDS_DEVICE_SETTINGS_RESERVATION, "res://ZuneShellResources!DeviceSpaceReservation.uix#Default"); + return SettingCategories._spaceReservation; + } + } + + public static Category SubscriptionHistory + { + get + { + if (SettingCategories._subscriptionHistory == null) + SettingCategories._subscriptionHistory = new Category(StringId.IDS_BILLING_DOWNLOAD_HISTORY_HEADER, "res://ZuneShellResources!ManagementSubscription.uix", false); + return SettingCategories._subscriptionHistory; + } + } + + public static Category SyncGroups + { + get + { + if (SettingCategories._syncGroups == null) + SettingCategories._syncGroups = new Category(StringId.IDS_SYNC_GROUPS_SETTINGS_HEADER, "res://ZuneShellResources!DeviceSyncGroups.uix#SyncGroups", false); + return SettingCategories._syncGroups; + } + } + + public static Category SyncOptions + { + get + { + if (SettingCategories._syncOptions == null) + SettingCategories._syncOptions = new Category(StringId.IDS_SYNC_OPTIONS_HEADER, "res://ZuneShellResources!DeviceSyncOptions.uix#Default", false); + return SettingCategories._syncOptions; + } + } + + public static Category Transcoding + { + get + { + if (SettingCategories._transcoding == null) + SettingCategories._transcoding = new Category(StringId.IDS_TRANSCODING_HEADER, "res://ZuneShellResources!DeviceTranscode.uix#Default"); + return SettingCategories._transcoding; + } + } + + public static Category WirelessSetup + { + get + { + if (SettingCategories._wirelessSetup == null) + SettingCategories._wirelessSetup = new Category(StringId.IDS_WIRELESS_SYNC_HEADER, "res://ZuneShellResources!DeviceWirelessSync.uix#Default"); + return SettingCategories._wirelessSetup; + } + } + + public static Category WirelessSetupMobile + { + get + { + if (SettingCategories._wirelessSetupMobile == null) + SettingCategories._wirelessSetupMobile = new Category(StringId.IDS_WIRELESS_SYNC_HEADER, "res://ZuneShellResources!DeviceWirelessSync.uix#MobileDefault"); + return SettingCategories._wirelessSetupMobile; + } + } + + public static Category WirelessSetupDevice + { + get + { + if (SettingCategories._wirelessSetupDevice == null) + SettingCategories._wirelessSetupDevice = new Category(StringId.IDS_WIRELESS_SYNC_HEADER, "res://ZuneShellResources!DeviceWirelessSync.uix#DeviceDefault"); + return SettingCategories._wirelessSetupDevice; + } + } + + public static Category WirelessSetupComplete + { + get + { + if (SettingCategories._wirelessSetupComplete == null) + SettingCategories._wirelessSetupComplete = new Category(StringId.IDS_WIRELESS_SYNC_HEADER, "res://ZuneShellResources!DeviceWirelessSync.uix#WirelessSyncComplete"); + return SettingCategories._wirelessSetupComplete; + } + } + + public static Category WirelessSetupManual + { + get + { + if (SettingCategories._wirelessSetupManual == null) + SettingCategories._wirelessSetupManual = new Category(StringId.IDS_WIRELESS_SYNC_HEADER, "res://ZuneShellResources!DeviceWirelessSync.uix#WirelessSyncManual"); + return SettingCategories._wirelessSetupManual; + } + } + + public static Category WirelessSetupNotConfigured + { + get + { + if (SettingCategories._wirelessSetupNotConfigured == null) + SettingCategories._wirelessSetupNotConfigured = new Category(StringId.IDS_WIRELESS_SYNC_HEADER, "res://ZuneShellResources!DeviceWirelessSync.uix#WirelessSyncNotConfigured"); + return SettingCategories._wirelessSetupNotConfigured; + } + } + + public static Category WirelessSetupCurrentConfig + { + get + { + if (SettingCategories._wirelessSetupCurrentConfig == null) + SettingCategories._wirelessSetupCurrentConfig = new Category(StringId.IDS_WIRELESS_SYNC_HEADER, "res://ZuneShellResources!DeviceWirelessSync.uix#WirelessSyncCurrentConfig"); + return SettingCategories._wirelessSetupCurrentConfig; + } + } + + public static Category WirelessSetupDeviceBusy + { + get + { + if (SettingCategories._wirelessSetupDeviceBusy == null) + SettingCategories._wirelessSetupDeviceBusy = new Category(StringId.IDS_WIRELESS_SYNC_HEADER, "res://ZuneShellResources!DeviceWirelessSync.uix#WirelessSyncDeviceBusy"); + return SettingCategories._wirelessSetupDeviceBusy; + } + } + + public static Category DevicePrivacy + { + get + { + if (SettingCategories._devicePrivacy == null) + SettingCategories._devicePrivacy = new Category(StringId.IDS_DEVICE_PRIVACY_MENU_ITEM, "res://ZuneShellResources!DevicePrivacy.uix#Default"); + return SettingCategories._devicePrivacy; + } + } + } +} diff --git a/ZuneUI/SettingsExperience.cs b/ZuneUI/SettingsExperience.cs new file mode 100644 index 0000000..bc00d43 --- /dev/null +++ b/ZuneUI/SettingsExperience.cs @@ -0,0 +1,167 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SettingsExperience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; + +namespace ZuneUI +{ + public class SettingsExperience : Experience + { + private ArrayListDataSet _nodes; + private CategoryPageNode _software; + private CategoryPageNode _device; + private CategoryPageNode _account; + private Category _nameYourDevice; + + public SettingsExperience(Frame frameOwner) + : base(frameOwner, StringId.IDS_SETTINGS_PIVOT, SQMDataId.Invalid) + => SyncControls.Instance.PropertyChanged += new PropertyChangedEventHandler(this.OnSyncPropertyChanged); + + protected override void OnInvoked() + { + if (Shell.SettingsFrame.Wizard.IsCurrent) + return; + base.OnInvoked(); + } + + protected override void OnDispose(bool disposing) + { + SyncControls.Instance.PropertyChanged -= new PropertyChangedEventHandler(this.OnSyncPropertyChanged); + base.OnDispose(disposing); + } + + private void OnSyncPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "CurrentDevice")) + return; + this.Device.Description = SyncControls.Instance.CurrentDevice.PivotDescription; + if (this._nameYourDevice == null) + return; + this._nameYourDevice.Description = Shell.LoadString(StringId.IDS_NAME_ZUNE_HEADER); + } + + public override IList NodesList + { + get + { + if (this._nodes == null) + { + this._nodes = new ArrayListDataSet((IModelItemOwner)this); + this._nodes.Add((object)this.Software); + if (FeatureEnablement.IsFeatureEnabled(Features.eDevice)) + this._nodes.Add((object)this.Device); + if (FeatureEnablement.IsFeatureEnabled(Features.eSignInAvailable)) + this._nodes.Add((object)this.Account); + } + return (IList)this._nodes; + } + } + + public CategoryPageNode Software + { + get + { + if (this._software == null) + this._software = new CategoryPageNode((Experience)this, StringId.IDS_SOFTWARE_PIVOT, (IList)new Category[11] + { + SettingCategories.Collection, + SettingCategories.Filetype, + SettingCategories.Privacy, + SettingCategories.Podcast, + SettingCategories.Sharing, + SettingCategories.Photo, + SettingCategories.Display, + SettingCategories.Rip, + SettingCategories.Burn, + SettingCategories.Metadata, + SettingCategories.General + }, SQMDataId.Invalid, true, false); + return this._software; + } + } + + public CategoryPageNode Device + { + get + { + if (this._device == null) + { + List categoryList = new List(); + categoryList.Add(SettingCategories.SyncOptions); + categoryList.Add(SettingCategories.SyncGroups); + this._nameYourDevice = SettingCategories.NameDevice; + categoryList.Add(this._nameYourDevice); + categoryList.Add(SettingCategories.MoreOnWeb); + if (SettingsExperience.ShouldShowDeviceMarketplaceCategory) + categoryList.Add(SettingCategories.DeviceMarketplace); + categoryList.Add(SettingCategories.FirmwareUpdate); + categoryList.Add(SettingCategories.WirelessSetup); + categoryList.Add(SettingCategories.PictureVideo); + categoryList.Add(SettingCategories.Transcoding); + categoryList.Add(SettingCategories.SpaceReservation); + categoryList.Add(SettingCategories.DevicePrivacy); + this._device = new CategoryPageNode((Experience)this, StringId.IDS_DEVICE_PIVOT, (IList)categoryList, SQMDataId.Invalid, true, false); + } + return this._device; + } + } + + public CategoryPageNode Account + { + get + { + if (this._account == null) + { + List categoryList = new List(); + categoryList.Add(SettingCategories.AccountLinks); + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace)) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eSubscription) || FeatureEnablement.IsFeatureEnabled(Features.eApps)) + categoryList.Add(SettingCategories.Devices); + categoryList.Add(SettingCategories.PurchaseHistory); + categoryList.Add(SettingCategories.RentalHistory); + if (FeatureEnablement.IsFeatureEnabled(Features.eSubscription)) + categoryList.Add(SettingCategories.SubscriptionHistory); + } + this._account = new CategoryPageNode((Experience)this, StringId.IDS_ACCOUNT_PIVOT, (IList)categoryList, SQMDataId.Invalid, true, false); + } + return this._account; + } + } + + internal void ShowDevice(bool show) + { + IList nodesList = this.NodesList; + bool flag = false; + foreach (object obj in (IEnumerable)nodesList) + { + if (obj == this.Device) + { + flag = true; + break; + } + } + if (show == flag) + return; + this.Device.Available = show; + if (show) + { + if (nodesList.Count > 1 && nodesList[0] == this.Software) + nodesList.Insert(1, (object)this.Device); + else + nodesList.Add((object)this.Device); + } + else + nodesList.Remove((object)this.Device); + } + + public static bool ShouldShowDeviceMarketplaceCategory => FeatureEnablement.IsFeatureEnabled(Features.eMarketplace) || FeatureEnablement.IsFeatureEnabled(Features.eSocial); + } +} diff --git a/ZuneUI/SettingsFrame.cs b/ZuneUI/SettingsFrame.cs new file mode 100644 index 0000000..88ca39b --- /dev/null +++ b/ZuneUI/SettingsFrame.cs @@ -0,0 +1,58 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SettingsFrame +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class SettingsFrame : Frame + { + private Experience[] _experiences; + private SettingsExperience _settings; + private WizardExperience _wizard; + + public SettingsFrame(IModelItemOwner owner) + : base(owner) + { + } + + public override IList ExperiencesList + { + get + { + if (this._experiences == null) + this._experiences = new Experience[1] + { + (Experience) this.Settings + }; + return (IList)this._experiences; + } + } + + public SettingsExperience Settings + { + get + { + if (this._settings == null) + this._settings = new SettingsExperience((Frame)this); + return this._settings; + } + } + + public WizardExperience Wizard + { + get + { + if (this._wizard == null) + this._wizard = new WizardExperience((Frame)this); + return this._wizard; + } + } + + protected override void OnIsCurrentChanged() => SingletonModelItem.Instance.AllowUnreadyDevices = !this.IsCurrent || ZuneShell.DefaultInstance.CurrentPage is FirstLaunchLandPage || ZuneShell.DefaultInstance.CurrentPage is GDILandPage; + } +} diff --git a/ZuneUI/SetupLandPage.cs b/ZuneUI/SetupLandPage.cs new file mode 100644 index 0000000..3f1ee84 --- /dev/null +++ b/ZuneUI/SetupLandPage.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SetupLandPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class SetupLandPage : NoStackPage + { + public SetupLandPage() + { + this.SetConnectionRule(); + this.ShowComputerIcon = ComputerIconState.Hide; + this.ShowSearch = false; + this.ShowSettings = false; + this.ShowLogo = false; + this.ShowBackArrow = false; + this.ShowCDIcon = false; + this.ShowDeviceIcon = false; + this.ShowPlaylistIcon = false; + this.ShowPivots = false; + this.CanEnterCompactMode = false; + this.TransportControlStyle = TransportControlStyle.None; + this.NotificationAreaVisible = false; + this.TransportControlsVisible = false; + this.PivotPreference = (Node)Shell.SettingsFrame.Wizard.FUE; + } + + protected override void OnNavigatedToWorker() + { + SyncControls.Instance.CurrentDevice.IsLockedAgainstSyncing = true; + base.OnNavigatedToWorker(); + } + + protected override void OnNavigatedAwayWorker(IPage destination) + { + if (!(destination is SetupLandPage)) + SyncControls.Instance.CurrentDevice.IsLockedAgainstSyncing = false; + base.OnNavigatedAwayWorker(destination); + } + + protected virtual void SetConnectionRule() => SingletonModelItem.Instance.AllowDeviceConnections = false; + + protected override void OnDispose(bool disposing) + { + DeviceManagement.SetupDevice = (UIDevice)null; + SingletonModelItem.Instance.AllowDeviceConnections = true; + base.OnDispose(disposing); + } + } +} diff --git a/ZuneUI/SetupLandWizardNavigationCommand.cs b/ZuneUI/SetupLandWizardNavigationCommand.cs new file mode 100644 index 0000000..68d6061 --- /dev/null +++ b/ZuneUI/SetupLandWizardNavigationCommand.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SetupLandWizardNavigationCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class SetupLandWizardNavigationCommand : Command + { + private SetupLandPage _page; + + public SetupLandWizardNavigationCommand(SetupLandPage page) + : base((IModelItemOwner)null, (string)null, (EventHandler)null) + => this._page = page; + + protected override void OnInvoked() + { + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)this._page); + base.OnInvoked(); + } + } +} diff --git a/ZuneUI/Shell.cs b/ZuneUI/Shell.cs new file mode 100644 index 0000000..58f32cc --- /dev/null +++ b/ZuneUI/Shell.cs @@ -0,0 +1,914 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Shell +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Win32; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Globalization; +using System.IO; +using System.Security; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using UIXControls; + +namespace ZuneUI +{ + public class Shell : ZuneShell + { + private const int c_minimumWindowWidth = 734; + private const int c_minimumWindowHeight = 500; + private static ZuneUI.Shell.FeatureEnumUIPathMapping[] s_FeatureEnumUIPathMap = new ZuneUI.Shell.FeatureEnumUIPathMapping[32] + { + new ZuneUI.Shell.FeatureEnumUIPathMapping("Quickplay", Features.eQuickplay), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Social", Features.eSocial), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace\\Fresh", Features.ePicks), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace\\Default", Features.eMarketplace), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace\\MusicVideos", Features.eMusicVideos), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace\\Podcasts", Features.ePodcasts), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace\\Channels", Features.eChannels), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace\\Apps", Features.eGames), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace\\Apps", Features.eApps), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace\\Videos\\Series", Features.eTV), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace\\Videos\\TrailersHome", Features.eMovieTrailers), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Marketplace", Features.eMarketplace), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Collection\\Podcasts", Features.ePodcasts), + new ZuneUI.Shell.FeatureEnumUIPathMapping("Collection\\Channels", Features.eChannels), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eSubscription), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eSubscriptionConfirmation), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eSubscriptionFreeTracks), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eSubscriptionTrial), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eSubscriptionMusicDownload), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eSubscriptionMusicVideoStreaming), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eSignInAvailable), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eFirstLaunchIntroVideo), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eMBRRental), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eMBRPurchase), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eMBRPreview), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eOptIn), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eQuickMixLocal), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eQuickMixZmp), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eMusic), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eMixview), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eSocialMarketplace), + new ZuneUI.Shell.FeatureEnumUIPathMapping("", Features.eVideoAllHub) + }; + private static ZuneUI.Shell.ExternalLinkMapping[] s_externalLinkMap = new ZuneUI.Shell.ExternalLinkMapping[19] + { + new ZuneUI.Shell.ExternalLinkMapping("trackID", "Marketplace\\Music\\Artist", "TrackId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eMusic), + new ZuneUI.Shell.ExternalLinkMapping("albumID", "Marketplace\\Music\\Artist", "AlbumId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eMusic), + new ZuneUI.Shell.ExternalLinkMapping("videoID", "Marketplace\\Music\\Artist", "VideoId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eMusic), + new ZuneUI.Shell.ExternalLinkMapping("artistID", "Marketplace\\Music\\Artist", "ArtistId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eMusic), + new ZuneUI.Shell.ExternalLinkMapping("playlistID", "Marketplace\\Music\\Playlist", "PlaylistId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eMusic), + new ZuneUI.Shell.ExternalLinkMapping("hubID", "Marketplace\\Music\\FlexHub", "HubId", (ZuneUI.Shell.ConvertArgumentsDelegate) null, (ZuneUI.Shell.SetClientContextDelegate) null, Features.eMusic), + new ZuneUI.Shell.ExternalLinkMapping("podcastID", "Marketplace\\Podcasts\\Series", "PodcastId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.ePodcasts), + new ZuneUI.Shell.ExternalLinkMapping("tvSeriesID", "Marketplace\\Videos\\Series", "SeriesId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eTV), + new ZuneUI.Shell.ExternalLinkMapping("tvEpisodeID", "Marketplace\\Videos\\Series", "EpisodeId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eTV), + new ZuneUI.Shell.ExternalLinkMapping("tvSpecialID", "Marketplace\\Videos\\Short", "ShortId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eVideos), + new ZuneUI.Shell.ExternalLinkMapping("movieID", "Marketplace\\Videos\\Movie", "MovieId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eVideos), + new ZuneUI.Shell.ExternalLinkMapping("channelID", "Marketplace\\Channels\\Channel", "ChannelId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eChannels), + new ZuneUI.Shell.ExternalLinkMapping("appID", "Marketplace\\Apps\\Details\\ZuneHD", "AppId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eGames), + new ZuneUI.Shell.ExternalLinkMapping("phoneAppID", "Marketplace\\Apps\\Details\\WindowsPhone", "AppId", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.CanonicalizeGuid), new ZuneUI.Shell.SetClientContextDelegate(ZuneUI.Shell.SetGuidClientContext), Features.eApps), + new ZuneUI.Shell.ExternalLinkMapping("cartItemID", "Marketplace\\Cart", "MessageId", (ZuneUI.Shell.ConvertArgumentsDelegate) null, (ZuneUI.Shell.SetClientContextDelegate) null, Features.eMusic), + new ZuneUI.Shell.ExternalLinkMapping("messageID", "Social\\Inbox", "MessageId", (ZuneUI.Shell.ConvertArgumentsDelegate) null, (ZuneUI.Shell.SetClientContextDelegate) null, Features.eSocial), + new ZuneUI.Shell.ExternalLinkMapping("profile", "Social\\Profile", "ZuneTag", new ZuneUI.Shell.ConvertArgumentsDelegate(ZuneUI.Shell.IsValidZuneTag), (ZuneUI.Shell.SetClientContextDelegate) null, Features.eSocial), + new ZuneUI.Shell.ExternalLinkMapping("myProfile", "Social\\Profile", (string) null, (ZuneUI.Shell.ConvertArgumentsDelegate) null, (ZuneUI.Shell.SetClientContextDelegate) null, Features.eSocial), + new ZuneUI.Shell.ExternalLinkMapping("purchasePass", "Settings\\Account\\PurchaseSubscription", (string) null, (ZuneUI.Shell.ConvertArgumentsDelegate) null, (ZuneUI.Shell.SetClientContextDelegate) null, Features.eSubscription) + }; + private Node _currentNode; + private bool _haveDoneInitialNavigation; + private Command _searchButton; + private MainFrame _mainFrame; + private SettingsFrame _settingsFrame; + private bool _pivotMismatch; + private string _backgroundImage; + private bool _playSounds; + private bool _compactModeAlwaysOnTop; + private bool _showWhatsNew; + private Point _compactModeWindowPosition; + private Point _normalWindowPosition; + private Size _normalWindowSize; + private int _showNowPlayingBackgroundOnIdleTimeout; + private bool _applicationInitializationIsComplete; + private static string _sessionStartupPath; + + public Shell() + { + this._mainFrame = new MainFrame((IModelItemOwner)this); + this._searchButton = new Command((IModelItemOwner)this, new EventHandler(this.OnSearchButtonClicked)); + this._playSounds = ClientConfiguration.Shell.Sounds; + this._compactModeAlwaysOnTop = ClientConfiguration.GeneralSettings.CompactModeAlwaysOnTop; + this._showNowPlayingBackgroundOnIdleTimeout = ClientConfiguration.Shell.ShowNowPlayingBackgroundOnIdleTimeout; + this._showWhatsNew = ClientConfiguration.Shell.ShowWhatsNew; + this.ReadNormalWindowPositionAndSize(); + this.ReadCompactModeWindowPosition(); + } + + public Frame CurrentFrame => this.CurrentExperience?.Frame; + + public Experience CurrentExperience => this._currentNode == null ? (Experience)null : this._currentNode.Experience; + + public bool PivotMismatch + { + get => this._pivotMismatch; + set + { + if (this._pivotMismatch == value) + return; + this._pivotMismatch = value; + this.FirePropertyChanged(nameof(PivotMismatch)); + } + } + + public Node CurrentNode + { + get => this._currentNode; + set + { + if (this._currentNode == value) + return; + Frame currentFrame1 = this.CurrentFrame; + Experience currentExperience1 = this.CurrentExperience; + Node currentNode = this._currentNode; + this._currentNode = value; + if (currentNode != null) + currentNode.IsCurrent = false; + if (this._currentNode != null) + { + this._currentNode.IsCurrent = true; + Experience currentExperience2 = this.CurrentExperience; + Choice experiences = this.CurrentFrame.Experiences; + int num1 = experiences.Options.IndexOf((object)currentExperience2); + if (num1 != -1) + { + this.PivotMismatch = false; + experiences.ChosenIndex = num1; + Choice nodes = currentExperience2.Nodes; + int num2 = nodes.Options.IndexOf((object)this._currentNode); + if (num2 != -1) + nodes.ChosenIndex = num2; + } + else + this.PivotMismatch = true; + } + Frame currentFrame2 = this.CurrentFrame; + if (currentFrame1 != currentFrame2) + { + if (currentFrame1 != null) + currentFrame1.IsCurrent = false; + if (currentFrame2 != null) + currentFrame2.IsCurrent = true; + this.FirePropertyChanged("CurrentFrame"); + } + Experience currentExperience3 = this.CurrentExperience; + if (currentExperience1 != currentExperience3) + { + if (currentExperience1 != null) + currentExperience1.IsCurrent = false; + if (currentExperience3 != null) + currentExperience3.IsCurrent = true; + this.FirePropertyChanged("CurrentExperience"); + } + this.FirePropertyChanged(nameof(CurrentNode)); + } + } + + public SettingsFrame SettingsFrameImpl + { + get + { + if (this._settingsFrame == null) + this._settingsFrame = new SettingsFrame((IModelItemOwner)this); + return this._settingsFrame; + } + } + + public MainFrame MainFrameImpl => this._mainFrame; + + public static SettingsFrame SettingsFrame => ((ZuneUI.Shell)ZuneShell.DefaultInstance)?.SettingsFrameImpl; + + public static MainFrame MainFrame => ((ZuneUI.Shell)ZuneShell.DefaultInstance)?.MainFrameImpl; + + public static bool PreRelease => false; + + public static string SessionStartupPath + { + get => ZuneUI.Shell._sessionStartupPath; + private set => ZuneUI.Shell._sessionStartupPath = value; + } + + public static void InitializeInstance() + { + ZuneUI.Shell shell = new ZuneUI.Shell(); + } + + public static void NavigateToHomePage() + { + try + { + string path = ClientConfiguration.Shell.StartupPage; + if (!ZuneUI.Shell.IsUIPathEnabled(path)) + path = ZuneUI.Shell.MainFrame.Collection.DefaultUIPath; + ZuneUI.Shell.SessionStartupPath = path; + ZuneShell.DefaultInstance.Execute(ZuneUI.Shell.SessionStartupPath, (IDictionary)null); + } + catch (ArgumentException ex) + { + ZuneUI.Shell.SessionStartupPath = ZuneUI.Shell.MainFrame.Collection.DefaultUIPath; + ZuneShell.DefaultInstance.Execute(ZuneUI.Shell.SessionStartupPath, (IDictionary)null); + } + } + + public static unsafe SecureString MakeSecureString(string value, bool readOnly) + { + SecureString secureString; + if (string.IsNullOrEmpty(value)) + { + secureString = new SecureString(); + } + else + { + fixed (char* chPtr = value.ToCharArray()) + secureString = new SecureString(chPtr, value.Length); + } + if (readOnly) + secureString.MakeReadOnly(); + return secureString; + } + + protected override void OnPropertyChanged(string property) + { + if (property == "CurrentPage") + this.UpdatePivots(); + else if (property == "CommandHandler" && !this._haveDoneInitialNavigation) + { + if (ClientConfiguration.FUE.SettingsVersion < ZuneApplication.ZuneCurrentSettingsVersion || Fue.Instance.IsFirstLaunch) + { + (!FeatureEnablement.IsFeatureEnabled(Features.eQuickplay) ? (Command)ZuneUI.Shell.MainFrame.Collection : (Command)ZuneUI.Shell.MainFrame.Quickplay).Invoke(InvokePolicy.Synchronous); + ClientConfiguration.Devices.CurrentDeviceID = 0; + if (Application.RenderingType == RenderingType.GDI) + this.NavigateToPage((ZunePage)new GDILandPage()); + else + this.NavigateToPage((ZunePage)new FirstLaunchLandPage()); + } + else if (Application.RenderingType != RenderingType.GDI && ClientConfiguration.GeneralSettings.ReevaluateVideoSettings) + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.GdiToD3DRenderPrompt(); + }, new TimeSpan(0, 0, 3)); + this._haveDoneInitialNavigation = true; + } + base.OnPropertyChanged(property); + } + + private void GdiToD3DRenderPrompt() => Win32MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_RENDER_PROMPT_AFTER_D3D_SWITCH), ZuneUI.Shell.LoadString(StringId.IDS_RENDER_PROMPT_CAPTION), Win32MessageBoxType.MB_YESNO | Win32MessageBoxType.MB_ICONQUESTION, (DeferredInvokeHandler)(args => + { + int num = (int)args; + ClientConfiguration.GeneralSettings.ReevaluateVideoSettings = false; + if (num != 7) + return; + ClientConfiguration.GeneralSettings.RenderingType = 0; + Win32MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_RENDER_PROMPT_RESTART), ZuneUI.Shell.LoadString(StringId.IDS_RENDER_PROMPT_CAPTION), Win32MessageBoxType.MB_ICONASTERISK, (DeferredInvokeHandler)delegate + { + Application.Window.Close(); + }); + })); + + private void UpdatePivots() + { + if (this._mainFrame == null) + return; + ZunePage currentPage = this.CurrentPage; + int num = TraceSwitches.ShellSwitch.TraceVerbose ? 1 : 0; + if (currentPage.PivotPreference != null) + this.CurrentNode = currentPage.PivotPreference; + else + currentPage.PivotPreference = this.CurrentNode; + } + + private void OnSearchButtonClicked(object sender, EventArgs e) + { + if (!(this.CurrentPage.UI != ZuneUI.Shell.SearchTemplate)) + return; + ZunePage page = new ZunePage(); + page.UI = ZuneUI.Shell.SearchTemplate; + page.TakeFocusOnNavigate = false; + Node pivotPreference = this.CurrentPage.PivotPreference; + SearchResultContextType resultContextType = SearchResultContextType.Undefined; + if (pivotPreference == ZuneUI.Shell.MainFrame.Collection.Music || pivotPreference == ZuneUI.Shell.MainFrame.Marketplace.Music) + resultContextType = SearchResultContextType.Music; + else if (pivotPreference == ZuneUI.Shell.MainFrame.Collection.Videos || pivotPreference == ZuneUI.Shell.MainFrame.Marketplace.Videos) + resultContextType = SearchResultContextType.Video; + else if (pivotPreference == ZuneUI.Shell.MainFrame.Collection.Podcasts || pivotPreference == ZuneUI.Shell.MainFrame.Marketplace.Podcasts) + resultContextType = SearchResultContextType.Podcast; + else if (pivotPreference == ZuneUI.Shell.MainFrame.Collection.Channels || pivotPreference == ZuneUI.Shell.MainFrame.Marketplace.Channels) + resultContextType = SearchResultContextType.Channel; + else if (this.CurrentFrame.Experiences.ChosenValue == ZuneUI.Shell.MainFrame.Social) + resultContextType = SearchResultContextType.Social; + else if (pivotPreference == ZuneUI.Shell.MainFrame.Marketplace.Apps) + resultContextType = SearchResultContextType.App; + Search.Instance.UsersContextType = resultContextType; + this.NavigateToPage(page); + } + + public Command SearchButton => this._searchButton; + + public string BackgroundImage + { + get + { + if (this._backgroundImage == null) + this._backgroundImage = ClientConfiguration.Shell.BackgroundImage; + return this._backgroundImage; + } + internal set + { + if (!(this._backgroundImage != value)) + return; + this._backgroundImage = value; + this.FirePropertyChanged(nameof(BackgroundImage)); + } + } + + public bool AmbientAnimations => Application.RenderingQuality == RenderingQuality.MaxQuality; + + public bool PlaySounds + { + get => this._playSounds; + internal set + { + if (this._playSounds == value) + return; + this._playSounds = value; + this.FirePropertyChanged(nameof(PlaySounds)); + } + } + + public bool CompactModeAlwaysOnTop + { + get => this._compactModeAlwaysOnTop; + internal set + { + if (this._compactModeAlwaysOnTop == value) + return; + this._compactModeAlwaysOnTop = value; + this.FirePropertyChanged(nameof(CompactModeAlwaysOnTop)); + } + } + + public int ShowNowPlayingBackgroundOnIdleTimeout + { + get => this._showNowPlayingBackgroundOnIdleTimeout; + set + { + if (this._showNowPlayingBackgroundOnIdleTimeout == value) + return; + this._showNowPlayingBackgroundOnIdleTimeout = value; + this.FirePropertyChanged(nameof(ShowNowPlayingBackgroundOnIdleTimeout)); + } + } + + public bool ShowWhatsNew + { + get => this._showWhatsNew && FeatureEnablement.IsFeatureEnabled(Features.eSubscriptionFreeTracks); + set + { + if (this._showWhatsNew == value) + return; + this._showWhatsNew = value; + this.FirePropertyChanged(nameof(ShowWhatsNew)); + } + } + + public Point CompactModeWindowPosition + { + get => this._compactModeWindowPosition; + set + { + if (this._compactModeWindowPosition == value) + return; + this._compactModeWindowPosition = value; + this.FirePropertyChanged(nameof(CompactModeWindowPosition)); + this.SaveCompactModeWindowPosition(); + } + } + + public Point NormalWindowPosition + { + get => this._normalWindowPosition; + set + { + if (this._normalWindowPosition == value) + return; + this._normalWindowPosition = value; + this.FirePropertyChanged(nameof(NormalWindowPosition)); + this.SaveNormalWindowPositionAndSize(); + } + } + + public Size NormalWindowSize + { + get => this._normalWindowSize; + set + { + if (this._normalWindowSize == value) + return; + this._normalWindowSize = value; + this.FirePropertyChanged(nameof(NormalWindowSize)); + this.SaveNormalWindowPositionAndSize(); + } + } + + public bool ApplicationInitializationIsComplete + { + get => this._applicationInitializationIsComplete; + set + { + if (!value || this._applicationInitializationIsComplete) + return; + this._applicationInitializationIsComplete = value; + this.FirePropertyChanged(nameof(ApplicationInitializationIsComplete)); + } + } + + public static WindowColor WindowColorFromRGB(int rgb) + { + if (ClientConfiguration.Shell.StartupPage.ToLower().Contains("quickplay")) + return new WindowColor(17, 9, 15); + return (rgb >> 24 & (int)byte.MaxValue) == 0 ? new WindowColor(243, 239, 241) : new WindowColor(rgb >> 16 & (int)byte.MaxValue, rgb >> 8 & (int)byte.MaxValue, rgb & (int)byte.MaxValue); + } + + public static int WindowColorToRGB(WindowColor color) => -16777216 | (int)color.R << 16 | (int)color.G << 8 | (int)color.B; + + public static void ShowErrorDialog(int hr, string title) => ErrorDialogInfo.Show(hr, title); + + public static void ShowErrorDialog(int hr, eErrorCondition condition, string title) => ErrorDialogInfo.Show(hr, condition, title); + + public static void ShowErrorDialog(int hr, StringId stringId) => ZuneUI.Shell.ShowErrorDialog(hr, ZuneUI.Shell.LoadString(stringId)); + + public static void ShowErrorDialog(int hr, eErrorCondition condition, StringId stringId) => ZuneUI.Shell.ShowErrorDialog(hr, condition, ZuneUI.Shell.LoadString(stringId)); + + public static void ShowErrorDialog(int hr, StringId titleId, StringId descriptionId) => ErrorDialogInfo.Show(hr, ZuneUI.Shell.LoadString(titleId), ZuneUI.Shell.LoadString(descriptionId)); + + public static string LoadString(StringId stringId) + { + if (PhoneBrandingStringMap.Instance.BrandingEnabled) + stringId = PhoneBrandingStringMap.Instance.TryGetMappedStringId(stringId); + else if (KinBrandingStringMap.Instance.BrandingEnabled) + stringId = KinBrandingStringMap.Instance.TryGetMappedStringId(stringId); + return ZuneLibrary.LoadStringFromResource((uint)stringId); + } + + public static string LoadString(string stringIdString) + { + string str = string.Empty; + if (!string.IsNullOrEmpty(stringIdString)) + { + try + { + str = ZuneUI.Shell.LoadString((StringId)System.Enum.Parse(typeof(StringId), stringIdString, true)); + } + catch (ArgumentException ex) + { + } + } + return str; + } + + public static string TimeSpanToString(TimeSpan time, bool prefixWithNegative) + { + string str = !prefixWithNegative ? "" : CultureInfo.CurrentCulture.NumberFormat.NegativeSign; + return time.Hours != 0 ? string.Format("{4}{1}{0}{2:00}{0}{3:00}", (object)CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator, (object)time.Hours, (object)time.Minutes, (object)time.Seconds, (object)str) : string.Format("{3}{1:0}{0}{2:00}", (object)CultureInfo.CurrentCulture.DateTimeFormat.TimeSeparator, (object)time.Minutes, (object)time.Seconds, (object)str); + } + + public static string TimeSpanToString(TimeSpan time) => ZuneUI.Shell.TimeSpanToString(time, false); + + public static void DeleteMedia(IList mediaList, bool deleteFileOnDisk) + { + ArrayList tempMediaList = new ArrayList((ICollection)mediaList); + bool tempDelFileOnDisk = deleteFileOnDisk; + ThreadPool.QueueUserWorkItem((WaitCallback)(o => + { + LibraryDataProvider.ActOnItems((IList)tempMediaList, BulkItemAction.DeleteFromLibrary, (EventArgs)new DeleteFromLibraryEventArgs() + { + DeleteFromDisk = tempDelFileOnDisk + }); + foreach (IDatabaseMedia databaseMedia in tempMediaList) + { + if (databaseMedia is LibraryDataProviderListItem providerListItem && providerListItem.TypeName == "MediaFolder") + { + Management management = ZuneShell.DefaultInstance.Management; + management.RemoveMonitoredFolder(management.MonitoredPhotoFolders, (string)providerListItem.GetProperty("FolderPath"), true); + } + } + }), (object)null); + } + + public static void ProcessExternalLink(string link) + { + if (string.IsNullOrEmpty(link)) + return; + if (string.Compare(link, "zune://refreshAccount/", true) == 0) + { + SignIn.Instance.RefreshAccount(); + } + else + { + Match match = new Regex("^zune:(\\/\\/)?(?\\w+)(\\/)?\\?(?[^=]+)=?(?.*)$").Match(link); + if (!match.Success) + return; + string strA = match.Groups["action"].Value; + if (string.Compare(strA, "subscribe", true) == 0) + { + string feedTitle = match.Groups["param1"].Value; + string stringToEscape = match.Groups["value1"].Value; + if (stringToEscape != null && stringToEscape.Length < 32766) + { + string feedUrl = Uri.EscapeUriString(stringToEscape); + SubscribeConfirmDialogHelper.Show(feedTitle, feedUrl); + } + else + ErrorDialogInfo.Show(-1072884971, ZuneUI.Shell.LoadString(StringId.IDS_PODCAST_SUBSCRIPTION_ERROR)); + } + else + { + if (string.Compare(strA, "navigate", true) != 0) + return; + ZuneUI.Shell.ProtocolHandlerNavigate(match.Groups["param1"].Value, match.Groups["value1"]?.Value); + } + } + } + + public static void ProtocolHandlerNavigate(string typeId, string value) + { + bool flag = false; + foreach (ZuneUI.Shell.ExternalLinkMapping externalLink in ZuneUI.Shell.s_externalLinkMap) + { + if (string.Equals(externalLink.ExternalLinkName, typeId, StringComparison.OrdinalIgnoreCase)) + { + if (externalLink.FeatureRequired == Features.eLastFeature || FeatureEnablement.IsFeatureEnabled(externalLink.FeatureRequired)) + { + string convertedValue = value; + if (externalLink.ConversionFunction != null && !externalLink.ConversionFunction(value, out convertedValue)) + return; + Hashtable hashtable = (Hashtable)null; + if (externalLink.ParamName != null) + { + hashtable = new Hashtable(); + hashtable[(object)externalLink.ParamName] = (object)convertedValue; + hashtable[(object)"IsDeepLink"] = (object)true; + } + ZuneShell.DefaultInstance.Execute(externalLink.NavigatePath, (IDictionary)hashtable); + if (externalLink.ClientContextFunction != null) + externalLink.ClientContextFunction(convertedValue); + } + else + { + string empty = string.Empty; + string message; + switch (externalLink.FeatureRequired) + { + case Features.eVideos: + message = ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_VIDEO); + break; + case Features.ePodcasts: + message = ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_PODCAST); + break; + case Features.eChannels: + message = ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_CHANNEL); + break; + case Features.eGames: + message = ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_APPS); + break; + case Features.eApps: + message = ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_APPS); + break; + case Features.eTV: + message = ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_TV); + break; + case Features.eSubscription: + message = ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_SUBSCRIPTION); + break; + case Features.eMusic: + message = ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_MUSIC); + break; + default: + message = ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_GENERAL); + break; + } + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_EXTERNAL_LINK_BLOCKED_HEADER), message, (EventHandler)null); + } + flag = true; + break; + } + } + int num = flag ? 1 : 0; + } + + private static bool CanonicalizeGuid(string value, out string canonicalValue) + { + canonicalValue = (string)null; + bool flag = false; + try + { + canonicalValue = new Guid(value).ToString(); + flag = true; + } + catch (Exception ex) + { + } + return flag; + } + + private static void SetGuidClientContext(string value) + { + Guid empty = Guid.Empty; + Guid clientContextEventValue; + try + { + clientContextEventValue = new Guid(value); + } + catch (FormatException ex) + { + clientContextEventValue = Guid.Empty; + } + Download.Instance.ReportClientContextEvent(Microsoft.Zune.Service.EDownloadContextEvent.DeepLink, clientContextEventValue); + } + + private static bool IsValidZuneTag(string value, out string canonicalValue) + { + canonicalValue = (string)null; + bool flag = true; + foreach (char c in value) + { + if (!char.IsLetterOrDigit(c) && c != ' ') + { + flag = false; + break; + } + } + if (flag) + canonicalValue = value; + return flag; + } + + public static string ReformatFolderPathName(string path) + { + try + { + FileInfo fileInfo = new FileInfo(path); + string format = ZuneUI.Shell.LoadString(StringId.IDS_MEDIASTORE_TRACK_REFORMATTING); + if (string.IsNullOrEmpty(fileInfo.Name)) + ; + return string.Format(format, (object)fileInfo.Name, (object)path); + } + catch (Exception ex) + { + return path; + } + } + + public static void OpenFolderAndSelectItems(string filePath) => ShellInterop.OpenFolderAndSelectItem(filePath); + + public static string SettingsRegistryPath => "HKEY_CURRENT_USER\\Software\\Microsoft\\Zune\\Shell"; + + public static void SaveInt(string keyName, int value) => Registry.SetValue(ZuneUI.Shell.SettingsRegistryPath, keyName, (object)value); + + public static int GetInt(string keyName, int min, int max, int defaultValue) => string.IsNullOrEmpty(keyName) || (!(Registry.GetValue(ZuneUI.Shell.SettingsRegistryPath, keyName, (object)defaultValue) is int num) || num < min || num > max) ? defaultValue : num; + + private static void SaveList(string keyName, IList values, ZuneUI.Shell.ToStringer toString) + { + StringBuilder stringBuilder = new StringBuilder(); + foreach (object obj in (IEnumerable)values) + { + if (stringBuilder.Length > 0) + stringBuilder.Append(';'); + stringBuilder.Append(toString(obj)); + } + Registry.SetValue(ZuneUI.Shell.SettingsRegistryPath, keyName, (object)stringBuilder.ToString()); + } + + public static void SaveIntList(string keyName, IList values) => ZuneUI.Shell.SaveList(keyName, values, (ZuneUI.Shell.ToStringer)(value => ((int)value).ToString((IFormatProvider)NumberFormatInfo.InvariantInfo))); + + public static void SaveFloatList(string keyName, IList values) => ZuneUI.Shell.SaveList(keyName, values, (ZuneUI.Shell.ToStringer)(value => ((float)value).ToString((IFormatProvider)NumberFormatInfo.InvariantInfo))); + + private static IList GetList(string keyName, int expectedCount, ZuneUI.Shell.TryParser tryParse) + { + string str = Registry.GetValue(ZuneUI.Shell.SettingsRegistryPath, keyName, (object)null) as string; + if (string.IsNullOrEmpty(str)) + return (IList)null; + string[] strArray = str.Split(';'); + if (strArray.Length != expectedCount) + return (IList)null; + ArrayList arrayList = new ArrayList(expectedCount); + for (int index = 0; index < expectedCount; ++index) + { + object obj; + if (!tryParse(strArray[index], out obj)) + return (IList)null; + arrayList.Add(obj); + } + return (IList)arrayList; + } + + public static IList GetIntList(string keyName, int expectedCount) => ZuneUI.Shell.GetList(keyName, expectedCount, (ZuneUI.Shell.TryParser)((string s, out object value) => + { + int result; + bool flag = int.TryParse(s, NumberStyles.Integer, (IFormatProvider)NumberFormatInfo.InvariantInfo, out result); + value = (object)result; + return flag; + })); + + public static IList GetPositiveIntList(string keyName, int expectedCount) + { + IList list = ZuneUI.Shell.GetIntList(keyName, expectedCount); + if (list != null) + { + foreach (int num in (IEnumerable)list) + { + if (num <= 0) + { + list = (IList)null; + break; + } + } + } + return list; + } + + public static IList GetReorderedIntList(string keyName, int expectedCount) + { + IList list = ZuneUI.Shell.GetIntList(keyName, expectedCount); + if (list != null) + { + BitArray bitArray = new BitArray(expectedCount); + foreach (int index in (IEnumerable)list) + { + if (index < 0 || index >= expectedCount || bitArray[index]) + { + list = (IList)null; + break; + } + bitArray[index] = true; + } + } + return list; + } + + public static IList GetFloatList(string keyName, int expectedCount) => ZuneUI.Shell.GetList(keyName, expectedCount, (ZuneUI.Shell.TryParser)((string s, out object value) => + { + float result; + bool flag = float.TryParse(s, NumberStyles.Float, (IFormatProvider)NumberFormatInfo.InvariantInfo, out result); + value = (object)result; + return flag; + })); + + public static IList GetPositionList(string keyName, int expectedCount) + { + IList list = ZuneUI.Shell.GetFloatList(keyName, expectedCount); + if (list != null) + { + float num1 = 0.0f; + foreach (float num2 in (IEnumerable)list) + { + if ((double)num2 < (double)num1 || (double)num2 > 1.0) + { + list = (IList)null; + break; + } + num1 = num2; + } + } + return list; + } + + private void ReadNormalWindowPositionAndSize() + { + IList intList = ZuneUI.Shell.GetIntList(ZuneUI.Shell.regNormalWindowPosition, 4); + if (intList == null || intList.Count != 4) + return; + this._normalWindowPosition = new Point((int)intList[0], (int)intList[1]); + this._normalWindowSize = new Size((int)intList[2], (int)intList[3]); + } + + private void SaveNormalWindowPositionAndSize() + { + if (this._normalWindowPosition == null || this._normalWindowSize == null) + return; + ZuneUI.Shell.SaveIntList(ZuneUI.Shell.regNormalWindowPosition, (IList)new int[4] + { + this._normalWindowPosition.X, + this._normalWindowPosition.Y, + this._normalWindowSize.Width, + this._normalWindowSize.Height + }); + } + + private void ReadCompactModeWindowPosition() + { + IList intList = ZuneUI.Shell.GetIntList(ZuneUI.Shell.regCompactModeWindowPosition, 2); + if (intList == null || intList.Count != 2) + return; + this._compactModeWindowPosition = new Point((int)intList[0], (int)intList[1]); + } + + private void SaveCompactModeWindowPosition() + { + if (this._compactModeWindowPosition == null) + return; + ZuneUI.Shell.SaveIntList(ZuneUI.Shell.regCompactModeWindowPosition, (IList)new int[2] + { + this._compactModeWindowPosition.X, + this._compactModeWindowPosition.Y + }); + } + + public static bool IsUIPathEnabled(string path) + { + bool flag = true; + int num = 0; + if (!string.IsNullOrEmpty(path)) + { + foreach (ZuneUI.Shell.FeatureEnumUIPathMapping featureEnumUiPath in ZuneUI.Shell.s_FeatureEnumUIPathMap) + { + if (path.StartsWith(featureEnumUiPath.Path, StringComparison.InvariantCultureIgnoreCase) && (featureEnumUiPath.Path.Length == path.Length || featureEnumUiPath.Path.Length < path.Length && path[featureEnumUiPath.Path.Length] == '\\') && featureEnumUiPath.Path.Length >= num) + { + num = featureEnumUiPath.Path.Length; + flag = FeatureEnablement.IsFeatureEnabled(featureEnumUiPath.Feature); + if (flag) + break; + } + } + } + return flag; + } + + private static string LibraryTemplate => "res://ZuneShellResources!Library.uix#Library"; + + private static string SearchTemplate => "res://ZuneShellResources!Search.uix#Search"; + + private static string regNormalWindowPosition => "NormalWindowPosition"; + + private static string regCompactModeWindowPosition => "CompactModeWindowPosition"; + + public static int MinimumWindowWidth => 734; + + public static int MinimumWindowHeight => 500; + + public static bool IgnoreAppNavigationsArgs { get; set; } + + private delegate string ToStringer(object value); + + private delegate bool TryParser(string s, out object value); + + private class FeatureEnumUIPathMapping + { + public readonly string Path; + public readonly Features Feature; + + public FeatureEnumUIPathMapping(string path, Features feature) + { + this.Path = path; + this.Feature = feature; + } + } + + private delegate bool ConvertArgumentsDelegate(string value, out string convertedValue); + + private delegate void SetClientContextDelegate(string value); + + private class ExternalLinkMapping + { + public string ExternalLinkName; + public string NavigatePath; + public string ParamName; + public ZuneUI.Shell.ConvertArgumentsDelegate ConversionFunction; + public ZuneUI.Shell.SetClientContextDelegate ClientContextFunction; + public Features FeatureRequired; + + public ExternalLinkMapping( + string externalLinkName, + string navigatePath, + string paramName, + ZuneUI.Shell.ConvertArgumentsDelegate conversionFunction, + ZuneUI.Shell.SetClientContextDelegate clientContextFunction, + Features featureRequired) + { + this.ExternalLinkName = externalLinkName; + this.NavigatePath = navigatePath; + this.ParamName = paramName; + this.ConversionFunction = conversionFunction; + this.ClientContextFunction = clientContextFunction; + this.FeatureRequired = featureRequired; + } + } + } +} diff --git a/ZuneUI/ShellCommand.cs b/ZuneUI/ShellCommand.cs new file mode 100644 index 0000000..2bfef73 --- /dev/null +++ b/ZuneUI/ShellCommand.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ShellCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class ShellCommand : Microsoft.Iris.Command + { + private string _command; + private IDictionary _commandArguments; + + public string Command + { + get => this._command; + set + { + if (!(this._command != value)) + return; + this._command = value; + this.FirePropertyChanged(nameof(Command)); + } + } + + public IDictionary CommandArguments + { + get + { + if (this._commandArguments == null) + this.CommandArguments = (IDictionary)new Hashtable(); + return this._commandArguments; + } + set + { + if (this._commandArguments == value) + return; + this._commandArguments = value; + this.FirePropertyChanged(nameof(CommandArguments)); + } + } + + protected override void OnInvoked() + { + if (this._command != null) + ZuneShell.DefaultInstance?.Execute(this._command, this._commandArguments); + base.OnInvoked(); + } + } +} diff --git a/ZuneUI/ShellInterop.cs b/ZuneUI/ShellInterop.cs new file mode 100644 index 0000000..5fc10d8 --- /dev/null +++ b/ZuneUI/ShellInterop.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ShellInterop +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.InteropServices; +using System.Threading; + +namespace ZuneUI +{ + internal static class ShellInterop + { + public static void OpenFolderAndSelectItem(string path) + { + Thread thread = new Thread((ParameterizedThreadStart)(args => + { + IntPtr ppidl; + if (ShellInterop.SHParseDisplayName(path, IntPtr.Zero, out ppidl, 0, IntPtr.Zero) != 0) + return; + ShellInterop.SHOpenFolderAndSelectItems(ppidl, 0, IntPtr.Zero, 0); + ShellInterop.ILFree(ppidl); + })); + thread.TrySetApartmentState(ApartmentState.STA); + thread.Start(); + } + + [DllImport("shell32.dll", CharSet = CharSet.Auto)] + private static extern int SHParseDisplayName( + string path, + IntPtr pbc, + out IntPtr ppidl, + int sfgaoIn, + IntPtr psfgaoOut); + + [DllImport("shell32.dll")] + private static extern int SHOpenFolderAndSelectItems( + IntPtr pidl, + int cidl, + IntPtr apidl, + int dwFlags); + + [DllImport("shell32.dll")] + private static extern int ILFree(IntPtr pidl); + } +} diff --git a/ZuneUI/ShellMessagingNotifier.cs b/ZuneUI/ShellMessagingNotifier.cs new file mode 100644 index 0000000..8c4a9c4 --- /dev/null +++ b/ZuneUI/ShellMessagingNotifier.cs @@ -0,0 +1,94 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ShellMessagingNotifier +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Win32; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Messaging; +using System.Collections; + +namespace ZuneUI +{ + public class ShellMessagingNotifier : ModelItem + { + private static ShellMessagingNotifier _instance; + private MessagingNotifier _messagingNotifier; + private int _newDeviceCartItemsCount; + private int _newDeviceMessageCount; + private IList _liveMessageItems; + + public static ShellMessagingNotifier Instance + { + get + { + if (ShellMessagingNotifier._instance == null) + ShellMessagingNotifier._instance = new ShellMessagingNotifier(); + return ShellMessagingNotifier._instance; + } + } + + public static bool HasInstance => ShellMessagingNotifier._instance != null; + + private ShellMessagingNotifier() + { + this._messagingNotifier = new MessagingNotifier(); + this._messagingNotifier.OnDeviceCartItemsPosted += new DeviceItemsPostedHandler(this.OnDeviceCartItemsPostedAsync); + this._messagingNotifier.OnDeviceMessagesPosted += new DeviceItemsPostedHandler(this.OnDeviceMessagesPostedAsync); + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + this._messagingNotifier.OnDeviceMessagesPosted -= new DeviceItemsPostedHandler(this.OnDeviceMessagesPostedAsync); + this._messagingNotifier.OnDeviceCartItemsPosted -= new DeviceItemsPostedHandler(this.OnDeviceCartItemsPostedAsync); + this._messagingNotifier.Dispose(); + this._messagingNotifier = (MessagingNotifier)null; + } + base.OnDispose(disposing); + } + + public int NewDeviceCartItemsCount => this._newDeviceCartItemsCount; + + public int NewDeviceMessageCount => this._newDeviceMessageCount; + + private void OnDeviceCartItemsPostedAsync(int iNewDeviceCartItems) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnDeviceCartItemsPosted), (object)iNewDeviceCartItems); + + private void OnDeviceMessagesPostedAsync(int iNewDeviceMessages) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnDeviceMessagesPosted), (object)iNewDeviceMessages); + + private void OnDeviceCartItemsPosted(object args) + { + this._newDeviceCartItemsCount = (int)args; + this.FirePropertyChanged("NewDeviceCartItemsCount"); + } + + private void OnDeviceMessagesPosted(object args) + { + this._newDeviceMessageCount = (int)args; + this.FirePropertyChanged("NewDeviceMessageCount"); + } + + public static int PersistedCartItemsCount + { + get => ClientConfiguration.Service.GetIntProperty(string.Format("{0}", (object)ClientConfiguration.Service.LastSignedInUserGuid), 0); + set => ClientConfiguration.Service.SetIntProperty(string.Format("{0}", (object)ClientConfiguration.Service.LastSignedInUserGuid), value); + } + + public static int CartItemsToUploadCount => new MessagingUserGuidConfiguration(RegistryHive.CurrentUser, ClientConfiguration.Messaging.ConfigurationPath, string.Format("{0}", (object)ClientConfiguration.Service.LastSignedInUserGuid)).CartItemsToUploadCount; + + public IList LiveMessageItems + { + get => this._liveMessageItems; + set + { + if (this._liveMessageItems == value) + return; + this._liveMessageItems = value; + this.FirePropertyChanged(nameof(LiveMessageItems)); + } + } + } +} diff --git a/ZuneUI/SignIn.cs b/ZuneUI/SignIn.cs new file mode 100644 index 0000000..bf6ee6b --- /dev/null +++ b/ZuneUI/SignIn.cs @@ -0,0 +1,1180 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SignIn +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.ErrorMapperApi; +using Microsoft.Zune.Shell; +using Microsoft.Zune.User; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; + +namespace ZuneUI +{ + public class SignIn : ModelItem + { + private const int m_iInvalidUserId = 0; + private static SignIn s_instance; + private static object s_cs = new object(); + private static TimeSpan s_subscriptionEndingWarning = TimeSpan.FromDays(7.0); + private static TimeSpan s_subscriptionFreeTrackFirstExpireWarning = TimeSpan.FromDays(7.0); + private static TimeSpan s_subscriptionFreeTrackSecondExpireWarning = TimeSpan.FromDays(2.0); + private bool m_initialized; + private bool m_fSigningIn; + private bool m_fSignedIn; + private bool m_fSignedInWithSubscription; + private string m_strSignedInUsername; + private uint m_dwSignedInGeoId; + private int m_iLastSignedInUserId; + private string m_lastSignedInUsername; + private Guid m_lastSignedInUserGuid; + private bool m_lastSignedInUserHadActiveSubscription; + private string m_zunetag; + private string m_countryCode; + private Image m_zuneTile; + private string m_zuneTilePath; + private Guid m_userguid; + private string m_tempPasswordStorage; + private int m_pointsBalance; + private int m_subscriptionFreeTrackBalance; + private DateTime m_subscriptionFreeTrackExpiration; + private bool m_subscriptionFreeTrackExpiring; + private bool m_subscriptionFreeTrackExpiringWithinDays; + private IList m_persistedUsernames; + private string m_strErrorMessage; + private string m_strErrorWebHelpUrl; + private HRESULT m_hrError; + private bool m_fErrorTermsOfService; + private bool m_fErrorTermsOfServiceForChild; + private bool m_fRegionMismatchError; + private bool m_fErrorHttpGone; + private bool m_fErrorCredentials; + private bool m_fSubscriptionMachineCountExceeded; + private bool m_fShowLabelTakedownWarning; + private bool m_fSubscriptionAvailable; + private bool m_fSubscriptionBillingViolation; + private bool m_fSubscriptionExpiring; + private bool m_fSubscriptionExpired; + private bool m_fSubscriptionTrialsAvailable; + private bool m_fIsParentallyControlled; + private bool m_fIsLightWeight; + private bool m_noZuneAccountError; + private DateTime m_subscriptionEndDate; + private ulong m_subscriptionId; + private ulong m_subscriptionRenewalId; + private FamilySettings m_familySettings; + private Version m_maxConnectedPhoneVersion; + private Version m_maxRegisteredPhoneVersion; + private Version m_maxWindowsPhoneVersion; + private ITunerInfoHandler m_tunerHandler; + + public static SignIn Instance + { + get + { + if (SignIn.s_instance == null) + { + lock (SignIn.s_cs) + { + if (SignIn.s_instance == null) + SignIn.s_instance = new SignIn(); + } + } + return SignIn.s_instance; + } + } + + internal event EventHandler SignInStatusUpdatedEvent; + + public bool Initialized + { + get => this.m_initialized; + private set + { + if (this.m_initialized == value) + return; + this.m_initialized = value; + this.FirePropertyChanged(nameof(Initialized)); + } + } + + public bool SigningIn + { + get => this.m_fSigningIn; + set + { + if (this.m_fSigningIn == value) + return; + this.m_fSigningIn = value; + this.FirePropertyChanged(nameof(SigningIn)); + } + } + + public bool SignedIn + { + get => this.m_fSignedIn; + set + { + if (this.m_fSignedIn == value) + return; + this.m_fSignedIn = value; + this.FirePropertyChanged(nameof(SignedIn)); + } + } + + public bool SignedInWithSubscription + { + get => this.m_fSignedInWithSubscription; + set + { + if (this.m_fSignedInWithSubscription == value) + return; + this.m_fSignedInWithSubscription = value; + this.FirePropertyChanged(nameof(SignedInWithSubscription)); + } + } + + public string SignedInUsername + { + get => this.m_strSignedInUsername; + set + { + if (!(this.m_strSignedInUsername != value)) + return; + this.m_strSignedInUsername = value; + this.FirePropertyChanged(nameof(SignedInUsername)); + } + } + + public uint SignedInGeoId + { + get => this.m_dwSignedInGeoId; + set + { + if ((int)this.m_dwSignedInGeoId == (int)value) + return; + this.m_dwSignedInGeoId = value; + this.FirePropertyChanged(nameof(SignedInGeoId)); + } + } + + public int LastSignedInUserId + { + get + { + this.GetLastSignedIdUser(); + return this.m_iLastSignedInUserId; + } + set + { + if (this.m_iLastSignedInUserId == value) + return; + this.m_iLastSignedInUserId = value; + this.FirePropertyChanged(nameof(LastSignedInUserId)); + } + } + + public string LastSignedInUsername + { + get + { + if (this.m_lastSignedInUsername == null && this.LastSignedInUserId > 0) + this.m_lastSignedInUsername = SignIn.GetPassportIdFromUserId(this.LastSignedInUserId); + return this.m_lastSignedInUsername; + } + private set + { + if (!(this.m_lastSignedInUsername != value)) + return; + this.m_lastSignedInUsername = value; + this.FirePropertyChanged(nameof(LastSignedInUsername)); + } + } + + public Guid LastSignedInUserGuid + { + get + { + this.GetLastSignedIdUser(); + return this.m_lastSignedInUserGuid; + } + set + { + if (!(this.m_lastSignedInUserGuid != value)) + return; + this.m_lastSignedInUserGuid = value; + this.FirePropertyChanged(nameof(LastSignedInUserGuid)); + } + } + + public bool LastSignedInUserHadActiveSubscription + { + get => this.m_lastSignedInUserHadActiveSubscription; + private set + { + if (this.m_lastSignedInUserHadActiveSubscription == value) + return; + this.m_lastSignedInUserHadActiveSubscription = value; + this.FirePropertyChanged(nameof(LastSignedInUserHadActiveSubscription)); + } + } + + public Image ZuneTile + { + get => this.m_zuneTile; + set + { + if (this.m_zuneTile == value) + return; + this.m_zuneTile = value; + this.FirePropertyChanged(nameof(ZuneTile)); + } + } + + public string ZuneTag + { + get => this.m_zunetag; + set + { + if (!(this.m_zunetag != value)) + return; + this.m_zunetag = value; + this.FirePropertyChanged(nameof(ZuneTag)); + } + } + + public string CountryCode + { + get => this.m_countryCode; + set + { + if (!(this.m_countryCode != value)) + return; + this.m_countryCode = value; + this.FirePropertyChanged(nameof(CountryCode)); + } + } + + public Guid UserGuid + { + get => this.m_userguid; + set + { + if (!(this.m_userguid != value)) + return; + this.m_userguid = value; + this.FirePropertyChanged(nameof(UserGuid)); + } + } + + public string TempPasswordStorage + { + get => this.m_tempPasswordStorage; + set + { + if (!(this.m_tempPasswordStorage != value)) + return; + this.m_tempPasswordStorage = value; + this.FirePropertyChanged(nameof(TempPasswordStorage)); + } + } + + public int PointsBalance + { + get + { + this.UpdatePointsBalance(); + return this.m_pointsBalance; + } + } + + private void UpdatePointsBalance() + { + int pointsBalance = ZuneApplication.Service.GetPointsBalance(); + if (pointsBalance == this.m_pointsBalance) + return; + this.m_pointsBalance = pointsBalance; + this.FirePropertyChanged("PointsBalance"); + } + + public DateTime SubscriptionFreeTrackExpiration + { + get + { + this.UpdateSubscriptionFreeTrackExpiration(); + return this.m_subscriptionFreeTrackExpiration; + } + private set + { + if (!(this.m_subscriptionFreeTrackExpiration != value)) + return; + this.m_subscriptionFreeTrackExpiration = value; + this.FirePropertyChanged(nameof(SubscriptionFreeTrackExpiration)); + } + } + + public bool SubscriptionFreeTrackExpiring + { + get => this.m_subscriptionFreeTrackExpiring; + private set + { + if (this.m_subscriptionFreeTrackExpiring == value) + return; + this.m_subscriptionFreeTrackExpiring = value; + this.FirePropertyChanged(nameof(SubscriptionFreeTrackExpiring)); + } + } + + public bool SubscriptionFreeTrackExpiringWithinDays + { + get => this.m_subscriptionFreeTrackExpiringWithinDays; + private set + { + if (this.m_subscriptionFreeTrackExpiringWithinDays == value) + return; + this.m_subscriptionFreeTrackExpiringWithinDays = value; + this.FirePropertyChanged(nameof(SubscriptionFreeTrackExpiringWithinDays)); + } + } + + public int SubscriptionFreeTrackBalance + { + get + { + this.UpdateSubscriptionFreeTrackBalance(); + return this.m_subscriptionFreeTrackBalance; + } + private set + { + if (this.m_subscriptionFreeTrackBalance == value) + return; + this.m_subscriptionFreeTrackBalance = value; + this.FirePropertyChanged(nameof(SubscriptionFreeTrackBalance)); + } + } + + public void UpdateSubscriptionFreeTrackBalance() => this.SubscriptionFreeTrackBalance = ZuneApplication.Service.GetSubscriptionFreeTrackBalance(); + + public IList PersistedUsernames + { + get + { + if (this.m_persistedUsernames == null) + this.m_persistedUsernames = ZuneApplication.Service.GetPersistedUsernames(); + return this.m_persistedUsernames; + } + set + { + if (this.m_persistedUsernames == value) + return; + this.m_persistedUsernames = value; + this.FirePropertyChanged(nameof(PersistedUsernames)); + } + } + + public bool SubscriptionMachineCountExceeded + { + get => this.m_fSubscriptionMachineCountExceeded; + private set + { + if (this.m_fSubscriptionMachineCountExceeded == value) + return; + this.m_fSubscriptionMachineCountExceeded = value; + this.FirePropertyChanged(nameof(SubscriptionMachineCountExceeded)); + } + } + + public bool ShowLabelTakedownWarning + { + get => this.m_fShowLabelTakedownWarning; + private set + { + if (this.m_fShowLabelTakedownWarning == value) + return; + this.m_fShowLabelTakedownWarning = value; + this.FirePropertyChanged(nameof(ShowLabelTakedownWarning)); + } + } + + public bool SubscriptionBillingViolation + { + get => this.m_fSubscriptionBillingViolation; + private set + { + if (this.m_fSubscriptionBillingViolation == value) + return; + this.m_fSubscriptionBillingViolation = value; + this.FirePropertyChanged(nameof(SubscriptionBillingViolation)); + } + } + + public bool SubscriptionAvailable + { + get => this.m_fSubscriptionAvailable; + private set + { + if (this.m_fSubscriptionAvailable == value) + return; + this.m_fSubscriptionAvailable = value; + this.FirePropertyChanged(nameof(SubscriptionAvailable)); + } + } + + public bool SubscriptionTrialsAvailable + { + get => this.m_fSubscriptionTrialsAvailable; + private set + { + if (this.m_fSubscriptionTrialsAvailable == value) + return; + this.m_fSubscriptionTrialsAvailable = value; + this.FirePropertyChanged(nameof(SubscriptionTrialsAvailable)); + } + } + + public HRESULT SignInError + { + get => this.m_hrError; + private set + { + if (!(this.m_hrError != value)) + return; + this.m_hrError = value; + this.FirePropertyChanged(nameof(SignInError)); + } + } + + public string SignInErrorMessage + { + get => this.m_strErrorMessage; + set + { + if (!(this.m_strErrorMessage != value)) + return; + this.m_strErrorMessage = value; + this.FirePropertyChanged(nameof(SignInErrorMessage)); + } + } + + public string SignInErrorWebHelpUrl + { + get => this.m_strErrorWebHelpUrl; + set + { + if (!(this.m_strErrorWebHelpUrl != value)) + return; + this.m_strErrorWebHelpUrl = value; + this.FirePropertyChanged(nameof(SignInErrorWebHelpUrl)); + } + } + + public bool SignInTermsOfServiceError + { + get => this.m_fErrorTermsOfService; + set + { + if (this.m_fErrorTermsOfService == value) + return; + this.m_fErrorTermsOfService = value; + this.FirePropertyChanged(nameof(SignInTermsOfServiceError)); + } + } + + public bool SignInRegionMismatchError + { + get => this.m_fRegionMismatchError; + set + { + if (this.m_fRegionMismatchError == value) + return; + this.m_fRegionMismatchError = value; + this.FirePropertyChanged(nameof(SignInRegionMismatchError)); + } + } + + public bool SignInTermsOfServiceErrorForChild + { + get => this.m_fErrorTermsOfServiceForChild; + set + { + if (this.m_fErrorTermsOfServiceForChild == value) + return; + this.m_fErrorTermsOfServiceForChild = value; + this.FirePropertyChanged(nameof(SignInTermsOfServiceErrorForChild)); + } + } + + public bool SignInHttpGoneError + { + get => this.m_fErrorHttpGone; + set + { + if (this.m_fErrorHttpGone == value) + return; + this.m_fErrorHttpGone = value; + this.FirePropertyChanged(nameof(SignInHttpGoneError)); + } + } + + public bool SignInCredentialsError + { + get => this.m_fErrorCredentials; + set + { + if (this.m_fErrorCredentials == value) + return; + this.m_fErrorCredentials = value; + this.FirePropertyChanged(nameof(SignInCredentialsError)); + } + } + + public bool SignInNoZuneAccountError + { + get => this.m_noZuneAccountError; + private set + { + if (this.m_noZuneAccountError == value) + return; + this.m_noZuneAccountError = value; + this.FirePropertyChanged(nameof(SignInNoZuneAccountError)); + } + } + + public bool IsParentallyControlled + { + get => this.m_fIsParentallyControlled; + private set + { + if (this.m_fIsParentallyControlled == value) + return; + this.m_fIsParentallyControlled = value; + this.FirePropertyChanged(nameof(IsParentallyControlled)); + } + } + + public bool IsLightWeight + { + get => this.m_fIsLightWeight; + private set + { + if (this.m_fIsLightWeight == value) + return; + this.m_fIsLightWeight = value; + this.FirePropertyChanged(nameof(IsLightWeight)); + } + } + + public bool SubscriptionExpiring + { + get => this.m_fSubscriptionExpiring; + private set + { + if (this.m_fSubscriptionExpiring == value) + return; + this.m_fSubscriptionExpiring = value; + this.FirePropertyChanged(nameof(SubscriptionExpiring)); + } + } + + public bool SubscriptionExpired + { + get => this.m_fSubscriptionExpired; + private set + { + if (this.m_fSubscriptionExpired == value) + return; + this.m_fSubscriptionExpired = value; + this.FirePropertyChanged(nameof(SubscriptionExpired)); + } + } + + public DateTime SubscriptionEndDate + { + get => this.m_subscriptionEndDate; + private set + { + if (!(this.m_subscriptionEndDate != value)) + return; + this.m_subscriptionEndDate = value; + this.FirePropertyChanged("SubscriptionExpired"); + this.FirePropertyChanged("SubscriptionHasEndDate"); + } + } + + public ulong SubscriptionId + { + get => this.m_subscriptionId; + private set + { + if ((long)this.m_subscriptionId == (long)value) + return; + this.m_subscriptionId = value; + this.FirePropertyChanged(nameof(SubscriptionId)); + this.FirePropertyChanged("HasSubscriptionId"); + } + } + + public bool HasSubscriptionId => this.m_subscriptionId != 0UL; + + public ulong SubscriptionRenewalId + { + get => this.m_subscriptionRenewalId; + private set + { + if ((long)this.m_subscriptionRenewalId == (long)value) + return; + this.m_subscriptionRenewalId = value; + this.FirePropertyChanged(nameof(SubscriptionRenewalId)); + } + } + + public bool SubscriptionHasEndDate => this.m_subscriptionEndDate != DateTime.MaxValue && this.m_subscriptionEndDate.Year < 9999; + + private Version MaxWindowsPhoneVersion + { + get => this.m_maxWindowsPhoneVersion; + set + { + if (!(this.m_maxWindowsPhoneVersion != value)) + return; + this.m_maxWindowsPhoneVersion = value; + this.FirePropertyChanged("WindowsPhoneClientType"); + } + } + + private void UpdateMaxWindowsPhoneVersion() + { + if (this.MaxConnectedPhoneVersion == (Version)null) + this.MaxWindowsPhoneVersion = this.MaxRegisteredPhoneVersion; + else if (this.MaxRegisteredPhoneVersion == (Version)null) + this.MaxWindowsPhoneVersion = this.MaxConnectedPhoneVersion; + else + this.MaxWindowsPhoneVersion = this.MaxRegisteredPhoneVersion > this.MaxConnectedPhoneVersion ? this.MaxRegisteredPhoneVersion : this.MaxConnectedPhoneVersion; + } + + private Version MaxConnectedPhoneVersion + { + get => this.m_maxConnectedPhoneVersion; + set + { + if (!(this.m_maxConnectedPhoneVersion != value)) + return; + this.m_maxConnectedPhoneVersion = value; + this.UpdateMaxWindowsPhoneVersion(); + } + } + + private Version MaxRegisteredPhoneVersion + { + get => this.m_maxRegisteredPhoneVersion; + set + { + if (!(this.m_maxRegisteredPhoneVersion != value)) + return; + this.m_maxRegisteredPhoneVersion = value; + this.UpdateMaxWindowsPhoneVersion(); + } + } + + public string WindowsPhoneClientType => this.GetWindowsPhoneClientType(this.MaxWindowsPhoneVersion); + + private string GetWindowsPhoneClientType(Version phoneVersion) + { + string strPhoneOsVersion = string.Empty; + if (phoneVersion != (Version)null) + strPhoneOsVersion = string.Format("{0}.{1}", (object)phoneVersion.Major, (object)phoneVersion.Minor); + return Microsoft.Zune.Service.Service.Instance.GetPhoneClientType(strPhoneOsVersion); + } + + public void CheckConnectedPhoneForNewerFirmware() + { + this.MaxConnectedPhoneVersion = this.GetConnectedPhoneFirmwareVersion(); + this.UpdateMaxWindowsPhoneVersion(); + } + + private Version GetConnectedPhoneFirmwareVersion() + { + Version version = (Version)null; + UIDevice connectedPaidAppDevice = ApplicationMarketplaceHelper.FindConnectedPaidAppDevice(); + if (connectedPaidAppDevice != UIDeviceList.NullDevice && connectedPaidAppDevice.Class == DeviceClass.WindowsPhone) + { + if (!string.IsNullOrEmpty(connectedPaidAppDevice.FirmwareVersion)) + { + try + { + version = new Version(connectedPaidAppDevice.FirmwareVersion.Split('-')[0]); + } + catch + { + } + } + } + return version; + } + + private ITunerInfoHandler TunerHandler + { + get + { + if (this.m_tunerHandler == null) + { + this.m_tunerHandler = TunerInfoHandlerFactory.CreateTunerInfoHandler(); + this.m_tunerHandler.OnChanged += new EventHandler(this.OnTunerInfoChanged); + } + return this.m_tunerHandler; + } + } + + private void OnTunerInfoChanged(object oSenderUNUSED, EventArgs eargs) => Application.DeferredInvoke(new DeferredInvokeHandler(this.UpdatedAssociatedPhoneVersion), DeferredInvokePriority.Normal); + + private void UpdatedAssociatedPhoneVersion(object argsUNUSED) + { + Version version1 = (Version)null; + foreach (Microsoft.Zune.Configuration.TunerInfo appStoreDevices in (IEnumerable)this.TunerHandler.GetAppStoreDevicesList()) + { + if (appStoreDevices.TunerType == TunerType.MobileDevice) + { + Version version2 = new Version(appStoreDevices.TunerVersion); + if (version1 == (Version)null || version2 > version1) + version1 = version2; + } + } + this.MaxRegisteredPhoneVersion = version1; + this.MaxConnectedPhoneVersion = this.GetConnectedPhoneFirmwareVersion(); + this.UpdateMaxWindowsPhoneVersion(); + } + + public bool PasswordRequired(string strUsername) => ZuneApplication.Service.SignInPasswordRequired(strUsername); + + public bool SignInAtStartup(string strUsername) => ZuneApplication.Service.SignInAtStartup(strUsername); + + public bool RememberUsername(string strUsername) + { + bool flag = this.PersistedUsernames != null && this.PersistedUsernames.Contains((object)strUsername); + if (!flag) + flag = !this.PasswordRequired(strUsername); + return flag; + } + + public void RefreshAccount() + { + if (!ZuneApplication.Service.IsSignedIn()) + return; + ZuneApplication.Service.RefreshAccount(new AsyncCompleteHandler(this.OnManualSignIn)); + } + + public void SignInUser(string strUsername, string strPassword) + { + bool fRememberUsername = this.RememberUsername(strUsername); + bool fRememberPassword = !this.PasswordRequired(strUsername); + bool fSignInAtStartup = this.SignInAtStartup(strUsername); + this.SignInUser(strUsername, strPassword, fRememberUsername, fRememberPassword, fSignInAtStartup); + } + + public void SignInUser( + string strUsername, + string strPassword, + bool fRememberUsername, + bool fRememberPassword, + bool fSignInAtStartup) + { + if (this.SigningIn) + ZuneApplication.Service.CancelSignIn(); + else if (this.SignedIn) + ZuneApplication.Service.SignOut(); + if (strPassword == null || strPassword == this.PseudoPassword) + strPassword = string.Empty; + ZuneApplication.Service.SignIn(strUsername, strPassword, fRememberUsername, fRememberPassword, fSignInAtStartup, new AsyncCompleteHandler(this.OnManualSignIn)); + this.UpdateState(); + } + + public void SwitchToUser(string strUsername) + { + Guid guidFromPassportId = SignIn.GetGuidFromPassportId(strUsername); + int iUserId = 0; + if (!ZuneApplication.Service.SetLastSignedInUserGuid(ref guidFromPassportId, out iUserId)) + return; + if (this.SigningIn) + ZuneApplication.Service.CancelSignIn(); + else if (this.SignedIn) + ZuneApplication.Service.SignOut(); + this.LastSignedInUserId = iUserId; + this.LastSignedInUserGuid = guidFromPassportId; + this.UpdateState(); + } + + public void CancelSignIn() + { + ZuneApplication.Service.CancelSignIn(); + this.UpdateState(); + } + + public void SignOut() => this.SignOut(false); + + private void SignOut(bool forget) + { + ZuneApplication.Service.SignOut(); + if (forget) + this.ClearLastSignedIdUser(); + this.UpdateState(); + } + + public string PseudoPassword => "********"; + + public void RemovePersistedUsername(string persistedUsername) + { + ZuneApplication.Service.RemovePersistedUsername(persistedUsername); + int idFromPassportId = SignIn.GetUserIdFromPassportId(persistedUsername); + if (idFromPassportId > 0) + UserManager.Instance.CleanupUserData(idFromPassportId); + this.PersistedUsernames = (IList)null; + if (!SignIn.TagsMatch(this.ZuneTag, SignIn.GetZuneTagFromPassportId(persistedUsername))) + return; + this.SignOut(true); + } + + public static bool TagsMatch(string zuneTag1, string zuneTag2) => StringHelper.CaseInsensitiveCompare(zuneTag1, zuneTag2); + + public static bool LiveIdsMatch(string liveId1, string liveId2) => StringHelper.CaseInsensitiveCompare(liveId1, liveId2); + + public bool IsSignedInUser(string zuneTag) => this.SignedIn && SignIn.TagsMatch(zuneTag, this.m_zunetag); + + public bool IsSignedInLiveId(string liveId) => this.SignedIn && SignIn.LiveIdsMatch(liveId, this.SignedInUsername); + + public bool IsLastSignedInLiveId(string liveId) => SignIn.LiveIdsMatch(liveId, this.LastSignedInUsername); + + private static object GetUserFieldValues( + int userId, + SchemaMap columnIndex, + object defaultValue) + { + object obj = (object)null; + if (userId > 0) + { + int[] columnIndexes = new int[1] + { + (int) columnIndex + }; + object[] fieldValues = new object[1] { defaultValue }; + if (ZuneLibrary.GetFieldValues(userId, EListType.eUserList, columnIndexes.Length, columnIndexes, fieldValues, PlaylistManager.Instance.QueryContext).IsSuccess) + obj = fieldValues[0]; + } + return obj; + } + + public FamilySettings FamilySettings + { + get + { + if (this.SignedIn) + { + if (this.m_familySettings == null) + this.m_familySettings = new FamilySettings(this.LastSignedInUserId); + } + else + this.m_familySettings = (FamilySettings)null; + return this.m_familySettings; + } + private set + { + this.m_familySettings = value; + this.FirePropertyChanged(nameof(FamilySettings)); + } + } + + public static string GetPassportIdFromUserId(int userId) => SignIn.GetUserFieldValues(userId, SchemaMap.kiIndex_PassportID, (object)string.Empty) as string; + + public static Guid GetGuidFromPassportId(string passportId) => SignIn.GetGuidFromUserId(SignIn.GetUserIdFromPassportId(passportId)); + + public static Guid GetGuidFromUserId(int userId) => SignIn.GetUserFieldValues(userId, SchemaMap.kiIndex_ZuneMediaID, (object)Guid.Empty) is Guid userFieldValues ? userFieldValues : Guid.Empty; + + public static int GetUserIdFromPassportId(string passportId) + { + int userId = 0; + if (!string.IsNullOrEmpty(passportId) && new HRESULT(UserManager.Instance.FindUserByPassportId(passportId, out userId)).IsError) + userId = 0; + return userId; + } + + public static string GetZuneTagFromPassportId(string passportId) => SignIn.GetZuneTagFromUserId(SignIn.GetUserIdFromPassportId(passportId)); + + public static string GetZuneTagFromUserId(int userId) => SignIn.GetUserFieldValues(userId, SchemaMap.kiIndex_ZuneTag, (object)string.Empty) as string; + + public static string GetImagePathFromPassportId(string passportId) => SignIn.GetImagePathFromUserId(SignIn.GetUserIdFromPassportId(passportId)); + + public static string GetImagePathFromUserId(int userId) + { + string str = SignIn.GetUserFieldValues(userId, SchemaMap.kiIndex_ArtUrl, (object)string.Empty) as string; + if (!string.IsNullOrEmpty(str) && !str.StartsWith("file://")) + str = "file://" + str; + return str; + } + + public static Image GetImageFromPassportId(string passportId) => SignIn.GetImageFromUserId(SignIn.GetUserIdFromPassportId(passportId)); + + public static Image GetImageFromUserId(int userId) + { + Image image = (Image)null; + string imagePathFromUserId = SignIn.GetImagePathFromUserId(userId); + if (!string.IsNullOrEmpty(imagePathFromUserId)) + { + bool antialiasEdges = Application.RenderingType != RenderingType.GDI; + image = new Image(imagePathFromUserId, ProfileImage.DefaultTileSize.Width, ProfileImage.DefaultTileSize.Height, false, antialiasEdges); + } + return image; + } + + public static void ErrorMessageRegionInvalid() => ErrorDialogInfo.Show(HRESULT._NS_E_SIGNIN_INVALID_REGION.Int, ZuneUI.Shell.LoadString(StringId.IDS_SIGNIN_REGION_INVALID_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_SIGNIN_REGION_INVALID_MESSAGE)); + + internal void SetError(HRESULT hrError) + { + ErrorMapperResult descriptionAndUrl = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hrError.Int, eErrorCondition.eEC_SignIn); + this.SignInTermsOfServiceErrorForChild = HRESULT._ZUNE_E_SIGNIN_TERMS_OF_SERVICE_CHILD == (HRESULT)descriptionAndUrl.Hr; + this.SignInTermsOfServiceError = HRESULT._NS_E_SIGNIN_TERMS_OF_SERVICE == (HRESULT)descriptionAndUrl.Hr; + this.SignInRegionMismatchError = HRESULT._NS_E_SIGNIN_INVALID_REGION == (HRESULT)descriptionAndUrl.Hr; + this.SignInHttpGoneError = HRESULT._NS_E_SIGNIN_HTTP_GONE == (HRESULT)descriptionAndUrl.Hr; + this.SignInCredentialsError = HRESULT._NS_E_SERVER_ACCESSDENIED == (HRESULT)descriptionAndUrl.Hr || HRESULT._NS_E_PASSPORT_LOGIN_FAILED == (HRESULT)descriptionAndUrl.Hr || HRESULT._NS_E_SUBSCRIPTIONSERVICE_LOGIN_FAILED == (HRESULT)descriptionAndUrl.Hr || HRESULT._NS_E_INVALID_USERNAME_AND_PASSWORD == (HRESULT)descriptionAndUrl.Hr; + this.SignInNoZuneAccountError = HRESULT._ZEST_E_UNAUTHENTICATED == (HRESULT)descriptionAndUrl.Hr; + this.SignInError = (HRESULT)descriptionAndUrl.Hr; + this.SignInErrorMessage = this.SignInTermsOfServiceError || this.SignInTermsOfServiceErrorForChild ? (string)null : descriptionAndUrl.Description; + this.SignInErrorWebHelpUrl = this.SignInTermsOfServiceError || this.SignInTermsOfServiceErrorForChild ? (string)null : descriptionAndUrl.WebHelpUrl; + this.SigningIn = false; + if (this.SignInStatusUpdatedEvent == null) + return; + this.SignInStatusUpdatedEvent((object)this, EventArgs.Empty); + } + + internal void UpdateState() + { + this.SubscriptionMachineCountExceeded = ZuneApplication.Service.IsSignedInWithSubscription() && !ZuneApplication.Service.CanDownloadSubscriptionContent(); + this.SubscriptionBillingViolation = ZuneApplication.Service.IsSignedInWithSubscription() && ZuneApplication.Service.HasSignInBillingViolation(); + this.ShowLabelTakedownWarning = ZuneApplication.Service.HasSignInLabelTakedown(); + this.SignedIn = ZuneApplication.Service.IsSignedIn(); + this.SigningIn = !this.SignedIn && ZuneApplication.Service.IsSigningIn(); + this.SignedInUsername = ZuneApplication.Service.GetSignedInUsername(); + this.SignedInGeoId = ZuneApplication.Service.GetSignedInGeoId(); + this.SignInErrorMessage = (string)null; + this.SignInErrorWebHelpUrl = (string)null; + this.SignInError = HRESULT._S_OK; + this.SignInTermsOfServiceError = false; + this.SignInTermsOfServiceErrorForChild = false; + this.SignInRegionMismatchError = false; + this.SignInHttpGoneError = false; + this.SignInCredentialsError = false; + this.SignInNoZuneAccountError = false; + this.UserGuid = (Guid)ZuneApplication.Service.GetUserGuid(); + this.UpdatePointsBalance(); + this.UpdateSubscriptionFreeTrackBalance(); + this.UpdateSubscriptionFreeTrackExpiration(); + this.FamilySettings = (FamilySettings)null; + this.LastSignedInUsername = (string)null; + this.CountryCode = (string)null; + if (this.SignedIn) + { + int iUserId; + Guid guidUserGuid; + ZuneApplication.Service.GetLastSignedInUserGuid(out iUserId, out guidUserGuid); + this.LastSignedInUserId = iUserId; + this.LastSignedInUserGuid = guidUserGuid; + this.ZuneTag = ZuneApplication.Service.GetZuneTag(); + this.IsParentallyControlled = ZuneApplication.Service.IsParentallyControlled(); + this.IsLightWeight = ZuneApplication.Service.IsLightWeight(); + string locale = ZuneApplication.Service.GetLocale(); + if (!string.IsNullOrEmpty(locale)) + { + string[] strArray = locale.Split('-'); + if (strArray.Length >= 2) + this.CountryCode = strArray[1]; + } + this.PersistedUsernames = (IList)null; + if (this.TunerHandler.CanQueryTunerList()) + this.TunerHandler.RefreshTunerList(); + } + else + { + this.ZuneTag = SignIn.GetZuneTagFromUserId(this.LastSignedInUserId); + this.IsParentallyControlled = false; + this.IsLightWeight = false; + this.MaxRegisteredPhoneVersion = (Version)null; + this.MaxConnectedPhoneVersion = this.GetConnectedPhoneFirmwareVersion(); + this.UpdateMaxWindowsPhoneVersion(); + } + this.UpdateSubscriptionState(); + this.UpdateStateAsyncStart(); + if (this.SignInStatusUpdatedEvent != null) + this.SignInStatusUpdatedEvent((object)this, EventArgs.Empty); + this.Initialized = true; + } + + private void UpdateStateAsyncStart() => ThreadPool.QueueUserWorkItem(new WaitCallback(this.UpdateStateAsync), (object)new object[3] + { + (object) this.m_zuneTile, + (object) this.m_zuneTilePath, + (object) this.LastSignedInUserId + }); + + private void UpdateStateAsync(object args) + { + object[] objArray = (object[])args; + Image image1 = objArray[0] as Image; + string str = objArray[1] as string; + string imagePathFromUserId = SignIn.GetImagePathFromUserId((int)objArray[2]); + Image image2 = image1; + if (imagePathFromUserId != str) + { + if (!string.IsNullOrEmpty(imagePathFromUserId)) + { + bool antialiasEdges = Application.RenderingType != RenderingType.GDI; + image2 = new Image(imagePathFromUserId, ProfileImage.DefaultTileSize.Width, ProfileImage.DefaultTileSize.Height, false, antialiasEdges); + } + else + image2 = (Image)null; + } + objArray[0] = (object)image2; + objArray[1] = (object)imagePathFromUserId; + Application.DeferredInvoke(new DeferredInvokeHandler(this.UpdateStateAsyncEnd), (object)objArray, DeferredInvokePriority.Low); + } + + private void UpdateStateAsyncEnd(object args) + { + object[] objArray = (object[])args; + this.ZuneTile = objArray[0] as Image; + this.m_zuneTilePath = objArray[1] as string; + } + + private void UpdateSubscriptionFreeTrackExpiration() + { + bool flag1 = false; + bool flag2 = false; + DateTime dateTime1 = DateTime.MaxValue; + DateTime maxValue1 = DateTime.MaxValue; + DateTime maxValue2 = DateTime.MaxValue; + if (this.SignedIn) + { + dateTime1 = ZuneApplication.Service.GetSubscriptionFreeTrackExpiration(); + DateTime dateTime2 = !(dateTime1 >= DateTime.MinValue.Add(SignIn.s_subscriptionFreeTrackFirstExpireWarning)) ? DateTime.MinValue : dateTime1.Subtract(SignIn.s_subscriptionFreeTrackFirstExpireWarning); + DateTime dateTime3 = !(dateTime1 >= DateTime.MinValue.Add(SignIn.s_subscriptionFreeTrackSecondExpireWarning)) ? DateTime.MinValue : dateTime1.Subtract(SignIn.s_subscriptionFreeTrackSecondExpireWarning); + flag1 = dateTime2 <= DateTime.UtcNow; + flag2 = dateTime3 <= DateTime.UtcNow; + } + this.SubscriptionFreeTrackExpiration = dateTime1; + this.SubscriptionFreeTrackExpiring = flag1; + this.SubscriptionFreeTrackExpiringWithinDays = flag2; + } + + private void UpdateSubscriptionState() + { + bool flag1 = false; + bool flag2 = false; + DateTime dateTime = DateTime.MaxValue; + this.SignedInWithSubscription = ZuneApplication.Service.IsSignedInWithSubscription(); + if (this.SignedIn) + { + this.LastSignedInUserHadActiveSubscription = this.SignedInWithSubscription; + this.SubscriptionEndDate = ZuneApplication.Service.GetSubscriptionEndDate(); + this.SubscriptionId = ZuneApplication.Service.GetSubscriptionOfferId(); + this.SubscriptionRenewalId = ZuneApplication.Service.GetSubscriptionRenewalOfferId(); + if (ZuneApplication.Service.SubscriptionPendingCancel() || this.SubscriptionRenewalId == 0UL) + { + dateTime = !(this.SubscriptionEndDate >= DateTime.MinValue.Add(SignIn.s_subscriptionEndingWarning)) ? DateTime.MinValue : this.SubscriptionEndDate.Subtract(SignIn.s_subscriptionEndingWarning); + flag1 = !this.SignedInWithSubscription && this.SubscriptionHasEndDate && this.SubscriptionEndDate <= DateTime.Today; + flag2 = this.SignedInWithSubscription && this.SubscriptionHasEndDate && this.SubscriptionEndDate >= DateTime.Today; + } + } + else + { + bool activeSubscription; + ulong subscriptionId; + ZuneApplication.Service.GetLastSignedInUserSubscriptionState(out activeSubscription, out subscriptionId); + this.LastSignedInUserHadActiveSubscription = activeSubscription; + this.SubscriptionId = subscriptionId; + this.SubscriptionEndDate = DateTime.MaxValue; + this.SubscriptionRenewalId = 0UL; + } + this.SubscriptionExpired = flag1; + this.SubscriptionExpiring = flag2; + this.SubscriptionTrialsAvailable = !this.SignedInWithSubscription && this.SubscriptionId == 0UL && FeatureEnablement.IsFeatureEnabled(Features.eSubscriptionTrial); + this.SubscriptionAvailable = !this.SignedInWithSubscription && FeatureEnablement.IsFeatureEnabled(Features.eSubscription); + if (!this.SubscriptionExpired && (!this.SubscriptionExpiring || !(dateTime <= DateTime.Today))) + return; + SubscriptionEndingDialog.Show(this.SubscriptionEndDate); + } + + public void UpdateUserTile() + { + if (this.LastSignedInUserId <= 0) + return; + string imagePathFromUserId = SignIn.GetImagePathFromUserId(this.LastSignedInUserId); + if (!string.IsNullOrEmpty(imagePathFromUserId)) + { + bool antialiasEdges = Application.RenderingType != RenderingType.GDI; + Image.RemoveCache(imagePathFromUserId, ProfileImage.DefaultTileSize.Height, ProfileImage.DefaultTileSize.Width, false, antialiasEdges); + } + UserManager.Instance.RefreshUserTile(this.LastSignedInUserId); + } + + public void OnManualSignIn(HRESULT hr) + { + if (hr.IsSuccess || hr == HRESULT._E_ABORT) + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredUpdateStatus), (object)null); + else + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetError), (object)hr); + } + + public void OnAutomaticSignIn(HRESULT hr) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredUpdateStatus), (object)null); + + private void DeferredUpdateStatus(object args) => this.UpdateState(); + + private void DeferredSetError(object args) => this.SetError((HRESULT)args); + + internal void Phase3Init() + { + if (this.AutomaticSignIn()) + return; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.UpdateState(); + }, DeferredInvokePriority.Low); + } + + private bool AutomaticSignIn() + { + bool flag = false; + string atStartupUsername = ZuneApplication.Service.GetSignInAtStartupUsername(); + if (atStartupUsername != null) + { + flag = true; + ZuneApplication.Service.SignIn(atStartupUsername, "", true, true, true, new AsyncCompleteHandler(this.OnAutomaticSignIn)); + } + return flag; + } + + private SignIn() + { + this.m_iLastSignedInUserId = 0; + this.m_lastSignedInUserGuid = Guid.Empty; + } + + private void GetLastSignedIdUser() + { + if (!(this.m_lastSignedInUserGuid == Guid.Empty) && this.m_iLastSignedInUserId != 0) + return; + ZuneApplication.Service.GetLastSignedInUserGuid(out this.m_iLastSignedInUserId, out this.m_lastSignedInUserGuid); + } + + private void ClearLastSignedIdUser() + { + if (!ZuneApplication.Service.ClearLastSignedInUser()) + return; + this.m_lastSignedInUserGuid = Guid.Empty; + this.m_iLastSignedInUserId = 0; + } + } +} diff --git a/ZuneUI/SingletonModelItem`1.cs b/ZuneUI/SingletonModelItem`1.cs new file mode 100644 index 0000000..5849642 --- /dev/null +++ b/ZuneUI/SingletonModelItem`1.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SingletonModelItem`1 +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public abstract class SingletonModelItem : ModelItem where T : SingletonModelItem, new() + { + private static T _singletonInstance; + + protected SingletonModelItem() + : this((IModelItemOwner)ZuneShell.DefaultInstance) + { + } + + protected SingletonModelItem(IModelItemOwner parent) + : base(parent) + { + } + + public static T Instance + { + get + { + if ((object)SingletonModelItem._singletonInstance == null) + SingletonModelItem._singletonInstance = new T(); + return SingletonModelItem._singletonInstance; + } + } + } +} diff --git a/ZuneUI/SlideShowState.cs b/ZuneUI/SlideShowState.cs new file mode 100644 index 0000000..18648a0 --- /dev/null +++ b/ZuneUI/SlideShowState.cs @@ -0,0 +1,129 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SlideShowState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class SlideShowState : ModelItem + { + private int _index; + private string _sort; + private bool _play; + private bool _canPlay; + private bool _usePhotoIds; + private bool _startWithFirstPhotoId; + private Command _navigate; + private int _folderId; + private List _photoIds; + + public SlideShowState(IModelItemOwner owner) + : base(owner) + { + this._navigate = new Command((IModelItemOwner)this); + this._photoIds = new List(); + } + + public int Index + { + get => this._index; + set + { + if (this._index == value) + return; + this._index = value; + this.FirePropertyChanged(nameof(Index)); + } + } + + public string Sort + { + get => this._sort; + set + { + if (!(this._sort != value)) + return; + this._sort = value; + this.FirePropertyChanged(nameof(Sort)); + } + } + + public bool Play + { + get => this._play; + set + { + if (this._play == value) + return; + this._play = value; + this.FirePropertyChanged(nameof(Play)); + } + } + + public bool CanPlay + { + get => this._canPlay; + set + { + if (this._canPlay == value) + return; + this._canPlay = value; + this.FirePropertyChanged(nameof(CanPlay)); + } + } + + public Command Navigate => this._navigate; + + public int FolderId + { + get => this._folderId; + set + { + if (this._folderId == value) + return; + this._folderId = value; + this.FirePropertyChanged(nameof(FolderId)); + } + } + + public List PhotoIds + { + get => this._photoIds; + set + { + if (this._photoIds == value) + return; + this._photoIds = value; + this.FirePropertyChanged(nameof(PhotoIds)); + } + } + + public bool UsePhotoIds + { + get => this._usePhotoIds; + set + { + if (this._usePhotoIds == value) + return; + this._usePhotoIds = value; + this.FirePropertyChanged(nameof(UsePhotoIds)); + } + } + + public bool StartWithFirstPhotoId + { + get => this._startWithFirstPhotoId; + set + { + if (this._startWithFirstPhotoId == value) + return; + this._startWithFirstPhotoId = value; + this.FirePropertyChanged(nameof(StartWithFirstPhotoId)); + } + } + } +} diff --git a/ZuneUI/SlideshowLand.cs b/ZuneUI/SlideshowLand.cs new file mode 100644 index 0000000..48eb1da --- /dev/null +++ b/ZuneUI/SlideshowLand.cs @@ -0,0 +1,44 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SlideshowLand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.ComponentModel; + +namespace ZuneUI +{ + public class SlideshowLand : PlaybackPage, ISlideShowStateOwner, INotifyPropertyChanged + { + private SlideShowState _state; + + public SlideshowLand() + { + this.BackgroundUI = SlideshowLand.PhotoSlideshowTemplate; + this.TransportControlStyle = TransportControlStyle.Photo; + this.AutoHideToolbars = true; + this.ShowAppBackground = true; + this.NoStackPage = true; + } + + public SlideShowState SlideShowState + { + get => this._state; + set + { + if (this._state == value) + return; + this._state = value; + this.FirePropertyChanged(nameof(SlideShowState)); + } + } + + public void MoveToNextSlide() => ++this.SlideShowState.Index; + + public void MoveToPreviousSlide() => --this.SlideShowState.Index; + + public void TogglePlayOrPauseSlideshow() => this.SlideShowState.Play = !this.SlideShowState.Play; + + private static string PhotoSlideshowTemplate => "res://ZuneShellResources!PhotoSlideShow.uix#PhotoSlideShow"; + } +} diff --git a/ZuneUI/SocialExperience.cs b/ZuneUI/SocialExperience.cs new file mode 100644 index 0000000..f7fd7a1 --- /dev/null +++ b/ZuneUI/SocialExperience.cs @@ -0,0 +1,117 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SocialExperience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class SocialExperience : Experience + { + private int _messageCount; + private Node[] _nodes; + private Node _friends; + private Node _me; + private Node _inbox; + + public SocialExperience(Frame frameOwner) + : base(frameOwner, StringId.IDS_SOCIAL_PIVOT, SQMDataId.SocialClicks) + { + } + + public override IList NodesList + { + get + { + if (this._nodes == null) + this._nodes = new Node[3] + { + this.Friends, + this.Me, + this.Inbox + }; + return (IList)this._nodes; + } + } + + public Node Friends + { + get + { + if (this._friends == null) + this._friends = new Node((Experience)this, StringId.IDS_FRIENDS_PIVOT, "Social\\Friends", SQMDataId.SocialFriendsClicks); + return this._friends; + } + } + + public Node Me + { + get + { + if (this._me == null) + this._me = new Node((Experience)this, StringId.IDS_PROFILE_PIVOT, "Social\\Profile", SQMDataId.SocialProfileClicks); + return this._me; + } + } + + public Node Inbox + { + get + { + if (this._inbox == null) + this._inbox = new Node((Experience)this, StringId.IDS_INBOX_PIVOT, "Social\\Inbox", SQMDataId.SocialInboxClicks); + return this._inbox; + } + } + + public int MessageCount + { + get => this._messageCount; + set + { + if (this._messageCount == value) + return; + if (value > this._messageCount) + { + this.FirePropertyChanged("MessagesArrived"); + if (this.MessagesArrived != null) + this.MessagesArrived((object)this, (EventArgs)null); + } + this._messageCount = value; + this.FirePropertyChanged(nameof(MessageCount)); + } + } + + public int PlayCount + { + get => SignIn.Instance.SignedIn ? ProfileDataHelper.ProfilePlayCount : -1; + set + { + if (ProfileDataHelper.ProfilePlayCount == value || !SignIn.Instance.SignedIn) + return; + ProfileDataHelper.ProfilePlayCount = value; + this.FirePropertyChanged(nameof(PlayCount)); + } + } + + public DateTime CommentsLastRead + { + get => SignIn.Instance.SignedIn ? ProfileDataHelper.CommentsLastRead : DateTime.MinValue; + set + { + if (!(ProfileDataHelper.CommentsLastRead != value) || !SignIn.Instance.SignedIn) + return; + ProfileDataHelper.CommentsLastRead = value; + this.FirePropertyChanged(nameof(CommentsLastRead)); + } + } + + public override string DefaultUIPath => "Social\\Default"; + + public event EventHandler MessagesArrived; + } +} diff --git a/ZuneUI/SoftwareUpdates.cs b/ZuneUI/SoftwareUpdates.cs new file mode 100644 index 0000000..f61bac8 --- /dev/null +++ b/ZuneUI/SoftwareUpdates.cs @@ -0,0 +1,310 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SoftwareUpdates +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Win32; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Service; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Globalization; +using System.Net; +using System.Text; +using System.Threading; + +namespace ZuneUI +{ + public class SoftwareUpdates : ModelItem + { + private const string m_PID = "92510-320-9256355-04773"; + private bool m_checkingForUpdates; + private bool m_backgroundCheck; + private bool m_userInitiatedUpdate; + private static SoftwareUpdates m_instance; + private UpdateCheckEventArguments _lastUpdateCheckResult; + + public event EventHandler InstallInitiated; + + public static SoftwareUpdates Instance + { + get + { + if (SoftwareUpdates.m_instance == null) + SoftwareUpdates.m_instance = new SoftwareUpdates(); + return SoftwareUpdates.m_instance; + } + } + + public static string PID => "92510-320-9256355-04773"; + + public void StartUp() => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredStartUp), DeferredInvokePriority.Low); + + public bool CheckingForUpdates + { + get => this.m_checkingForUpdates; + private set + { + if (this.m_checkingForUpdates == value) + return; + this.m_checkingForUpdates = value; + this.FirePropertyChanged(nameof(CheckingForUpdates)); + } + } + + public UpdateCheckEventArguments LastUpdateCheckResult + { + get => this._lastUpdateCheckResult; + set + { + if (this._lastUpdateCheckResult == value) + return; + this._lastUpdateCheckResult = value; + this.FirePropertyChanged(nameof(LastUpdateCheckResult)); + } + } + + public void CheckForUpdates(bool isUserInitiated) + { + if (!this.CheckingForUpdates) + { + this._lastUpdateCheckResult = (UpdateCheckEventArguments)null; + this.CheckingForUpdates = true; + this.m_userInitiatedUpdate = isUserInitiated; + UpdateManager.Instance.BeginUpdateCheck(new UpdateProgressHandler(this.UpdateCheckCallback)); + if (!this.m_userInitiatedUpdate) + return; + SQMLog.Log(SQMDataId.ManualCheckForUpdatesInvoked, 1); + } + else + this.m_backgroundCheck = false; + } + + public void CancelCheckForUpdates() + { + UpdateManager.Instance.CancelUpdateCheck(); + SoftwareUpdates.Instance.CheckingForUpdates = false; + } + + public void InstallUpdates() + { + this.OnInstallInitiated(); + UpdateManager.Instance.InstallUpdate(new UpdateProgressHandler(this.UpdateCheckCallback)); + } + + public void ShowUpdateAvailabilityDialog() + { + if (!this.LastUpdateCheckResult.UpdateFound && this.m_backgroundCheck) + return; + if (this.IsWUClientUpToDate()) + { + if (this.LastUpdateCheckResult.HR >= 0) + UpdateDialogInfo.Show(this.LastUpdateCheckResult.UpdateFound, this.LastUpdateCheckResult.CriticalUpdateFound, this.m_userInitiatedUpdate); + else + Shell.ShowErrorDialog(this.LastUpdateCheckResult.HR, StringId.IDS_CHECK_FOR_UPDATES_FAILED); + } + else + Shell.ShowErrorDialog(-1072885299, StringId.IDS_CHECK_FOR_UPDATES_FAILED, StringId.IDS_CHECK_FOR_UPDATES_FAILED_DESCRIPTION); + } + + private bool IsWUClientUpToDate() + { + string str = Environment.ExpandEnvironmentVariables("%windir%\\System32\\wuaueng.dll"); + bool flag = false; + if (str != null && System.IO.File.Exists(str) && new Version(FileVersionInfo.GetVersionInfo(str).ProductVersion).CompareTo(new Version("7.2.6001.784")) >= 0) + flag = true; + return flag; + } + + private void OnInstallInitiated() + { + if (this.InstallInitiated != null) + this.InstallInitiated((object)this, (EventArgs)null); + this.FirePropertyChanged("InstallInitiated"); + } + + private void DeferredStartUp(object state) + { + this.CheckOsUpgrade(); + DateTime lastUpdateCheck = ClientConfiguration.Shell.LastUpdateCheck; + uint num = Math.Min((uint)MachineConfiguration.Setup.UpdateCheckFrequency, 14U); + if ((long)Math.Abs((DateTime.UtcNow - lastUpdateCheck).Days) >= (long)num && !Fue.Instance.IsFirstLaunch && !Shell.SettingsFrame.Wizard.IsCurrent) + { + this.m_backgroundCheck = true; + this.CheckForUpdates(false); + } + this.CheckCodecAccounting(); + } + + private void DeferredUpdateCheckCallback(object args) + { + this.LastUpdateCheckResult = (UpdateCheckEventArguments)args; + if (this.LastUpdateCheckResult.HR >= 0) + { + try + { + ClientConfiguration.Shell.LastUpdateCheck = DateTime.UtcNow; + } + catch (ApplicationException ex) + { + } + } + if (this.m_backgroundCheck) + this.ShowUpdateAvailabilityDialog(); + this.m_userInitiatedUpdate = false; + this.m_backgroundCheck = false; + this.CheckingForUpdates = false; + } + + private void UpdateCheckCallback(UpdateCheckEventArguments args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredUpdateCheckCallback), (object)args, DeferredInvokePriority.Normal); + + private void CheckOsUpgrade() + { + int num = Environment.OSVersion.Version.Major * 100 + Environment.OSVersion.Version.Minor; + int osVersion = MachineConfiguration.Setup.OSVersion; + if (num <= osVersion) + return; + if (osVersion < 600 && MachineConfiguration.HME.CurrentSharingUID != 0) + ThreadPool.QueueUserWorkItem(new WaitCallback(this.RepairNetworkSharingService), (object)num); + if (osVersion >= 601 || num < 601) + return; + ThreadPool.QueueUserWorkItem(new WaitCallback(this.CreatePodcastLibraryTemplate), (object)num); + } + + private void RepairNetworkSharingService(object state) + { + int num = (int)state; + HMESettings hmeSettings = new HMESettings(); + HRESULT hresult = (HRESULT)hmeSettings.Init(); + if (hresult.IsSuccess) + hresult = (HRESULT)hmeSettings.RepairSharing(); + if (!hresult.IsSuccess) + return; + MachineConfiguration.Setup.OSVersion = num; + } + + private void CreatePodcastLibraryTemplate(object state) + { + int num = (int)state; + if (((HRESULT)Win7ShellManager.Instance.CreatePodcastLibraryTemplate()).IsSuccess) + MachineConfiguration.Setup.OSVersion = num; + Win7ShellManager.Instance.SyncLibraryFolders(); + } + + private void CheckCodecAccounting() + { + if (MachineConfiguration.Setup.CodecInfoSent) + return; + RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Zune"); + DateTime utcNow = DateTime.UtcNow; + DateTime localTime = utcNow.ToLocalTime(); + long totalMilliseconds = (long)localTime.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds; + string str1 = "ZuneSetup.exe"; + string wtProfile = MachineConfiguration.Setup.WTProfile; + string str2 = totalMilliseconds.ToString(); + string str3 = localTime.ToString("yyyy/MM/dd"); + string str4 = TimeZone.CurrentTimeZone.GetUtcOffset(localTime).Hours.ToString(); + string str5 = localTime.Hour.ToString(); + string ietfLanguageTag = CultureInfo.CurrentUICulture.IetfLanguageTag; + string installationSource = MachineConfiguration.Setup.InstallationSource; + string pid = SoftwareUpdates.PID; + string version1 = (string)registryKey.GetValue("CurrentVersion"); + string oldVersion = MachineConfiguration.Setup.OldVersion; + string str6 = string.Empty; + string str7 = "New"; + if (!string.IsNullOrEmpty(version1)) + { + try + { + Version version2 = new Version(version1); + int major = version2.Major; + int minor = version2.Minor; + if (!string.IsNullOrEmpty(oldVersion)) + { + Version version3 = new Version(oldVersion); + str7 = !(version2 == version3) ? (version2.Major <= version3.Major ? (version2.Major != version3.Major ? "ReInstall" : "Upgrade") : "MajorUpgrade") : "ReInstall"; + } + } + catch (ArgumentException ex) + { + } + catch (FormatException ex) + { + } + catch (OverflowException ex) + { + } + } + try + { + using (CryptoHelper cryptoHelper = new CryptoHelper(pid)) + { + string data = utcNow.ToString("yyyy-MM-dd-hh-mm-ss"); + str6 = Uri.EscapeDataString(cryptoHelper.Encrypt(data)); + } + } + catch (Win32Exception ex) + { + } + string[] strArray = new string[27] + { + "http://m.webtrends.com/dcs8fe5yk00000s538qdxmbst_2t2k/dcs.gif", + "?dcsdat=", + str2, + "&dcsuri=", + str1, + "&dcssip=", + wtProfile, + "&wt.tz=", + str4, + "&wt.bh=", + str5, + "&wt.date=", + str3, + "&wt.ul=", + ietfLanguageTag, + "&zune_cver=", + version1, + "&zune_isource=", + installationSource, + "&zune_itype=", + str7, + "&zune_over=", + oldVersion, + "&zune_pid=", + pid, + "&zune_gmthash=", + str6 + }; + StringBuilder stringBuilder = new StringBuilder(); + for (int index = 0; index < strArray.Length; ++index) + stringBuilder.Append(strArray[index]); + try + { + Microsoft.Zune.Service.HttpWebRequest httpWebRequest = Microsoft.Zune.Service.HttpWebRequest.Create(new Uri(stringBuilder.ToString())); + httpWebRequest.CancelOnShutdown = true; + httpWebRequest.GetResponseAsync(new AsyncRequestComplete(this.OnRequestComplete), (object)null); + } + catch (Exception ex) + { + } + } + + private void OnRequestComplete(Microsoft.Zune.Service.HttpWebResponse response, object requestArgs) + { + if (response.StatusCode == HttpStatusCode.OK) + { + MachineConfiguration.Setup.CodecInfoSent = true; + } + else + { + int statusCode = (int)response.StatusCode; + } + } + } +} diff --git a/ZuneUI/SongMatchData.cs b/ZuneUI/SongMatchData.cs new file mode 100644 index 0000000..0e0f726 --- /dev/null +++ b/ZuneUI/SongMatchData.cs @@ -0,0 +1,48 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SongMatchData +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class SongMatchData + { + private AlbumMetadata _mergedAlbum; + private TrackMetadata _track; + private GroupedList _matchOptions; + private int _originalMergedIndex; + private int _selectedMatchIndex; + + internal SongMatchData( + AlbumMetadata mergedAlbum, + TrackMetadata track, + GroupedList matchOptions, + int originalMergedIndex, + int selectedMatchIndex) + { + this._mergedAlbum = mergedAlbum; + this._track = track; + this._matchOptions = matchOptions; + this._originalMergedIndex = originalMergedIndex; + this._selectedMatchIndex = selectedMatchIndex; + } + + public AlbumMetadata MergedAlbum => this._mergedAlbum; + + public TrackMetadata Track => this._track; + + public GroupedList MatchOptions => this._matchOptions; + + public int OriginalMergedIndex => this._originalMergedIndex; + + public int SelectedMatchIndex + { + get => this._selectedMatchIndex; + set => this._selectedMatchIndex = value; + } + } +} diff --git a/ZuneUI/SortCommand.cs b/ZuneUI/SortCommand.cs new file mode 100644 index 0000000..77c4276 --- /dev/null +++ b/ZuneUI/SortCommand.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SortCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class SortCommand : Command + { + private string _sort; + private bool _supportsJumpInList; + + public SortCommand() + : this((string)null, (string)null, false) + { + } + + public SortCommand(string description, string sort, bool supportsJumpInList) + { + this.Description = description; + this.Sort = sort; + this.SupportsJumpInList = supportsJumpInList; + } + + public string Sort + { + get => this._sort; + set + { + if (!(this._sort != value)) + return; + this._sort = value; + this.FirePropertyChanged(nameof(Sort)); + } + } + + public bool SupportsJumpInList + { + get => this._supportsJumpInList; + set + { + if (this._supportsJumpInList == value) + return; + this._supportsJumpInList = value; + this.FirePropertyChanged(nameof(SupportsJumpInList)); + } + } + } +} diff --git a/ZuneUI/SoundHelper.cs b/ZuneUI/SoundHelper.cs new file mode 100644 index 0000000..27802a6 --- /dev/null +++ b/ZuneUI/SoundHelper.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SoundHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.InteropServices; + +namespace ZuneUI +{ + public static class SoundHelper + { + private const uint SND_ASYNC = 1; + private const uint SND_NODEFAULT = 2; + private const uint SND_RESOURCE = 262148; + private const uint SND_SYSTEM = 2097152; + private const uint LOAD_LIBRARY_AS_DATAFILE = 2; + private static IntPtr s_hModZuneShellResources; + + public static void Play(SoundId soundId) + { + if (!((Shell)ZuneShell.DefaultInstance).PlaySounds) + return; + string pszSound = (string)null; + switch (soundId) + { + case SoundId.DownloadComplete: + pszSound = "Download.wav"; + break; + case SoundId.BurnComplete: + pszSound = "BurnComplete.wav"; + break; + case SoundId.RipComplete: + pszSound = "RipComplete.wav"; + break; + case SoundId.Inbox: + pszSound = "Inbox.wav"; + break; + } + if (pszSound == null) + return; + uint fdwSound = 262151; + if (Environment.OSVersion.Version.Major >= 6) + fdwSound |= 2097152U; + if (SoundHelper.s_hModZuneShellResources == IntPtr.Zero) + SoundHelper.s_hModZuneShellResources = SoundHelper.LoadLibraryEx("ZuneShellResources.dll", IntPtr.Zero, 2U); + SoundHelper.PlaySound(pszSound, SoundHelper.s_hModZuneShellResources, fdwSound); + } + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + public static extern IntPtr LoadLibraryEx( + string lpModuleName, + IntPtr mustBeZero, + uint dwFlags); + + [DllImport("winmm.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern bool PlaySound(string pszSound, IntPtr hmod, uint fdwSound); + } +} diff --git a/ZuneUI/SoundId.cs b/ZuneUI/SoundId.cs new file mode 100644 index 0000000..183565c --- /dev/null +++ b/ZuneUI/SoundId.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SoundId +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum SoundId + { + DownloadComplete, + BurnComplete, + RipComplete, + Inbox, + } +} diff --git a/ZuneUI/SpecialPlaylist.cs b/ZuneUI/SpecialPlaylist.cs new file mode 100644 index 0000000..ba098e0 --- /dev/null +++ b/ZuneUI/SpecialPlaylist.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SpecialPlaylist +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum SpecialPlaylist + { + InvalidId = -2147483648, // 0x80000000 + NowPlaying = -1, // 0xFFFFFFFF + } +} diff --git a/ZuneUI/SplitAudioTrack.cs b/ZuneUI/SplitAudioTrack.cs new file mode 100644 index 0000000..a6b6135 --- /dev/null +++ b/ZuneUI/SplitAudioTrack.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SplitAudioTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Runtime.InteropServices; +using UIXControls; + +namespace ZuneUI +{ + public static class SplitAudioTrack + { + public static void Split(IList tracks) + { + bool flag = false; + foreach (DataProviderObject track in (IEnumerable)tracks) + { + if ((long)(track.GetProperty("FileCount") ?? (object)0) > 1L) + { + HRESULT hresult = SplitAudioTrack.Split((int)(track.GetProperty("LibraryId") ?? (object)-1)); + flag |= hresult.IsError; + } + } + if (!flag) + return; + MessageBox.Show(Shell.LoadString(StringId.IDS_GENERIC_ERROR), Shell.LoadString(StringId.IDS_SHOW_DUPLICATES_FAILED), (EventHandler)null); + } + + private static HRESULT Split(int libraryId) + { + try + { + ZuneLibrary.SplitAudioTrack(libraryId); + } + catch (COMException ex) + { + return (HRESULT)ex.ErrorCode; + } + return HRESULT._S_OK; + } + } +} diff --git a/ZuneUI/StandardPlaylistFactory.cs b/ZuneUI/StandardPlaylistFactory.cs new file mode 100644 index 0000000..fda6059 --- /dev/null +++ b/ZuneUI/StandardPlaylistFactory.cs @@ -0,0 +1,37 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StandardPlaylistFactory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Playlist; + +namespace ZuneUI +{ + public class StandardPlaylistFactory : PlaylistFactory + { + private readonly string _baseUniqueTitle; + + private StandardPlaylistFactory(string baseUniqueTitle) + : base(false) + { + this.Ready = true; + this._baseUniqueTitle = baseUniqueTitle; + } + + public static StandardPlaylistFactory CreateInstance( + string baseUniqueTitle) + { + return new StandardPlaylistFactory(baseUniqueTitle); + } + + public override string GetUniqueTitle() => Microsoft.Zune.Playlist.PlaylistManager.Instance.GetUniquePlaylistTitle(this._baseUniqueTitle); + + public override PlaylistResult CreatePlaylist( + string title, + CreatePlaylistOption option) + { + return PlaylistManager.Instance.CreatePlaylist(title, option); + } + } +} diff --git a/ZuneUI/StartSyncCommand.cs b/ZuneUI/StartSyncCommand.cs new file mode 100644 index 0000000..bf05b22 --- /dev/null +++ b/ZuneUI/StartSyncCommand.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StartSyncCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class StartSyncCommand : SyncCommandBase + { + public StartSyncCommand() => this._availableWhenSyncing = false; + + protected override void OnInvoked() + { + if (this.Device != null) + this.Device.BeginSync(true, false); + base.OnInvoked(); + } + } +} diff --git a/ZuneUI/StartupPage.cs b/ZuneUI/StartupPage.cs new file mode 100644 index 0000000..a1c2846 --- /dev/null +++ b/ZuneUI/StartupPage.cs @@ -0,0 +1,12 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StartupPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class StartupPage : NoStackPage + { + } +} diff --git a/ZuneUI/StateDescriptor.cs b/ZuneUI/StateDescriptor.cs new file mode 100644 index 0000000..f00781a --- /dev/null +++ b/ZuneUI/StateDescriptor.cs @@ -0,0 +1,48 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StateDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Globalization; + +namespace ZuneUI +{ + public class StateDescriptor : CountryFieldValidationPropertyDescriptor + { + public StateDescriptor(string name) + : base(name, CountryFieldValidatorType.State) + { + } + + public override object ConvertFromString(string value) + { + string str = SignIn.Instance.SignedIn ? SignIn.Instance.CountryCode : RegionInfo.CurrentRegion.TwoLetterISORegionName; + return this.ConvertFromString(value, (object)str); + } + + public override object ConvertFromString(string value, object country) + { + string str = (string)null; + AccountCountry country1 = AccountCountryList.Instance.GetCountry(country as string); + if (country1 != null) + str = country1.GetStateAbbreviation(value); + return (object)str ?? (object)value; + } + + public override string ConvertToString(object value) + { + string str = SignIn.Instance.SignedIn ? SignIn.Instance.CountryCode : RegionInfo.CurrentRegion.TwoLetterISORegionName; + return this.ConvertToString(value, (object)str); + } + + public override string ConvertToString(object value, object country) + { + string str = (string)null; + AccountCountry country1 = AccountCountryList.Instance.GetCountry(country as string); + if (country1 != null) + str = country1.GetState(value as string); + return str ?? value as string; + } + } +} diff --git a/ZuneUI/StatusNavigationCommandHandler.cs b/ZuneUI/StatusNavigationCommandHandler.cs new file mode 100644 index 0000000..9329cab --- /dev/null +++ b/ZuneUI/StatusNavigationCommandHandler.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StatusNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class StatusNavigationCommandHandler : NavigationCommandHandlerBase + { + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new Deviceland(); + } +} diff --git a/ZuneUI/StopSyncCommand.cs b/ZuneUI/StopSyncCommand.cs new file mode 100644 index 0000000..bb09b90 --- /dev/null +++ b/ZuneUI/StopSyncCommand.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StopSyncCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class StopSyncCommand : SyncCommandBase + { + public StopSyncCommand() => this._availableWhenSyncing = true; + + protected override void OnInvoked() + { + if (this.Device != null) + this.Device.EndSync(true); + base.OnInvoked(); + } + } +} diff --git a/ZuneUI/StreamingPlaybackTrack.cs b/ZuneUI/StreamingPlaybackTrack.cs new file mode 100644 index 0000000..107c2e2 --- /dev/null +++ b/ZuneUI/StreamingPlaybackTrack.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StreamingPlaybackTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + [Serializable] + public class StreamingPlaybackTrack : PlaybackTrack + { + private string _uri; + private string _title; + private bool _isVideo; + private MediaType _mediaType; + + public StreamingPlaybackTrack(string uri, string title, MediaType mediaType) + { + this._uri = uri; + this._title = title; + this._isVideo = mediaType == MediaType.Video; + this._mediaType = mediaType; + } + + public override Guid ZuneMediaId => Guid.Empty; + + public override HRESULT GetURI(out string uri) + { + uri = this._uri; + return HRESULT._S_OK; + } + + public override string Title => this._title; + + public override TimeSpan Duration => TimeSpan.Zero; + + public override bool IsVideo => this._isVideo; + + public override MediaType MediaType => this._mediaType; + } +} diff --git a/ZuneUI/StreamingRadioPlaybackTrack.cs b/ZuneUI/StreamingRadioPlaybackTrack.cs new file mode 100644 index 0000000..5cdcddc --- /dev/null +++ b/ZuneUI/StreamingRadioPlaybackTrack.cs @@ -0,0 +1,53 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StreamingRadioPlaybackTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + [Serializable] + public class StreamingRadioPlaybackTrack : PlaybackTrack + { + private string _originalUri; + private string _title; + private bool _isVideo; + private MediaType _mediaType; + [NonSerialized] + private RadioPlaylist _playlist; + + public StreamingRadioPlaybackTrack(string uri, string title, MediaType mediaType) + { + this._originalUri = uri; + this._title = title; + this._isVideo = mediaType == MediaType.Video; + this._mediaType = mediaType; + } + + public override Guid ZuneMediaId => Guid.Empty; + + public override HRESULT GetURI(out string uri) + { + string str = (string)null; + if (this._playlist == null && this._originalUri != null) + this._playlist = RadioStationManager.Instance.GetRadioPlaylist(this._originalUri); + if (this._playlist != null) + str = this._playlist.GetNextUri(); + uri = str; + return HRESULT._S_OK; + } + + public override string Title => this._title; + + public override TimeSpan Duration => TimeSpan.Zero; + + public override bool IsVideo => this._isVideo; + + public override bool IsStreaming => true; + + public override MediaType MediaType => this._mediaType; + } +} diff --git a/ZuneUI/StringCaseInsensitiveComparer.cs b/ZuneUI/StringCaseInsensitiveComparer.cs new file mode 100644 index 0000000..b12427c --- /dev/null +++ b/ZuneUI/StringCaseInsensitiveComparer.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StringCaseInsensitiveComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + internal class StringCaseInsensitiveComparer : IComparer + { + private static StringCaseInsensitiveComparer s_instance; + + public static IComparer Instance + { + get + { + if (StringCaseInsensitiveComparer.s_instance == null) + StringCaseInsensitiveComparer.s_instance = new StringCaseInsensitiveComparer(); + return (IComparer)StringCaseInsensitiveComparer.s_instance; + } + } + + private StringCaseInsensitiveComparer() + { + } + + int IComparer.Compare(string x, string y) => string.Compare(x, y, StringComparison.CurrentCultureIgnoreCase); + } +} diff --git a/ZuneUI/StringExtractorList.cs b/ZuneUI/StringExtractorList.cs new file mode 100644 index 0000000..b753072 --- /dev/null +++ b/ZuneUI/StringExtractorList.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StringExtractorList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class StringExtractorList : VirtualList, ISearchableList + { + private IList _source; + private ISearchableList _searchableSource; + private bool _canSearchForString; + + public IList Source + { + get => this._source; + set + { + if (this._source == value) + return; + this._source = value; + this.FirePropertyChanged(nameof(Source)); + this._searchableSource = this._source as ISearchableList; + this.Reset(); + } + } + + public bool CanSearchForString + { + get => this._canSearchForString; + set => this._canSearchForString = value; + } + + protected void Reset() + { + this.Clear(); + this.Count = this._source != null ? this._source.Count : 0; + } + + protected override object OnRequestItem(int index) => (object)this.ExtractString(this._source[index]); + + int ISearchableList.SearchForString(string str) => this._searchableSource != null && this._canSearchForString ? this._searchableSource.SearchForString(str) : -1; + + protected virtual string ExtractString(object item) => item.ToString(); + } +} diff --git a/ZuneUI/StringFormatHelper.cs b/ZuneUI/StringFormatHelper.cs new file mode 100644 index 0000000..372420f --- /dev/null +++ b/ZuneUI/StringFormatHelper.cs @@ -0,0 +1,76 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StringFormatHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Globalization; + +namespace ZuneUI +{ + public static class StringFormatHelper + { + private static string _unknown = Shell.LoadString(StringId.IDS_TYPE_UNKNOWN); + + private static string Format(DateTime date, string format, string unknown) => date == DateTime.MinValue ? unknown : date.ToString(format); + + public static string Format(DateTime date, string format) => StringFormatHelper.Format(date, format, StringFormatHelper._unknown); + + public static string FormatShortDate(DateTime date, string unknown) => StringFormatHelper.Format(date, StringFormatHelper.ShortDateFormat, unknown); + + public static string FormatShortDate(DateTime date) => StringFormatHelper.FormatShortDate(date, StringFormatHelper._unknown); + + public static string ShortDateFormat => "d"; + + public static string ShortDatePatternForDisplay => DateTimeFormatInfo.CurrentInfo.ShortDatePattern.ToLower(); + + public static string ShortTimeFormat => "t"; + + public static string FormatYear(DateTime date, string unknown) => StringFormatHelper.Format(date, StringFormatHelper.YearFormat, unknown); + + public static string FormatYear(DateTime date) => StringFormatHelper.FormatYear(date, StringFormatHelper._unknown); + + public static string YearFormat => "yyyy"; + + public static string NumericMonthDayPattern => Shell.LoadString(StringId.IDS_DATETIME_NUMERIC_MONTH_DAY_PATTERN); + + public static string NumericMonthYearPattern => Shell.LoadString(StringId.IDS_DATETIME_NUMERIC_MONTH_YEAR_PATTERN); + + public static string FriendlyMonthYearPattern => Shell.LoadString(StringId.IDS_DATETIME_MONTH_DAY_YEAR_PATTERN); + + public static string FormatPrice(double price, string currencyCode) + { + CultureInfo cultureInfo = CultureInfo.CurrentCulture; + bool flag = string.IsNullOrEmpty(currencyCode); + if (!flag) + { + try + { + flag = new RegionInfo(cultureInfo.LCID).ISOCurrencySymbol.Equals(currencyCode, StringComparison.InvariantCultureIgnoreCase); + } + catch (ArgumentException ex) + { + } + } + if (!flag) + { + foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures)) + { + try + { + if (new RegionInfo(culture.LCID).ISOCurrencySymbol.Equals(currencyCode, StringComparison.InvariantCultureIgnoreCase)) + { + cultureInfo = culture; + break; + } + } + catch (ArgumentException ex) + { + } + } + } + return string.Format((IFormatProvider)cultureInfo, "{0:c}", (object)price); + } + } +} diff --git a/ZuneUI/StringHelper.cs b/ZuneUI/StringHelper.cs new file mode 100644 index 0000000..dc09728 --- /dev/null +++ b/ZuneUI/StringHelper.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StringHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class StringHelper + { + public static bool IsEqualCaseInsensitive(string first, string second) => string.Compare(first, second, StringComparison.InvariantCultureIgnoreCase) == 0; + + public static string[] Split(string value, string splitPattern) + { + if (string.IsNullOrEmpty(value)) + return (string[])null; + return value.Split(new string[1] { splitPattern }, StringSplitOptions.RemoveEmptyEntries); + } + + public static bool CaseInsensitiveCompare(string str1, string str2) => !string.IsNullOrEmpty(str1) && !string.IsNullOrEmpty(str2) && string.Compare(str1, str2, StringComparison.CurrentCultureIgnoreCase) == 0; + } +} diff --git a/ZuneUI/StringId.cs b/ZuneUI/StringId.cs new file mode 100644 index 0000000..c5933c6 --- /dev/null +++ b/ZuneUI/StringId.cs @@ -0,0 +1,3670 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StringId +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum StringId + { + IDS_ZUNECLIENT_SHORTCUT = 5, + IDS_ZUNECLIENT_USERAGENT = 6, + IDS_ZUNECLIENT_LOCALE = 7, + IDS_ZUNECLIENT_WEBHELPLINK_URL = 8, + IDS_ZUNELAUNCH_FAILED = 10, // 0x0000000A + IDS_ZUNELAUNCH_ERRORTITLE = 11, // 0x0000000B + IDS_ZUNELAUNCHSHELL_FAILED = 12, // 0x0000000C + IDS_ZUNELAUNCH_PRERELEASEEXPIRED = 13, // 0x0000000D + IDS_ZUNELAUNCH_PRERELEASEEXPIREWARNING = 14, // 0x0000000E + IDS_ZUNELAUNCH_MUSTREBOOT = 15, // 0x0000000F + IDS_ZUNELAUNCH_FATAL_ERROR = 16, // 0x00000010 + IDS_ZUNELAUNCH_SIGNING_FAILURE = 17, // 0x00000011 + IDS_ZUNELAUNCH_COMPONENT_ERROR = 18, // 0x00000012 + IDS_APPDATAFOLDERNAME = 20, // 0x00000014 + IDS_ROOTFOLDERNAME = 21, // 0x00000015 + IDS_ART_CACHE_FOLDER_NAME = 22, // 0x00000016 + IDS_PODCAST_FOLDER_NAME = 23, // 0x00000017 + IDS_MDRCD_FOLDER_NAME = 24, // 0x00000018 + IDS_TRANCODED_CACHE_FOLDER_NAME = 25, // 0x00000019 + IDS_FIRMWARE_UPDATE_FOLDER_NAME = 26, // 0x0000001A + IDS_PLAYLISTFOLDERNAME = 27, // 0x0000001B + IDS_PODCAST_FOLDER_SUFFIX = 28, // 0x0000001C + IDS_HIDDEN_CONTENT_FOLDER_SUFFIX = 29, // 0x0000001D + IDS_TEMPORARY_MUSIC_FOLDER_SUFFIX = 30, // 0x0000001E + IDS_REVERSE_SYNC_IMPORTED_ON = 31, // 0x0000001F + IDS_APPLICATIONS_FOLDER_NAME = 32, // 0x00000020 + IDS_DEVICE_ASSET_FOLDER_NAME = 33, // 0x00000021 + IDS_UGC_FOLDER_NAME = 34, // 0x00000022 + IDS_CAMERA_ROLL_FOLDER_NAME = 35, // 0x00000023 + IDS_SAVED_CONTENT_FOLDER_NAME = 36, // 0x00000024 + IDS_SAMPLE_PICTURES_FOLDER_NAME = 38, // 0x00000026 + IDS_PLAYLIST_MULTIVALSEPSTRING = 100, // 0x00000064 + IDS_MEDIASTORE_UNKNOWN_TRACK_FORMAT = 101, // 0x00000065 + IDS_MEDIASTORE_UNKNOWN_ALBUM_FORMAT = 102, // 0x00000066 + IDS_MEDIASTORE_UNKNOWN_ALBUM_PREFIX = 103, // 0x00000067 + IDS_MEDIASTORE_UNKNOWN_ARTIST = 104, // 0x00000068 + IDS_MEDIASTORE_UNKNOWN_TRACK_PREFIX = 105, // 0x00000069 + IDS_MEDIASTORE_IGNORED_ARTICLE_LIST = 106, // 0x0000006A + IDS_MEDIASTORE_TRACK_REFORMATTING = 107, // 0x0000006B + IDS_MEDIASTORE_VARIOUS_ARTISTS = 108, // 0x0000006C + IDS_MEDIASTORE_DATABASE_CORRUPT_TITLE = 109, // 0x0000006D + IDS_MEDIASTORE_DATABASE_CORRUPT = 110, // 0x0000006E + IDS_MEDIASTORE_UNKNOWN_ALBUM = 111, // 0x0000006F + IDS_CDBURN_QUALITY32 = 204, // 0x000000CC + IDS_CDBURN_QUALITY48 = 205, // 0x000000CD + IDS_CDBURN_QUALITY64 = 206, // 0x000000CE + IDS_CDBURN_QUALITY96 = 207, // 0x000000CF + IDS_CDBURN_QUALITY128 = 208, // 0x000000D0 + IDS_CDBURN_QUALITY160 = 209, // 0x000000D1 + IDS_CDBURN_QUALITY192 = 210, // 0x000000D2 + IDS_CD_DRIVE = 211, // 0x000000D3 + IDS_BURNLIST = 212, // 0x000000D4 + IDS_CDMDRCD_FORMAT_STRING = 213, // 0x000000D5 + IDS_SERVICE_UNKNOWNTRACK = 250, // 0x000000FA + IDS_SERVICE_UNKNOWNARTIST = 251, // 0x000000FB + IDS_SERVICE_UNKNOWNALBUM = 252, // 0x000000FC + IDS_SERVICE_DEFAULTDOWNLOADFOLDER = 253, // 0x000000FD + IDS_SERVICE_SUBSCRIPTIONFOLDER = 254, // 0x000000FE + IDS_SERVICE_VIDEOFOLDER = 255, // 0x000000FF + IDS_SERVICE_FILENAME_FORMAT_NO_DISC = 256, // 0x00000100 + IDS_SERVICE_FILENAME_FORMAT_WITH_DISC = 257, // 0x00000101 + IDS_SERVICE_UNKNOWNSERIES = 258, // 0x00000102 + IDS_SERVICE_UNKNOWNVIDEO = 259, // 0x00000103 + IDS_SERIES_UNKNOWNSERIES_TITLE = 260, // 0x00000104 + IDS_SERIES_UNKNOWNSERIES_DESCRIPTION = 261, // 0x00000105 + IDS_SERIES_GROVELLED_SERIES_DESCRIPTION = 262, // 0x00000106 + IDS_NSS_FW_APP_NAME = 270, // 0x0000010E + IDS_NSS_FW_QWAVE_1 = 271, // 0x0000010F + IDS_NSS_FW_QWAVE_2 = 272, // 0x00000110 + IDS_NSS_FW_QWAVE_3 = 273, // 0x00000111 + IDS_NSS_FW_QWAVE_4 = 274, // 0x00000112 + IDS_NSS_FW_QWAVE_5 = 275, // 0x00000113 + IDS_NSS_FW_QWAVE_6 = 276, // 0x00000114 + IDS_NSS_FW_QWAVE_7 = 277, // 0x00000115 + IDS_NSS_FW_QWAVE_8 = 278, // 0x00000116 + IDS_NSS_FW_SSDP_1 = 279, // 0x00000117 + IDS_NSS_FW_SSDP_2 = 280, // 0x00000118 + IDS_NSS_FW_SSDP_3 = 281, // 0x00000119 + IDS_NSS_FW_SSDP_4 = 282, // 0x0000011A + IDS_NSS_FW_UPNP_1 = 283, // 0x0000011B + IDS_NSS_FW_UPNP_2 = 284, // 0x0000011C + IDS_NSS_FW_UPNP_3 = 285, // 0x0000011D + IDS_NSS_FW_UPNP_4 = 286, // 0x0000011E + IDS_NSS_FW_HTTP_1 = 287, // 0x0000011F + IDS_NSS_FW_HTTP_2 = 288, // 0x00000120 + IDS_NSS_FW_HTTP_3 = 289, // 0x00000121 + IDS_NSS_FW_HTTP_4 = 290, // 0x00000122 + IDS_NSS_FW_UDP_1 = 291, // 0x00000123 + IDS_NSS_FW_UDP_2 = 292, // 0x00000124 + IDS_NSS_FW_UDP_3 = 293, // 0x00000125 + IDS_NSS_FW_UDP_4 = 294, // 0x00000126 + IDS_NSS_FW_TCP_1 = 295, // 0x00000127 + IDS_NSS_FW_TCP_2 = 296, // 0x00000128 + IDS_NSS_FW_TCP_3 = 297, // 0x00000129 + IDS_NSS_FW_TCP_4 = 298, // 0x0000012A + IDS_NSS_FW_UPNPHOST_1 = 299, // 0x0000012B + IDS_NSS_FW_UPNPHOST_2 = 300, // 0x0000012C + IDS_WIRELESS_FW_APP_NAME = 301, // 0x0000012D + IDS_WIRELESS_FW_SSDP_1 = 302, // 0x0000012E + IDS_WIRELESS_FW_SSDP_2 = 303, // 0x0000012F + IDS_WIRELESS_FW_SSDP_3 = 304, // 0x00000130 + IDS_WIRELESS_FW_SSDP_4 = 305, // 0x00000131 + IDS_WIRELESS_FW_UPNP_1 = 306, // 0x00000132 + IDS_WIRELESS_FW_UPNP_2 = 307, // 0x00000133 + IDS_WIRELESS_FW_UPNP_3 = 308, // 0x00000134 + IDS_WIRELESS_FW_UPNP_4 = 309, // 0x00000135 + IDS_WIRELESS_FW_UPNPHOST_1 = 310, // 0x00000136 + IDS_WIRELESS_FW_UPNPHOST_2 = 311, // 0x00000137 + IDS_WIRELESS_FW_TCP_1 = 312, // 0x00000138 + IDS_WIRELESS_FW_TCP_2 = 313, // 0x00000139 + IDS_DOWNLOAD_FOLDER_FORMAT_MUSIC_VIDEO = 320, // 0x00000140 + IDS_DOWNLOAD_FOLDER_FORMAT_TV_EPISODE = 321, // 0x00000141 + IDS_DOWNLOAD_FOLDER_FORMAT_TV_SHORT = 322, // 0x00000142 + IDS_DOWNLOAD_FILENAME_FORMAT_TV_EPISODE_XD = 324, // 0x00000144 + IDS_DOWNLOAD_FILENAME_FORMAT_VIDEO_XD = 326, // 0x00000146 + IDS_DOWNLOAD_FOLDER_FORMAT_MOVIE = 328, // 0x00000148 + IDS_DOWNLOAD_FILENAME_EXTENSION_VIDEO_MBR = 329, // 0x00000149 + IDS_DOWNLOAD_FILENAME_FORMAT_TV_EPISODE_SD = 330, // 0x0000014A + IDS_DOWNLOAD_FILENAME_FORMAT_TV_EPISODE_HD = 331, // 0x0000014B + IDS_DOWNLOAD_FILENAME_FORMAT_VIDEO_SD = 332, // 0x0000014C + IDS_DOWNLOAD_FILENAME_FORMAT_VIDEO_HD = 333, // 0x0000014D + IDS_DOWNLOAD_FILENAME_EXTENSION_VIDEO_WMV = 334, // 0x0000014E + IDS_DOWNLOAD_FILENAME_FORMAT_MUSIC_VIDEO_XD = 335, // 0x0000014F + IDS_DOWNLOAD_FILENAME_FORMAT_MUSIC_VIDEO_SD = 336, // 0x00000150 + IDS_DOWNLOAD_FILENAME_FORMAT_MUSIC_VIDEO_HD = 337, // 0x00000151 + IDS_USERCARDS_DOWNLOADFOLDER = 350, // 0x0000015E + IDS_CHANNEL_PLAYLIST_NAME_FORMAT = 360, // 0x00000168 + IDS_GENRE_AUDIOBOOK_0 = 370, // 0x00000172 + IDS_GENRE_AUDIOBOOK_1 = 371, // 0x00000173 + IDS_GENRE_COMEDY_SPOKEN_WORD = 372, // 0x00000174 + IDS_GENRE_PODCAST = 373, // 0x00000175 + IDS_SUBSTRING_KARAOKE = 374, // 0x00000176 + IDS_GENRE_PODCAST_ENGLISH = 375, // 0x00000177 + IDS_SHELL_PLAY_AUDIO_CD = 600, // 0x00000258 + IDS_SHELL_PLAY_MUSIC_MEDIA = 601, // 0x00000259 + IDS_SHELL_RIP_AUDIO_CD = 602, // 0x0000025A + IDS_SHELL_ZUNE_PROVIDER = 603, // 0x0000025B + IDS_PLAY_VERB = 604, // 0x0000025C + IDS_RIP_VERB = 605, // 0x0000025D + IDS_JUMP_LIST_QUICKPLAY_CATEGORY = 606, // 0x0000025E + IDS_JUMP_LIST_QUICKMIX_CATEGORY = 607, // 0x0000025F + IDS_JUMP_LIST_RESUME_NOWPLAYING = 609, // 0x00000261 + IDS_JUMP_LIST_SHUFFLE_ALL = 610, // 0x00000262 + IDS_PODCAST_LIBRARY_NAME = 611, // 0x00000263 + IDS_PODCAST_LIBRARY_DESC = 612, // 0x00000264 + IDS_PODCAST_LIBRARY_TOOLTIP = 613, // 0x00000265 + IDS_SHELLHELP_PLAYASPLAYLIST = 614, // 0x00000266 + IDS_SHELLHELP_PLAYASPLAYLIST_ALTERNATIVE_NAME = 615, // 0x00000267 + IDS_SHELLHELP_PLAYASPLAYLISTHELPTEXT = 616, // 0x00000268 + IDS_PODCAST_LIBRARY_FOLDER_NAME = 617, // 0x00000269 + IDS_CONVERSION_CACHE_NAME = 618, // 0x0000026A + IDS_FILETYPE_M3U = 701, // 0x000002BD + IDS_FILETYPE_M4A = 702, // 0x000002BE + IDS_FILETYPE_M4B = 703, // 0x000002BF + IDS_FILETYPE_M4V = 704, // 0x000002C0 + IDS_FILETYPE_MP3 = 705, // 0x000002C1 + IDS_FILETYPE_MP4 = 706, // 0x000002C2 + IDS_FILETYPE_WMA = 707, // 0x000002C3 + IDS_FILETYPE_WMV = 708, // 0x000002C4 + IDS_FILETYPE_ZPL = 709, // 0x000002C5 + IDS_FILETYPE_MBR = 710, // 0x000002C6 + IDS_NSS_FW_APP_DESC = 10270, // 0x0000281E + IDS_WIRELESS_FW_APP_DESC = 10301, // 0x0000283D + IDS_BULLET = 20000, // 0x00004E20 + IDS_RETURN_URL = 20001, // 0x00004E21 + IDS_PLEASE_WAIT = 20002, // 0x00004E22 + IDS_PLEASE_WAIT_TITLE = 20003, // 0x00004E23 + SPLASHFX_STRINGMAP_ENUMTYPE = 32768, // 0x00008000 + IDS_DATA_ONLY_DISC = 33000, // 0x000080E8 + IDS_ADDITIONAL_CDS = 33001, // 0x000080E9 + IDS_NO_CD = 33002, // 0x000080EA + IDS_BLANK_CD = 33003, // 0x000080EB + IDS_STOP_RIP_BUTTON = 33004, // 0x000080EC + IDS_START_RIP_BUTTON = 33005, // 0x000080ED + IDS_RIP_COMPLETE_NOTIFICATION = 33006, // 0x000080EE + IDS_RIP_PROGRESS_NOTIFICATION = 33007, // 0x000080EF + IDS_RIP_CURRENT_NOTIFICATION = 33008, // 0x000080F0 + IDS_RIP_CANCELED_NOTIFICATION = 33009, // 0x000080F1 + IDS_RIP_TRACK_PENDING = 33010, // 0x000080F2 + IDS_RIP_TRACK_PROGRESS = 33011, // 0x000080F3 + IDS_RIP_TRACK_DONE = 33012, // 0x000080F4 + IDS_RIP_TRACK_NOT_RIPPED = 33013, // 0x000080F5 + IDS_RIP_TRACK_INCOMPLETE = 33014, // 0x000080F6 + IDS_RIP_TRACK_ERROR = 33015, // 0x000080F7 + IDS_CD_LAND_MESSAGE = 33016, // 0x000080F8 + IDS_RIP_WMA_48 = 33017, // 0x000080F9 + IDS_RIP_WMA_64 = 33018, // 0x000080FA + IDS_RIP_WMA_96 = 33019, // 0x000080FB + IDS_RIP_WMA_128 = 33020, // 0x000080FC + IDS_RIP_WMA_160 = 33021, // 0x000080FD + IDS_RIP_WMA_192 = 33022, // 0x000080FE + IDS_RIP_WMAV_25 = 33023, // 0x000080FF + IDS_RIP_WMAV_50 = 33024, // 0x00008100 + IDS_RIP_WMAV_75 = 33025, // 0x00008101 + IDS_RIP_WMAV_90 = 33026, // 0x00008102 + IDS_RIP_WMAV_98 = 33027, // 0x00008103 + IDS_RIP_MP3_128 = 33028, // 0x00008104 + IDS_RIP_MP3_192 = 33029, // 0x00008105 + IDS_RIP_MP3_256 = 33030, // 0x00008106 + IDS_RIP_MP3_320 = 33031, // 0x00008107 + IDS_RIP_WMA_LOSSLESS = 33032, // 0x00008108 + IDS_CD_LAND_ALBUM_INFO = 33033, // 0x00008109 + IDS_CD_LAND_DRIVE_INFO = 33034, // 0x0000810A + IDS_EJECT_CD_MENUITEM = 33035, // 0x0000810B + IDS_ERASE_CD_MENUITEM = 33036, // 0x0000810C + IDS_FINDALBUMINFO_MENUITEM = 33037, // 0x0000810D + IDS_BURN_LENGTH_AVAILABLE = 33038, // 0x0000810E + IDS_BURN_LENGTH_USED = 33039, // 0x0000810F + IDS_START_BURN_BUTTON = 33040, // 0x00008110 + IDS_STOP_BURN_BUTTON = 33041, // 0x00008111 + IDS_BURN_FAILED = 33042, // 0x00008112 + IDS_BURNERROR_INSERT_WRITEABLE_DISC = 33043, // 0x00008113 + IDS_BURN_STARTED_NOTIFICATION = 33044, // 0x00008114 + IDS_BURN_PROGRESS_NOTIFICATION = 33045, // 0x00008115 + IDS_BURN_SUCCEEDED_NOTIFICATION = 33046, // 0x00008116 + IDS_BURN_FAILED_NOTIFICATION = 33047, // 0x00008117 + IDS_BURN_TRACK_ERROR = 33048, // 0x00008118 + IDS_BURN_TRACK_PENDING = 33049, // 0x00008119 + IDS_BURN_TRACK_PROGRESS = 33050, // 0x0000811A + IDS_BURN_TRACK_COMPLETE = 33051, // 0x0000811B + IDS_BURN_ERROR_DIALOG_TITLE = 33052, // 0x0000811C + IDS_BURN_FINALIZING = 33053, // 0x0000811D + IDS_REMOVE_FROM_BURNLIST = 33054, // 0x0000811E + IDS_BURNERROR_ATTACH_BURNER = 33055, // 0x0000811F + IDS_BURN_SIZE_AVAILABLE = 33056, // 0x00008120 + IDS_BURN_SIZE_USED = 33057, // 0x00008121 + IDS_BURN_CANCELED_NOTIFICATION = 33058, // 0x00008122 + IDS_CREATE_BURN_LIST_DIALOG_TITLE = 33059, // 0x00008123 + IDS_CREATE_BURN_LIST_QUESTION = 33060, // 0x00008124 + IDS_CREATE_BURN_LIST_YES_CREATE = 33061, // 0x00008125 + IDS_CREATE_BURN_LIST_NO_ADD = 33062, // 0x00008126 + IDS_BURN_PREPARING = 33063, // 0x00008127 + IDS_BURN_CANCELING_NOTIFICATION = 33064, // 0x00008128 + IDS_ERASE_STARTED_NOTIFICATION = 33065, // 0x00008129 + IDS_ERASE_COMPLETED_NOTIFICATION = 33066, // 0x0000812A + IDS_RIP_ERROR_DIALOG_TITLE = 33067, // 0x0000812B + IDS_RIP_ERROR_TOOLTIP = 33068, // 0x0000812C + IDS_RIP_FAILED_NOTIFICATION = 33069, // 0x0000812D + IDS_BURN_LIST_AUDIO = 33070, // 0x0000812E + IDS_BURN_LIST_DATA = 33071, // 0x0000812F + IDS_BURNERROR_CANT_BURN_AUDIO_TO_DVD = 33072, // 0x00008130 + IDS_BURNERROR_CANT_BURN_DATA_TO_AUDIO = 33073, // 0x00008131 + IDS_CD_EDIT_ALBUM_INFO_DIALOG_TITLE = 33074, // 0x00008132 + IDS_CD_EDIT_ALBUM_INFO_MENU_ITEM = 33075, // 0x00008133 + IDS_NO_BURN_RIGHTS_DIALOG_TITLE = 33076, // 0x00008134 + IDS_NO_BURN_RIGHTS_NEED_TO_BUY = 33077, // 0x00008135 + IDS_BURN_PROGRESS_NOTIFICATION_DATA = 33078, // 0x00008136 + IDS_MIXED_CD = 33079, // 0x00008137 + IDS_CANT_BURN_DIALOG_TITLE = 33080, // 0x00008138 + IDS_BURN_CANCEL_DIALOG_TITLE = 33081, // 0x00008139 + IDS_BURN_CANCEL_PROMPT = 33082, // 0x0000813A + IDS_INCOLLECTION = 34000, // 0x000084D0 + IDS_PENDING = 34001, // 0x000084D1 + IDS_BUY = 34002, // 0x000084D2 + IDS_DOWNLOAD = 34003, // 0x000084D3 + IDS_AUTOMATIC = 34004, // 0x000084D4 + IDS_DOWNLOAD_ERROR_BUTTON = 34005, // 0x000084D5 + IDS_DOWNLOAD_PROGRESS = 34006, // 0x000084D6 + IDS_CANCEL_DOWNLOAD = 34007, // 0x000084D7 + IDS_DOWNLOADINPROGRESS_DIALOG_TITLE = 34008, // 0x000084D8 + IDS_DOWNLOADINPROGRESS_DIALOG_MESSAGE = 34009, // 0x000084D9 + IDS_DOWNLOAD_ERROR = 34010, // 0x000084DA + IDS_FREE = 34011, // 0x000084DB + IDS_BUY_MENUITEM = 34012, // 0x000084DC + IDS_DOWNLOAD_MENUITEM = 34013, // 0x000084DD + IDS_PLAY_MENUITEM = 34014, // 0x000084DE + IDS_TELL_A_FRIEND_MENUITEM = 34015, // 0x000084DF + IDS_CANCEL_DOWNLOAD_MENUITEM = 34016, // 0x000084E0 + IDS_DOWNLOAD_NEXT_MENUITEM = 34017, // 0x000084E1 + IDS_CANCELLED = 34018, // 0x000084E2 + IDS_FAILED = 34019, // 0x000084E3 + IDS_ALBUM_ONLY = 34020, // 0x000084E4 + IDS_NOT_AVAILABLE = 34021, // 0x000084E5 + IDS_DOWNLOADSINPROGRESS_DIALOG_MESSAGE = 34022, // 0x000084E6 + IDS_DOWNLOAD_COMPLETE_NOTIFICATION = 34023, // 0x000084E7 + IDS_DOWNLOAD_PROGRESS_NOTIFICATION = 34024, // 0x000084E8 + IDS_DOWNLOAD_CURRENT_NOTIFICATION = 34025, // 0x000084E9 + IDS_DOWNLOAD_FAILED_NOTIFICATION = 34027, // 0x000084EB + IDS_TASKSINPROGRESS_DIALOG_TITLE = 34028, // 0x000084EC + IDS_TASKSINPROGRESS_DIALOG_MESSAGE = 34029, // 0x000084ED + IDS_VIEW_IN_MARKETPLACE = 34030, // 0x000084EE + IDS_MORE_INFO = 34031, // 0x000084EF + IDS_VIEW_IN_ZUNEDOTNET = 34032, // 0x000084F0 + IDS_PREVIEW_MENUITEM = 34033, // 0x000084F1 + IDS_SEND_USER_CARD_MENUITEM = 34034, // 0x000084F2 + IDS_ADD_TO_CART_MENUITEM = 34035, // 0x000084F3 + IDS_BUY_ALL = 34036, // 0x000084F4 + IDS_ADD_TO_FAVORITES_MENUITEM = 34037, // 0x000084F5 + IDS_REMOVE_FROM_FAVORITES_MENUITEM = 34038, // 0x000084F6 + IDS_ADD_TO_COLLECTION = 34039, // 0x000084F7 + IDS_BUY_AVAILABLE = 34040, // 0x000084F8 + IDS_FREE_MENUITEM = 34041, // 0x000084F9 + IDS_PAUSE_DOWNLOADS = 34042, // 0x000084FA + IDS_RESUME_DOWNLOADS = 34043, // 0x000084FB + IDS_DOWNLOAD_TIME_REMAINING = 34044, // 0x000084FC + IDS_DOWNLOAD_TIME_UNTIL_PLAY = 34045, // 0x000084FD + IDS_DOWNLOAD_TIME_FORMAT_ONE_SECOND = 34046, // 0x000084FE + IDS_DOWNLOAD_TIME_FORMAT_N_SECONDS = 34047, // 0x000084FF + IDS_DOWNLOAD_TIME_FORMAT_ONE_MINUTE = 34048, // 0x00008500 + IDS_DOWNLOAD_TIME_FORMAT_N_MINUTES = 34049, // 0x00008501 + IDS_DOWNLOAD_TIME_FORMAT_ONE_HOUR = 34050, // 0x00008502 + IDS_DOWNLOAD_TIME_FORMAT_N_HOURS = 34051, // 0x00008503 + IDS_DOWNLOAD_TIME_FORMAT_ONE_MINUTE_N_SECONDS = 34052, // 0x00008504 + IDS_DOWNLOAD_TIME_FORMAT_N_MINUTES_N_SECONDS = 34053, // 0x00008505 + IDS_DOWNLOAD_TIME_FORMAT_ONE_HOUR_N_MINUTES = 34054, // 0x00008506 + IDS_DOWNLOAD_TIME_FORMAT_N_HOURS_N_MINUTES = 34055, // 0x00008507 + IDS_PLAY_SONG = 34056, // 0x00008508 + IDS_PREVIEW_SONG = 34057, // 0x00008509 + IDS_RENT = 34058, // 0x0000850A + IDS_DOWNLOAD_RETRY_MENUITEM = 34059, // 0x0000850B + IDS_DOWNLOAD_PAUSED_NOTIFICATION = 34060, // 0x0000850C + IDS_DOWNLOAD_SIGNIN_NOTIFICATION = 34061, // 0x0000850D + IDS_SONG_CREDIT_MENUITEM = 34062, // 0x0000850E + IDS_UPDATE = 34063, // 0x0000850F + IDS_TRY = 34064, // 0x00008510 + IDS_BUY_CURRENCY = 34065, // 0x00008511 + IDS_DOWNLOAD_MBR_PAUSED_NOTIFICATION = 34066, // 0x00008512 + IDS_PURCHASE = 34067, // 0x00008513 + IDS_TRIAL = 34068, // 0x00008514 + IDS_BETA = 34069, // 0x00008515 + IDS_BUY_SEASON = 34070, // 0x00008516 + IDS_BUY_SEASON_PASS = 34071, // 0x00008517 + IDS_IMAGE_NOT_AVAILABLE = 35000, // 0x000088B8 + IDS_ASCENDING_SORT = 35001, // 0x000088B9 + IDS_DESCENDING_SORT = 35002, // 0x000088BA + IDS_ASCENDING_TRACK_SORT = 35003, // 0x000088BB + IDS_COLLECTION_PIVOT = 35004, // 0x000088BC + IDS_SOCIAL_PIVOT = 35005, // 0x000088BD + IDS_MARKETPLACE_PIVOT = 35006, // 0x000088BE + IDS_MUSIC_PIVOT = 35007, // 0x000088BF + IDS_VIDEO_PIVOT = 35008, // 0x000088C0 + IDS_PICTURES_PIVOT = 35009, // 0x000088C1 + IDS_PODCASTS_PIVOT = 35010, // 0x000088C2 + IDS_INBOX_PIVOT = 35011, // 0x000088C3 + IDS_FRIENDS_PIVOT = 35012, // 0x000088C4 + IDS_PROFILE_PIVOT = 35013, // 0x000088C5 + IDS_SOCIAL_WITH_MESSAGES_PIVOT = 35014, // 0x000088C6 + IDS_SYNC_STATUS_PIVOT = 35015, // 0x000088C7 + IDS_ALBUMS_HEADER = 35016, // 0x000088C8 + IDS_ARTISTS_HEADER = 35017, // 0x000088C9 + IDS_EPISODES_HEADER = 35018, // 0x000088CA + IDS_PODCASTS_HEADER = 35019, // 0x000088CB + IDS_TRACKS_HEADER = 35020, // 0x000088CC + IDS_DETAILS_HEADER = 35021, // 0x000088CD + IDS_BLANK_COLUMN_HEADER = 35023, // 0x000088CF + IDS_ALBUM_COLUMN_HEADER = 35024, // 0x000088D0 + IDS_ALL_SONGS_COLUMN_HEADER = 35025, // 0x000088D1 + IDS_ARTIST_COLUMN_HEADER = 35026, // 0x000088D2 + IDS_BUY_COLUMN_HEADER = 35027, // 0x000088D3 + IDS_DATE_COLUMN_HEADER = 35028, // 0x000088D4 + IDS_EXPLICIT_COLUMN_HEADER = 35029, // 0x000088D5 + IDS_GENRE_COLUMN_HEADER = 35030, // 0x000088D6 + IDS_LENGTH_COLUMN_HEADER = 35031, // 0x000088D7 + IDS_MEDIA_COLUMN_HEADER = 35032, // 0x000088D8 + IDS_MPAA_COLUMN_HEADER = 35033, // 0x000088D9 + IDS_NOW_PLAYING_COLUMN_HEADER = 35034, // 0x000088DA + IDS_SONG_COLUMN_HEADER = 35035, // 0x000088DB + IDS_STATUS_COLUMN_HEADER = 35036, // 0x000088DC + IDS_TITLE_COLUMN_HEADER = 35038, // 0x000088DE + IDS_FROM_COLUMN_HEADER = 35039, // 0x000088DF + IDS_TYPE_COLUMN_HEADER = 35040, // 0x000088E0 + IDS_SUBJECT_COLUMN_HEADER = 35041, // 0x000088E1 + IDS_RECEIVED_COLUMN_HEADER = 35042, // 0x000088E2 + IDS_CATEGORY_COLUMN_HEADER = 35043, // 0x000088E3 + IDS_DATE_ADDED_COLUMN_HEADER = 35044, // 0x000088E4 + IDS_CONTRIBUTING_ARTIST_COLUMN_HEADER = 35045, // 0x000088E5 + IDS_DATE_LAST_PLAYED_COLUMN_HEADER = 35046, // 0x000088E6 + IDS_PLAY_COUNT_COLUMN_HEADER = 35047, // 0x000088E7 + IDS_SIZE_COLUMN_HEADER = 35048, // 0x000088E8 + IDS_SONG_NUMBER_COLUMN_HEADER = 35049, // 0x000088E9 + IDS_RELEASE_YEAR_COLUMN_HEADER = 35050, // 0x000088EA + IDS_COMPOSER_COLUMN_HEADER = 35051, // 0x000088EB + IDS_PARENTAL_RATING_COLUMN_HEADER = 35052, // 0x000088EC + IDS_PROTECTED_COLUMN_HEADER = 35053, // 0x000088ED + IDS_PUBLISHER_COLUMN_HEADER = 35054, // 0x000088EE + IDS_CONDUCTOR_COLUMN_HEADER = 35055, // 0x000088EF + IDS_SUBGENRE_COLUMN_HEADER = 35056, // 0x000088F0 + IDS_GENRE_UNKNOWN = 35057, // 0x000088F1 + IDS_RELEASE_DATE_UNKNOWN = 35058, // 0x000088F2 + IDS_PROTECTED_YES = 35059, // 0x000088F3 + IDS_PROTECTED_NO = 35060, // 0x000088F4 + IDS_LIBRARY_DELETE_MENU_ITEM = 35061, // 0x000088F5 + IDS_LIBRARY_PROPERTIES_MENU_ITEM = 35062, // 0x000088F6 + IDS_LIBRARY_MENUITEM_HEADER_1_ARTIST = 35063, // 0x000088F7 + IDS_LIBRARY_MENUITEM_HEADER_1_ALBUM = 35064, // 0x000088F8 + IDS_LIBRARY_MENUITEM_HEADER_1_TRACK = 35065, // 0x000088F9 + IDS_LIBRARY_MENUITEM_HEADER_1_PHOTO = 35066, // 0x000088FA + IDS_LIBRARY_MENUITEM_HEADER_1_VIDEO = 35067, // 0x000088FB + IDS_LIBRARY_MENUITEM_HEADER_N_ARTISTS = 35068, // 0x000088FC + IDS_LIBRARY_MENUITEM_HEADER_N_ALBUMS = 35069, // 0x000088FD + IDS_LIBRARY_MENUITEM_HEADER_N_TRACKS = 35070, // 0x000088FE + IDS_LIBRARY_MENUITEM_HEADER_N_PHOTOS = 35071, // 0x000088FF + IDS_LIBRARY_MENUITEM_HEADER_N_VIDEOS = 35072, // 0x00008900 + IDS_LIBRARY_MENUITEM_HEADER_1_FOLDER = 35073, // 0x00008901 + IDS_LIBRARY_MENUITEM_HEADER_N_FOLDERS = 35074, // 0x00008902 + IDS_LIBRARY_MENUITEM_HEADER_N_ITEMS = 35075, // 0x00008903 + IDS_SEARCH_STARTER_TEXT = 35077, // 0x00008905 + IDS_NAVIGATE_BACK = 35078, // 0x00008906 + IDS_LIBRARY_DELETE_FROMLIBRARY = 35079, // 0x00008907 + IDS_LIBRARY_DELETE_FROMLIBRARYANDPC = 35080, // 0x00008908 + IDS_DONT_SHOW_THIS_MESSAGE_AGAIN = 35081, // 0x00008909 + IDS_LIBRARY_QUESTION_1_ITEM = 35082, // 0x0000890A + IDS_LIBRARY_QUESTION_N_ITEMS = 35083, // 0x0000890B + IDS_COLLECTION_BROWSE = 35085, // 0x0000890D + IDS_COLLECTION_LIST = 35086, // 0x0000890E + IDS_LOG_OFF_BUTTON = 35087, // 0x0000890F + IDS_LOG_ON_BUTTON = 35088, // 0x00008910 + IDS_SYNC_PERCENTAGE = 35089, // 0x00008911 + IDS_SYNC_STATUS = 35090, // 0x00008912 + IDS_PLAYLISTS_HEADER = 35091, // 0x00008913 + IDS_LIBRARY_MENUITEM_HEADER_1_PLAYLIST = 35092, // 0x00008914 + IDS_LIBRARY_MENUITEM_HEADER_N_PLAYLISTS = 35093, // 0x00008915 + IDS_DOWNLOADS_PIVOT = 35094, // 0x00008916 + IDS_ACTIVEDOWNLOADS_PIVOT = 35095, // 0x00008917 + IDS_PURCHASEDDOWNLOADS_PIVOT = 35096, // 0x00008918 + IDS_SUBSCRIPTIONDOWNLOADS_PIVOT = 35097, // 0x00008919 + IDS_PURCHASEDDOWNLOADS_DESCRIPTION = 35099, // 0x0000891B + IDS_SUBSCRIPTIONDOWNLOADS_DESCRIPTION = 35100, // 0x0000891C + IDS_ALBUM_SERIES_COLUMN_HEADER = 35101, // 0x0000891D + IDS_NOACTIVEDOWNLOADS_DESCRIPTION = 35102, // 0x0000891E + IDS_ACTIONS_COLUMN_HEADER = 35103, // 0x0000891F + IDS_LIBRARY_EDIT_MENU_ITEM = 35104, // 0x00008920 + IDS_SYNC_STATUS_COLUMN_HEADER_TOOLTIP = 35105, // 0x00008921 + IDS_LIBRARY_RATE_MENU_ITEM = 35106, // 0x00008922 + IDS_ALBUM_ARTIST_COLUMN_HEADER = 35107, // 0x00008923 + IDS_PLAYLISTS_PIVOT = 35108, // 0x00008924 + IDS_RATING_COLUMN_HEADER = 35109, // 0x00008925 + IDS_SYNC_STATUS_COLUMN_HEADER = 35110, // 0x00008926 + IDS_CHOOSE_COLUMN_MENU_ITEM = 35111, // 0x00008927 + IDS_CHOOSE_COLUMN_TITLE = 35112, // 0x00008928 + IDS_TRANSCODE_STATUS = 35113, // 0x00008929 + IDS_LIBRARY_IMPORTING_MEDIA = 35114, // 0x0000892A + IDS_LIBRARY_ADD_FILE = 35115, // 0x0000892B + IDS_LIBRARY_SCAN_COMPLETE = 35116, // 0x0000892C + IDS_LIBRARY_FILE_CHANGE_COMPLETE = 35117, // 0x0000892D + IDS_CONTRIBUTING_ARTISTS_SEPARATION_FORMAT = 35119, // 0x0000892F + IDS_SYNC_STATUS_COLUMN_TOOLTIP_SYNCING = 35125, // 0x00008935 + IDS_SYNC_STATUS_COLUMN_TOOLTIP_ONDEVICE = 35126, // 0x00008936 + IDS_SYNC_STATUS_COLUMN_TOOLTIP_EXCLUDED = 35127, // 0x00008937 + IDS_LIBRARY_MENUITEM_HEADER_1_PODCAST = 35128, // 0x00008938 + IDS_LIBRARY_MENUITEM_HEADER_N_PODCASTS = 35129, // 0x00008939 + IDS_PLAYLIST_DELETE_FROMLIBRARY = 35131, // 0x0000893B + IDS_PLAYLIST_DELETE_FROMLIBRARYANDPC = 35132, // 0x0000893C + IDS_LIBRARY_METADATA_UPDATE = 35133, // 0x0000893D + IDS_LIBRARY_METADATA_UPDATE_INFO = 35134, // 0x0000893E + IDS_LIBRARY_MEDIATYPE_AUDIOMP4 = 35135, // 0x0000893F + IDS_LIBRARY_MEDIATYPE_AUDIOMP3 = 35136, // 0x00008940 + IDS_LIBRARY_MEDIATYPE_AUDIOWMA = 35137, // 0x00008941 + IDS_LIBRARY_MEDIATYPE_AUDIOQT = 35138, // 0x00008942 + IDS_LIBRARY_MEDIATYPE_AUDIOWAV = 35139, // 0x00008943 + IDS_LIBRARY_MEDIATYPE_IMAGEJPEG = 35140, // 0x00008944 + IDS_LIBRARY_MEDIATYPE_VIDEOMP4 = 35141, // 0x00008945 + IDS_LIBRARY_MEDIATYPE_VIDEOMPG = 35142, // 0x00008946 + IDS_LIBRARY_MEDIATYPE_VIDEOWMV = 35143, // 0x00008947 + IDS_LIBRARY_MEDIATYPE_VIDEOQT = 35144, // 0x00008948 + IDS_LIBRARY_MEDIATYPE_VIDEODVRMS = 35145, // 0x00008949 + IDS_NOPURCHASEDDOWNLOADS_DESCRIPTION = 35146, // 0x0000894A + IDS_NOSUBSCRIPTIONDOWNLOADS_DESCRIPTION = 35147, // 0x0000894B + IDS_HISTORY_MUST_LOGON_TEXT = 35148, // 0x0000894C + IDS_DEVICE_PIVOT = 35149, // 0x0000894D + IDS_DISC_PIVOT = 35150, // 0x0000894E + IDS_SOFTWARE_PIVOT = 35151, // 0x0000894F + IDS_SETTINGS_PIVOT = 35152, // 0x00008950 + IDS_LIBRARY_MENUITEM_HEADER_1_PODCASTEPISODE = 35153, // 0x00008951 + IDS_LIBRARY_MENUITEM_HEADER_N_PODCASTEPISODES = 35154, // 0x00008952 + IDS_CHANGE_TAG_BUTTON = 35155, // 0x00008953 + IDS_LIBRARY_ADD_FILE_FAILED = 35156, // 0x00008954 + IDS_LIBRARY_ADD_FILE_FAILED_SUBMESSAGE = 35157, // 0x00008955 + IDS_DELETING_STATUS = 35158, // 0x00008956 + IDS_INBOX_DETAILS_NOSELECT_HEADER = 35159, // 0x00008957 + IDS_INBOX_DETAILS_HEADER = 35160, // 0x00008958 + IDS_DESCENDING_RATING_SORT = 35161, // 0x00008959 + IDS_RELEASE_YEAR_SORT = 35162, // 0x0000895A + IDS_HISTORY_DOWNLOAD_ALL_BUTTON = 35165, // 0x0000895D + IDS_HISTORY_PURCHASE_MUSIC_PIVOT = 35166, // 0x0000895E + IDS_VIDEO_EPISODE_COLUMN_HEADER = 35168, // 0x00008960 + IDS_TRANSPORT_MUSIC_SELECTOR = 35169, // 0x00008961 + IDS_TRANSPORT_SLIDESHOW_SELECTOR = 35170, // 0x00008962 + IDS_MUSIC_EMPTY = 35171, // 0x00008963 + IDS_MUSIC_EMPTY_SETTINGS_LINK = 35172, // 0x00008964 + IDS_MUSIC_EMPTY_MARKETPLACE_LINK = 35173, // 0x00008965 + IDS_VIDEO_EMPTY = 35174, // 0x00008966 + IDS_VIDEO_EMPTY_SETTINGS_LINK = 35175, // 0x00008967 + IDS_VIDEO_EMPTY_MARKETPLACE_LINK = 35176, // 0x00008968 + IDS_PHOTO_EMPTY = 35177, // 0x00008969 + IDS_PHOTO_EMPTY_SETTINGS_LINK = 35178, // 0x0000896A + IDS_PLAYLIST_EMPTY_TITLE = 35179, // 0x0000896B + IDS_DRM_PERMANENT_LICENSE_DESC = 35180, // 0x0000896C + IDS_DRM_NO_LICENSE_DESC = 35181, // 0x0000896D + IDS_DRM_SUBSCRIPTION_LICENSE_DESC = 35182, // 0x0000896E + IDS_DRM_LICENSE_EXPIRED_DESC = 35183, // 0x0000896F + IDS_DRM_HAS_SYNC_RIGHTS = 35184, // 0x00008970 + IDS_DRM_NO_SYNC_RIGHTS = 35185, // 0x00008971 + IDS_DRM_HAS_BURN_RIGHTS = 35186, // 0x00008972 + IDS_DRM_NO_BURN_RIGHTS = 35187, // 0x00008973 + IDS_DRM_UNKNOWN = 35188, // 0x00008974 + IDS_ACCOUNT_PIVOT = 35189, // 0x00008975 + IDS_SIGN_OUT_BUTTON = 35190, // 0x00008976 + IDS_ZUNE_ACCOUNT_HEADER = 35191, // 0x00008977 + IDS_ZUNE_MARKETPLACE_HEADER = 35192, // 0x00008978 + IDS_DEVICE_QUESTION_1_ITEM = 35193, // 0x00008979 + IDS_DEVICE_QUESTION_N_ITEMS = 35194, // 0x0000897A + IDS_COLLECTION_DELETE_TITLE = 35195, // 0x0000897B + IDS_STATUS_COLUMN_DATA_HEADER = 35196, // 0x0000897C + IDS_ITEM_COLUMN_HEADER = 35197, // 0x0000897D + IDS_LIBRARY_MERGE_ALBUMS = 35198, // 0x0000897E + IDS_LIBRARY_FIND_IN_MARKETPLACE = 35199, // 0x0000897F + IDS_LIBRARY_RENAME_MENU_ITEM = 35200, // 0x00008980 + IDS_INBOX_MULTISELECT_HEADER = 35201, // 0x00008981 + IDS_CONTRIBUTING_ARTISTS_SEPARATOR = 35202, // 0x00008982 + IDS_LIBRARY_PROPERTIES_DIALOG = 35203, // 0x00008983 + IDS_ARTIST_SORT = 35204, // 0x00008984 + IDS_ALBUM_SORT = 35205, // 0x00008985 + IDS_COLLECTION_GENRE = 35206, // 0x00008986 + IDS_GENRES_HEADER = 35207, // 0x00008987 + IDS_RATING_COLUMN_TOOLTIP_SINGLE = 35208, // 0x00008988 + IDS_RATING_COLUMN_TOOLTIP_MULTIPLE = 35209, // 0x00008989 + IDS_PLAYLISTTYPE_SORT = 35210, // 0x0000898A + IDS_COLLECTION_VIDEO_ALL_PIVOT = 35211, // 0x0000898B + IDS_COLLECTION_VIDEO_TV_PIVOT = 35212, // 0x0000898C + IDS_COLLECTION_VIDEO_MUSIC_PIVOT = 35213, // 0x0000898D + IDS_COLLECTION_VIDEO_MOVIES_PIVOT = 35214, // 0x0000898E + IDS_COLLECTION_VIDEO_OTHER_PIVOT = 35215, // 0x0000898F + IDS_COLLECTION_VIDEO_TV = 35216, // 0x00008990 + IDS_COLLECTION_VIDEO_MUSIC = 35217, // 0x00008991 + IDS_COLLECTION_VIDEO_MOVIES = 35218, // 0x00008992 + IDS_COLLECTION_VIDEO_OTHER = 35219, // 0x00008993 + IDS_UNREAD_MESSAGE_PLURAL = 35220, // 0x00008994 + IDS_UNREAD_MESSAGE_SINGULAR = 35221, // 0x00008995 + IDS_PENDING_PURCHASE_PLURAL = 35222, // 0x00008996 + IDS_PENDING_PURCHASE_SINGULAR = 35223, // 0x00008997 + IDS_LIBRARY_FINDALBUMINFO_MENU_ITEM = 35224, // 0x00008998 + IDS_PLAYLIST_TRACK_NUMBER_COLUMN_HEADER = 35225, // 0x00008999 + IDS_NETWORK_COLUMN_HEADER = 35226, // 0x0000899A + IDS_SEASON_COLUMN_HEADER = 35227, // 0x0000899B + IDS_SERIES_COLUMN_HEADER = 35228, // 0x0000899C + IDS_EPISODE_COLUMN_HEADER = 35229, // 0x0000899D + IDS_CART_PIVOT = 35230, // 0x0000899E + IDS_COLLECTION_VIDEO_TV_SERIES = 35231, // 0x0000899F + IDS_COLLECTION_VIDEO_TV_SHORTS = 35232, // 0x000089A0 + IDS_COLLECTION_VIDEO_TV_NEWS = 35233, // 0x000089A1 + IDS_VIDEO_TV_EMPTY = 35234, // 0x000089A2 + IDS_VIDEO_TV_EMPTY_MARKETPLACE_LINK = 35235, // 0x000089A3 + IDS_VIDEO_MUSIC_EMPTY = 35236, // 0x000089A4 + IDS_VIDEO_MUSIC_EMPTY_MARKETPLACE_LINK = 35237, // 0x000089A5 + IDS_VIDEO_MOVIES_EMPTY = 35238, // 0x000089A6 + IDS_VIDEO_OTHER_EMPTY = 35239, // 0x000089A7 + IDS_SONG_ARTISTS_COLUMN_HEADER = 35240, // 0x000089A8 + IDS_GENERIC_ERROR = 35241, // 0x000089A9 + IDS_UNKNOWN_YEAR = 35242, // 0x000089AA + IDS_ACTIVEDOWNLOADS_SIGNIN_REQUIRED = 35243, // 0x000089AB + IDS_HISTORY_PURCHASE_MUSIC_VIDEO_PIVOT = 35244, // 0x000089AC + IDS_CONFIRM_PASTE_ALBUM_ART = 35245, // 0x000089AD + IDS_CONFIRM_PASTE_ALBUM_ART_NO_NAME = 35246, // 0x000089AE + IDS_CONFIRM_PASTE_ALBUM_ART_TITLE = 35247, // 0x000089AF + IDS_DATETIME_NUMERIC_MONTH_DAY_PATTERN = 35248, // 0x000089B0 + IDS_COLLECTION_ALBUM = 35249, // 0x000089B1 + IDS_CHANNELS_PIVOT = 35251, // 0x000089B3 + IDS_LIBRARY_QUESTION_MANUAL_1_ITEM = 35252, // 0x000089B4 + IDS_LIBRARY_QUESTION_MANUAL_N_ITEMS = 35253, // 0x000089B5 + IDS_CHANNELS_HEADER = 35254, // 0x000089B6 + IDS_DATETIME_NUMERIC_MONTH_YEAR_PATTERN = 35255, // 0x000089B7 + IDS_DUPLICATE_STATUS_COLUMN_HEADER = 35256, // 0x000089B8 + IDS_UPDATING_STATUS = 35257, // 0x000089B9 + IDS_SYNC_STATUS_GROUP = 35258, // 0x000089BA + IDS_RECOMMENDATIONS_PIVOT = 35259, // 0x000089BB + IDS_LIBRARY_FILE_DELETE_FAILED = 35260, // 0x000089BC + IDS_LIBRARY_GENERATING_FINGERPRINT = 35261, // 0x000089BD + IDS_TUNNELLING_STATUS = 35262, // 0x000089BE + IDS_GENERIC_ELLIPSIS = 35263, // 0x000089BF + IDS_QUICKPLAY_PIVOT = 35264, // 0x000089C0 + IDS_MOVE_UP_MENU_ITEM = 35266, // 0x000089C2 + IDS_MOVE_DOWN_MENU_ITEM = 35267, // 0x000089C3 + IDS_DRM_HEADER_NO_LICENSE = 35268, // 0x000089C4 + IDS_DRM_HEADER_PERSONAL = 35269, // 0x000089C5 + IDS_DRM_HEADER_PURCHASED = 35270, // 0x000089C6 + IDS_DRM_HEADER_RENTAL = 35271, // 0x000089C7 + IDS_DRM_HEADER_SUBSCRIPTION = 35272, // 0x000089C8 + IDS_DRM_HEADER_UNKNOWN = 35273, // 0x000089C9 + IDS_PRESS_ESC_TO_EXIT = 35274, // 0x000089CA + IDS_SWITCH_BUTTON = 35275, // 0x000089CB + IDS_FILESIZE_DEFAULT_FORMAT = 35276, // 0x000089CC + IDS_FILESIZE_DEFAULT_FORMAT_SMALL = 35277, // 0x000089CD + IDS_FILESIZE_UNITS_KB = 35278, // 0x000089CE + IDS_FILESIZE_UNITS_MB = 35279, // 0x000089CF + IDS_FILESIZE_UNITS_GB = 35280, // 0x000089D0 + IDS_LIBRARY_QUESTION_RENTAL_1_ITEM = 35281, // 0x000089D1 + IDS_LIBRARY_QUESTION_RENTAL_N_ITEMS = 35282, // 0x000089D2 + IDS_LIBRARY_QUESTION_MIXED_RENTAL_N_ITEMS = 35283, // 0x000089D3 + IDS_LIBRARY_QUESTION_MIXED_RENTAL_MANUAL_N_ITEMS = 35284, // 0x000089D4 + IDS_ADD_TO_QUICKPLAY = 35285, // 0x000089D5 + IDS_REMOVE_FROM_QUICKPLAY = 35286, // 0x000089D6 + IDS_CONTENT_TYPE_COLUMN_HEADER = 35287, // 0x000089D7 + IDS_DRM_HEADER_SUBSCRIPTION_EXPIRED = 35288, // 0x000089D8 + IDS_DRM_HEADER_PROTECTED = 35289, // 0x000089D9 + IDS_COLLECTION_CONTENT_TYPES_ALL = 35290, // 0x000089DA + IDS_COLLECTION_CONTENT_TYPES_PERSONAL = 35291, // 0x000089DB + IDS_COLLECTION_CONTENT_TYPES_PROTECTED = 35292, // 0x000089DC + IDS_COLLECTION_CONTENT_TYPES_ZUNEPASS = 35293, // 0x000089DD + IDS_OVERLAY_MIXVIEW_TOOLTIP = 35296, // 0x000089E0 + IDS_MUSIC_DEVICE_EMPTY = 35297, // 0x000089E1 + IDS_VIDEO_DEVICE_EMPTY = 35298, // 0x000089E2 + IDS_PHOTO_DEVICE_EMPTY = 35299, // 0x000089E3 + IDS_PLAYLIST_DEVICE_EMPTY_TITLE = 35300, // 0x000089E4 + IDS_ACTORS_SEPARATION_FORMAT = 35305, // 0x000089E9 + IDS_DIRECTORS_SEPARATION_FORMAT = 35306, // 0x000089EA + IDS_LIBRARY_MEDIATYPE_VIDEOMBR = 35307, // 0x000089EB + IDS_APPS_PIVOT = 35308, // 0x000089EC + IDS_TEST_PIVOT = 35309, // 0x000089ED + IDS_COLLECTION_CONTENT_TYPES_LABEL = 35310, // 0x000089EE + IDS_HISTORY_PURCHASE_TV_PIVOT = 35311, // 0x000089EF + IDS_HISTORY_PURCHASE_MOVIE_PIVOT = 35312, // 0x000089F0 + IDS_VIDEO_MOVIES_EMPTY_MARKETPLACE_LINK = 35313, // 0x000089F1 + IDS_FILTERED_LIBRARY_QUESTION_1_ITEM = 35314, // 0x000089F2 + IDS_FILTERED_LIBRARY_DELETE_1_ALBUM = 35315, // 0x000089F3 + IDS_FILTERED_LIBRARY_DELETE_1_ARTIST = 35316, // 0x000089F4 + IDS_FILTERED_LIBRARY_DELETE_1_GENRE = 35317, // 0x000089F5 + IDS_FILTERED_LIBRARY_QUESTION_N_ITEMS = 35318, // 0x000089F6 + IDS_FILTERED_LIBRARY_DELETE_N_ALBUMS = 35319, // 0x000089F7 + IDS_FILTERED_LIBRARY_DELETE_N_ARTISTS = 35320, // 0x000089F8 + IDS_FILTERED_LIBRARY_DELETE_N_GENRES = 35321, // 0x000089F9 + IDS_YEAR_COLUMN_HEADER = 35322, // 0x000089FA + IDS_DATETIME_YEAR_ABBREVIATION = 35323, // 0x000089FB + IDS_DATETIME_MONTH_ABBREVIATION = 35324, // 0x000089FC + IDS_DATETIME_DAY_ABBREVIATION = 35325, // 0x000089FD + IDS_RENTALHISTORY_DESCRIPTION = 35326, // 0x000089FE + IDS_NORENTALHISTORY_DESCRIPTION = 35327, // 0x000089FF + IDS_DRM_DEVICE_LICENSE_DESC = 35328, // 0x00008A00 + IDS_SPLASH_UPDATING_COLLECTION = 35329, // 0x00008A01 + IDS_SPLASH_VERSION = 35330, // 0x00008A02 + IDS_DELETE_TRACK_WITH_MULTIPLE_FILES = 35331, // 0x00008A03 + IDS_LIBRARY_MEDIATYPE_VIDEOAVI = 35332, // 0x00008A04 + IDS_ALBUM_HEADER = 35333, // 0x00008A05 + IDS_ARTIST_HEADER = 35334, // 0x00008A06 + IDS_GENRE_HEADER = 35335, // 0x00008A07 + IDS_EPISODE_HEADER = 35336, // 0x00008A08 + IDS_PODCAST_HEADER = 35337, // 0x00008A09 + IDS_CHANNEL_HEADER = 35338, // 0x00008A0A + IDS_TRACK_HEADER = 35339, // 0x00008A0B + IDS_PLAYLIST_HEADER = 35340, // 0x00008A0C + IDS_DATETIME_MONTH_DAY_YEAR_PATTERN = 35341, // 0x00008A0D + IDS_HISTORY_PURCHASE_WINPHONE_APPS_PIVOT = 35342, // 0x00008A0E + IDS_PURCHASED_APP_DOWNLOADS_DESCRIPTION = 35343, // 0x00008A0F + IDS_PHONE_PIVOT = 35344, // 0x00008A10 + IDS_CAPS_LOCK_IS_ON_TOOLTIP = 35345, // 0x00008A11 + IDS_PLAYLIST_MEDIA_NOTACCESSIBLE = 35346, // 0x00008A12 + IDS_GENERAL_MENU_ITEM = 36000, // 0x00008CA0 + IDS_COLLECTION_MENU_ITEM = 36001, // 0x00008CA1 + IDS_FILE_TYPE_MENU_ITEM = 36002, // 0x00008CA2 + IDS_PRIVACY_MENU_ITEM = 36003, // 0x00008CA3 + IDS_PODCAST_MENU_ITEM = 36004, // 0x00008CA4 + IDS_SHARING_MENU_ITEM = 36006, // 0x00008CA6 + IDS_PHOTO_MENU_ITEM = 36007, // 0x00008CA7 + IDS_RIP_MENU_ITEM = 36008, // 0x00008CA8 + IDS_BURN_MENU_ITEM = 36009, // 0x00008CA9 + IDS_MARKETPLACE_MENU_ITEM = 36010, // 0x00008CAA + IDS_GB_FORMAT_STRING = 36011, // 0x00008CAB + IDS_CLIENT_UPDATE_HEADER = 36012, // 0x00008CAC + IDS_CLIENT_UPDATE_DESC = 36013, // 0x00008CAD + IDS_FIRMWARE_UPDATE_HEADER = 36015, // 0x00008CAF + IDS_FIRMWARE_CURRENT_VERSION = 36016, // 0x00008CB0 + IDS_FIRMWARE_UPDATING_VERSION = 36018, // 0x00008CB2 + IDS_FIRMWARE_UPDATE_PREPARING = 36019, // 0x00008CB3 + IDS_FIRMWARE_UPDATE_WARNING = 36020, // 0x00008CB4 + IDS_FIRMWARE_UPDATE_COMPLETE = 36021, // 0x00008CB5 + IDS_FIRMWARE_UPDATE_FAILURE = 36022, // 0x00008CB6 + IDS_FIRMWARE_UPDATE_SIZE = 36023, // 0x00008CB7 + IDS_CANCEL_BUTTON = 36024, // 0x00008CB8 + IDS_UPDATE_BUTTON = 36025, // 0x00008CB9 + IDS_SKIP_BUTTON = 36026, // 0x00008CBA + IDS_SETTINGS_BUTTON = 36027, // 0x00008CBB + IDS_FINISH_BUTTON = 36028, // 0x00008CBC + IDS_OK_BUTTON = 36030, // 0x00008CBE + IDS_SELECT_ALL_BUTTON = 36031, // 0x00008CBF + IDS_PRIVACY_STATEMENT_BUTTON = 36033, // 0x00008CC1 + IDS_ADD_FOLDER_BUTTON = 36034, // 0x00008CC2 + IDS_REMOVE_FOLDER_BUTTON = 36035, // 0x00008CC3 + IDS_CHECK_FOR_UPDATE_BUTTON = 36036, // 0x00008CC4 + IDS_RESET_WARNINGS_BUTTON = 36037, // 0x00008CC5 + IDS_SUBCRIPTION_BUTTON = 36038, // 0x00008CC6 + IDS_MEDIA_FOLDER_BUTTON = 36039, // 0x00008CC7 + IDS_SHARING_INFO_BUTTON = 36040, // 0x00008CC8 + IDS_USAGE_DATA_CHECK = 36041, // 0x00008CC9 + IDS_CRASH_DATA_CHECK = 36042, // 0x00008CCA + IDS_NORMALIZE_VOLUME_CHECK = 36043, // 0x00008CCB + IDS_BURN_AUTO_EJECT_CHECK = 36044, // 0x00008CCC + IDS_SCAN_REMOVED_FILES = 36045, // 0x00008CCD + IDS_IMPORT_DATA_CHECK = 36046, // 0x00008CCE + IDS_UPDATE_METADATA_CHECK = 36047, // 0x00008CCF + IDS_PERMANENT_DELETE_CHECK = 36048, // 0x00008CD0 + IDS_ADD_PLAYED_MEDIA_CHECK = 36050, // 0x00008CD2 + IDS_ALLOW_SCREENSAVERS_CHECK = 36051, // 0x00008CD3 + IDS_ACCELERATION_CHECK = 36055, // 0x00008CD7 + IDS_SHARE_MUSIC_CHECK = 36058, // 0x00008CDA + IDS_SHARE_PICTURES_CHECK = 36059, // 0x00008CDB + IDS_SHARE_PODCASTS_CHECK = 36060, // 0x00008CDC + IDS_SHARE_VIDEOS_CHECK = 36062, // 0x00008CDE + IDS_BURN_AUDIO_OPTION = 36063, // 0x00008CDF + IDS_BURN_LOWER_RATE_OPTION = 36064, // 0x00008CE0 + IDS_BURN_DATA_OPTION = 36065, // 0x00008CE1 + IDS_BURN_KEEP_RATE_OPTION = 36066, // 0x00008CE2 + IDS_BURN_FAST_OPTION = 36067, // 0x00008CE3 + IDS_BURN_FASTEST_OPTION = 36068, // 0x00008CE4 + IDS_BURN_MEDIUM_OPTION = 36069, // 0x00008CE5 + IDS_BURN_SLOW_OPTION = 36070, // 0x00008CE6 + IDS_DONT_CHECK_OPTION = 36071, // 0x00008CE7 + IDS_CHECK_MONTHLY_OPTION = 36072, // 0x00008CE8 + IDS_CHECK_WEEKLY_OPTION = 36073, // 0x00008CE9 + IDS_SYNC_UNPLAYED_OPTION = 36080, // 0x00008CF0 + IDS_MP3_OPTION = 36081, // 0x00008CF1 + IDS_WMA_OPTION = 36082, // 0x00008CF2 + IDS_WMA_LOSSLESS_OPTION = 36083, // 0x00008CF3 + IDS_WMA_VARIABLE_OPTION = 36084, // 0x00008CF4 + IDS_SELECTIVE_SHARING_OPTION = 36085, // 0x00008CF5 + IDS_GLOBAL_SHARING_OPTION = 36086, // 0x00008CF6 + IDS_KEEP_15EPISODES = 36087, // 0x00008CF7 + IDS_KEEP_5EPISODES = 36088, // 0x00008CF8 + IDS_NEWEST_FIRST_OPTION = 36089, // 0x00008CF9 + IDS_OLDEST_FIRST_OPTION = 36090, // 0x00008CFA + IDS_CONFIGURE_FOLDERS = 36099, // 0x00008D03 + IDS_CONFIGURE_FILE_TYPES = 36100, // 0x00008D04 + IDS_SETTINGS_HEADER = 36101, // 0x00008D05 + IDS_PRIVACY_HEADER = 36102, // 0x00008D06 + IDS_SETTINGS_DESCRIPTION = 36103, // 0x00008D07 + IDS_FILE_TYPES_HEADER = 36105, // 0x00008D09 + IDS_FILE_TYPES_DESCRIPTION = 36108, // 0x00008D0C + IDS_MONITORED_FOLDERS_HEADER = 36110, // 0x00008D0E + IDS_MONITORED_FOLDERS_LIST = 36111, // 0x00008D0F + IDS_PRIVACY_SETTINGS = 36113, // 0x00008D11 + IDS_USAGE_DATA_HEADER = 36114, // 0x00008D12 + IDS_LARGEST_BIT_RATE = 36115, // 0x00008D13 + IDS_BURN_SPEED_HEADER = 36116, // 0x00008D14 + IDS_BURN_LOWER_RATE_HEADER = 36117, // 0x00008D15 + IDS_BURN_FORMAT_HEADER = 36118, // 0x00008D16 + IDS_SMALLEST_BIT_RATE = 36119, // 0x00008D17 + IDS_COLLECTION_OPTIONS_HEADER = 36120, // 0x00008D18 + IDS_MONITOR_DESCRIPTION = 36121, // 0x00008D19 + IDS_CHECK_FREQUENCY_HEADER = 36122, // 0x00008D1A + IDS_GENERAL_SETTINGS_HEADER = 36123, // 0x00008D1B + IDS_SPEED_HEADER = 36125, // 0x00008D1D + IDS_KEEP_COUNT_HEADER = 36128, // 0x00008D20 + IDS_KEEP_COUNT_NOTE = 36129, // 0x00008D21 + IDS_PLAYBACK_ORDER_HEADER = 36130, // 0x00008D22 + IDS_SYNC_HEADER = 36131, // 0x00008D23 + IDS_ADD_URL_DESCRIPTION = 36132, // 0x00008D24 + IDS_AUDIO_QUALITY_HEADER = 36134, // 0x00008D26 + IDS_MEDIA_FOLDER_HEADER = 36136, // 0x00008D28 + IDS_RIP_FORMAT_HEADER = 36137, // 0x00008D29 + IDS_SHARE_TYPE_HEADER = 36139, // 0x00008D2B + IDS_LIBRARY_NAME = 36140, // 0x00008D2C + IDS_SIZE_IN_GB = 36142, // 0x00008D2E + IDS_NAME_ZUNE_HEADER = 36143, // 0x00008D2F + IDS_SYNC_OPTIONS_HEADER = 36144, // 0x00008D30 + IDS_WIRELESS_ON_NOTE = 36145, // 0x00008D31 + IDS_VIEW_WARNINGS_HEADER = 36148, // 0x00008D34 + IDS_GO_TO_APP_BUTTON = 36149, // 0x00008D35 + IDS_CONFIGURE_BUTTON = 36150, // 0x00008D36 + IDS_FIRSTRUN_GREETING = 36151, // 0x00008D37 + IDS_FIRSTRUN_DESCRIPTION = 36152, // 0x00008D38 + IDS_GO_TO_APP_HEADER = 36153, // 0x00008D39 + IDS_CONFIGURE_HEADER = 36154, // 0x00008D3A + IDS_CONFIGURE_DETAILS = 36155, // 0x00008D3B + IDS_FIRMWARE_DOWNLOADING = 36156, // 0x00008D3C + IDS_FIRMWARE_TRANSFERRING = 36157, // 0x00008D3D + IDS_FIRMWARE_INSTALLING = 36158, // 0x00008D3E + IDS_SETTINGS_LAND_HEADER = 36159, // 0x00008D3F + IDS_MISSING_METADATA = 36160, // 0x00008D40 + IDS_OVERWRITE_METADATA = 36161, // 0x00008D41 + IDS_AUTO_RIP = 36162, // 0x00008D42 + IDS_EJECT_AFTER_RIP = 36163, // 0x00008D43 + IDS_SYNC_PROMPT = 36164, // 0x00008D44 + IDS_REGDEVICES_PAGE_TEXT = 36165, // 0x00008D45 + IDS_REGDEVICES_HEADER_TEXT = 36166, // 0x00008D46 + IDS_REGDEVICES_PAGE_TEXT_3 = 36167, // 0x00008D47 + IDS_REGDEVICES_MUST_LOGON_TEXT = 36168, // 0x00008D48 + IDS_REGDEVICES_LASTUSED_COLUMN_HEADER = 36169, // 0x00008D49 + IDS_REGDEVICES_COMPUTERS_COLUMN_HEADER = 36170, // 0x00008D4A + IDS_REGDEVICES_DEVICES_COLUMN_HEADER = 36171, // 0x00008D4B + IDS_GO_TO_APP_DETAILS = 36172, // 0x00008D4C + IDS_COLLECTION_AUDIO = 36173, // 0x00008D4D + IDS_COLLECTION_VIDEO = 36174, // 0x00008D4E + IDS_COLLECTION_PHOTO = 36175, // 0x00008D4F + IDS_COLLECTION_PODCAST = 36176, // 0x00008D50 + IDS_ADD_MONITORED_FOLDER_DIALOG_TITLE = 36177, // 0x00008D51 + IDS_CHANGE_MEDIA_FOLDER_DIALOG_TITLE = 36178, // 0x00008D52 + IDS_SYNC_NONE_OPTION = 36179, // 0x00008D53 + IDS_SYNC_ALL_DOWNLOADED_OPTION = 36180, // 0x00008D54 + IDS_SYNC_FIRST_UNPLAYED_OPTION = 36181, // 0x00008D55 + IDS_CHECK_FOR_UPDATES_FAILED = 36182, // 0x00008D56 + IDS_UPDATE_AVAILABLE = 36183, // 0x00008D57 + IDS_UPDATE_INSTALL_NOW = 36184, // 0x00008D58 + IDS_UPDATE_INSTALL_LATER = 36185, // 0x00008D59 + IDS_UPDATE_NOT_REQUIRED = 36186, // 0x00008D5A + IDS_KEEP_1_OPTION = 36187, // 0x00008D5B + IDS_KEEP_ALL_OPTION = 36192, // 0x00008D60 + IDS_PRIVACY_STATEMENT_URL = 36193, // 0x00008D61 + IDS_FIRMWARE_UPDATE_UNAVAILABLE = 36194, // 0x00008D62 + IDS_SHARING_MOREINFO_URL = 36195, // 0x00008D63 + IDS_SET_UP_YOUR_ZUNE = 36196, // 0x00008D64 + IDS_RELOCATING = 36197, // 0x00008D65 + IDS_EXISTING_PARTNERSHIP = 36198, // 0x00008D66 + IDS_ALWAYS_CONNECT_AS_GUEST = 36201, // 0x00008D69 + IDS_ASSOCIATE_YOUR_ZUNE = 36202, // 0x00008D6A + IDS_ASSOCIATE_ZUNE_OFFER_LOGGEDOUT = 36203, // 0x00008D6B + IDS_ASSOCIATE_ZUNE_OFFER_LOGGEDOUT_YES = 36204, // 0x00008D6C + IDS_ASSOCIATE_ZUNE_OFFER_LOGGEDIN = 36206, // 0x00008D6E + IDS_ASSOCIATE_ZUNE_OFFER_LOGGEDIN_YES = 36207, // 0x00008D6F + IDS_ASSOCIATED_ZUNE = 36209, // 0x00008D71 + IDS_CHANGE_BUTTON = 36210, // 0x00008D72 + IDS_OPEN_FILE_DIALOG_TITLE = 36211, // 0x00008D73 + IDS_FIRMWARE_UPDATE_PROGRESS = 36222, // 0x00008D7E + IDS_WIRELESS_SYNC_HEADER = 36223, // 0x00008D7F + IDS_WIRELESS_NAME_HEADER = 36224, // 0x00008D80 + IDS_WIRELESS_KEY_HEADER = 36225, // 0x00008D81 + IDS_WIRELESS_HELP = 36238, // 0x00008D8E + IDS_WIRELESS_SAVE_SETTINGS = 36243, // 0x00008D93 + IDS_WIRELESS_SETTINGS_AUTO_CONFIG_DESCRIPTION = 36247, // 0x00008D97 + IDS_WIRELESS_SETTINGS_MANUAL_CONFIG = 36248, // 0x00008D98 + IDS_WIRELESS_SETTINGS_SCAN = 36249, // 0x00008D99 + IDS_WIRELESS_SETTINGS_ATTEMPTING = 36250, // 0x00008D9A + IDS_WIRELESS_SETTINGS_SNIFFING = 36252, // 0x00008D9C + IDS_FORMAT_DEVICE_BUTTON = 36253, // 0x00008D9D + IDS_DELETE_DEVICE_BUTTON = 36254, // 0x00008D9E + IDS_FORMAT_IN_PROGRESS = 36255, // 0x00008D9F + IDS_LAUNCH_ON_ZUNE_CONNECT = 36256, // 0x00008DA0 + IDS_DELETE_DIALOG_TITLE = 36257, // 0x00008DA1 + IDS_DELETE_DIALOG_TEXT = 36258, // 0x00008DA2 + IDS_TRANSCODING_HEADER = 36259, // 0x00008DA3 + IDS_CACHE_LOCATION_HEADER = 36260, // 0x00008DA4 + IDS_CACHE_LOCATION_BUTTON = 36261, // 0x00008DA5 + IDS_CACHE_CLEAR_BUTTON = 36262, // 0x00008DA6 + IDS_CACHE_SIZE_HEADER = 36263, // 0x00008DA7 + IDS_CACHE_SIZE_PREFIX = 36264, // 0x00008DA8 + IDS_CACHE_SIZE_POSTFIX = 36265, // 0x00008DA9 + IDS_CACHE_USE_HEADER = 36266, // 0x00008DAA + IDS_CACHE_TRANSCODE_IN_BACKGROUND = 36267, // 0x00008DAB + IDS_SPACE_RESERVATION_HEADER = 36268, // 0x00008DAC + IDS_SPACE_RESERVATION_READOUT = 36269, // 0x00008DAD + IDS_CACHE_CLEAR_FAILED = 36272, // 0x00008DB0 + IDS_DELETE_DEVICE_FAILED = 36274, // 0x00008DB2 + IDS_WIRELESS_SYNC_DESCRIPTION = 36276, // 0x00008DB4 + IDS_WIRELESS_USE_CONNECTED = 36281, // 0x00008DB9 + IDS_WIRELESS_USE_CONNECTED_YES = 36282, // 0x00008DBA + IDS_WIRELESS_USE_CONNECTED_NO = 36283, // 0x00008DBB + IDS_GDI_WARNING = 36284, // 0x00008DBC + IDS_VIDEO_SUPPORT_URL = 36285, // 0x00008DBD + IDS_CONTINUE_BUTTON = 36286, // 0x00008DBE + IDS_RENDER_PROMPT = 36287, // 0x00008DBF + IDS_RENDER_PROMPT_RESTART = 36288, // 0x00008DC0 + IDS_RENDER_PROMPT_CAPTION = 36289, // 0x00008DC1 + IDS_ACCELERATION_RESTART_TEXT = 36291, // 0x00008DC3 + IDS_ENABLE_ACCELERATION_TITLE = 36292, // 0x00008DC4 + IDS_CHECK_FOR_UPDATES_TEXT = 36293, // 0x00008DC5 + IDS_CHECK_FOR_UPDATES_TITLE = 36294, // 0x00008DC6 + IDS_VIEW_WARNINGS_TITLE = 36295, // 0x00008DC7 + IDS_ACCELERATION_BUTTON_ENABLE = 36296, // 0x00008DC8 + IDS_ACCELERATION_BUTTON_DISABLE = 36297, // 0x00008DC9 + IDS_ACCELERATION_PROMPT_TEXT = 36298, // 0x00008DCA + IDS_ACCELERATION_LABEL_ENABLE = 36299, // 0x00008DCB + IDS_ACCELERATION_LABEL_DISABLE = 36300, // 0x00008DCC + IDS_SLIDESHOW_OPTION_VALUE = 36301, // 0x00008DCD + IDS_SLIDESHOW_SHORT = 36302, // 0x00008DCE + IDS_SLIDESHOW_LONG = 36303, // 0x00008DCF + IDS_WIRELESS_SYNC_SETUP_COMPLETE = 36304, // 0x00008DD0 + IDS_WIRELESS_SYNC_DEVICE = 36305, // 0x00008DD1 + IDS_WIRELESS_SYNC_NETWORK = 36306, // 0x00008DD2 + IDS_WIRELESS_SYNC_SETUP_FAILED = 36307, // 0x00008DD3 + IDS_WIRELESS_SYNC_SETUP_FAILED_GENERIC = 36308, // 0x00008DD4 + IDS_WIRELESS_SYNC_FAILED_MORE_INFO = 36309, // 0x00008DD5 + IDS_WIRELESS_SYNC_FAILED_MORE_INFO_LINK = 36310, // 0x00008DD6 + IDS_WIRELESS_SYNC_SHOW_ADVANCED_SETTINGS = 36311, // 0x00008DD7 + IDS_WIRELESS_SYNC_HIDE_ADVANCED_SETTINGS = 36312, // 0x00008DD8 + IDS_WIRELESS_TRY_AGAIN_BUTTON = 36314, // 0x00008DDA + IDS_WIRELESS_SHOW_CLEAR_TEXT = 36315, // 0x00008DDB + IDS_WIRELESS_NETWORK_PROTECTED = 36316, // 0x00008DDC + IDS_WIRELESS_ENTER_NETWORK_KEY = 36317, // 0x00008DDD + IDS_WIRELESS_SYNC_NOT_CONFIGURED = 36318, // 0x00008DDE + IDS_WIRELESS_ERROR_UNSUPPORTED_AUTH = 36319, // 0x00008DDF + IDS_WIRELESS_ERROR_INVALID_NAME = 36320, // 0x00008DE0 + IDS_DEVICE_NAME_STRING = 36321, // 0x00008DE1 + IDS_WIRELESS_SYNC_TEST_FAILED = 36322, // 0x00008DE2 + IDS_WIRELESS_DETECTING_NETWORKS = 36323, // 0x00008DE3 + IDS_WIRELESS_NO_NETWORKS = 36324, // 0x00008DE4 + IDS_WIRELESS_DETECTING_CONNECTED = 36325, // 0x00008DE5 + IDS_WIRELESS_RETRIEVING_PROFILE = 36326, // 0x00008DE6 + IDS_WIRELESS_CANCELING = 36327, // 0x00008DE7 + IDS_WIRELESS_SYNC_SETUP_CANCELED = 36328, // 0x00008DE8 + IDS_PODCAST_KEEP_EPISODES = 36329, // 0x00008DE9 + IDS_PODCAST_SLIDER_FEW = 36330, // 0x00008DEA + IDS_PODCAST_SLIDER_MANY = 36331, // 0x00008DEB + IDS_FORMAT_DIALOG_TITLE = 36332, // 0x00008DEC + IDS_FORMAT_DIALOG_TEXT = 36333, // 0x00008DED + IDS_CUSTOMER_EXPERIENCE_URL = 36337, // 0x00008DF1 + IDS_NEXT_BUTTON = 36338, // 0x00008DF2 + IDS_BACK_BUTTON = 36339, // 0x00008DF3 + IDS_OPTION_FOR_PARTNERS_ONLY = 36341, // 0x00008DF5 + IDS_ASSOCIATE_YOUR_ZUNE_ERROR = 36342, // 0x00008DF6 + IDS_SYNC_SETUP_COMPLETION_ERROR = 36343, // 0x00008DF7 + IDS_PAUSING_SYNC_DIALOG_TITLE = 36344, // 0x00008DF8 + IDS_PAUSING_SYNC_DIALOG_TEXT = 36345, // 0x00008DF9 + IDS_KEEP_N_OPTION = 36346, // 0x00008DFA + IDS_PODCAST_KEEP_SERIES_EPISODES = 36347, // 0x00008DFB + IDS_WIRELESS_SNIFF_FAILED = 36348, // 0x00008DFC + IDS_OPTION_FOR_EXISTING_ONLY = 36352, // 0x00008E00 + IDS_SUBMIT_BUTTON = 36353, // 0x00008E01 + IDS_CHANGE_PARTNERSHIP_DEVICE_BUTTON = 36356, // 0x00008E04 + IDS_TURN_OFF_SHARING_ALL_ERROR = 36357, // 0x00008E05 + IDS_FORMAT_IN_PROGRESS_HEADER = 36358, // 0x00008E06 + IDS_NOT_CONNECTED_VIA_USB = 36359, // 0x00008E07 + IDS_WIRELESS_COMMON_REASONS = 36360, // 0x00008E08 + IDS_WIRELESS_SUGG_BAD_KEY = 36361, // 0x00008E09 + IDS_WIRELESS_SUGG_OUT_OF_RANGE = 36362, // 0x00008E0A + IDS_WIRELESS_SUGG_MAC_FILTERING = 36363, // 0x00008E0B + IDS_WIRELESS_SUGG_LIST_DASH = 36364, // 0x00008E0C + IDS_MEDIA_FOLDER_TEXT = 36365, // 0x00008E0D + IDS_WIRELESS_NETWORK_TYPE = 36366, // 0x00008E0E + IDS_WIRELESS_NETWORK_NO_ENCRYPTION = 36367, // 0x00008E0F + IDS_WIRELESS_NETWORK_WEP_OPEN = 36368, // 0x00008E10 + IDS_WIRELESS_NETWORK_WEP_SHARED = 36369, // 0x00008E11 + IDS_WIRELESS_NETWORK_WPA_AES = 36370, // 0x00008E12 + IDS_WIRELESS_NETWORK_WPA_TKIP = 36371, // 0x00008E13 + IDS_WIRELESS_NETWORK_WPA2_AES = 36372, // 0x00008E14 + IDS_WIRELESS_NETWORK_WPA2_TKIP = 36373, // 0x00008E15 + IDS_WIRELESS_ERROR_DETAILS_BUTTON = 36374, // 0x00008E16 + IDS_FILE_TYPES_ERROR_DIALOG_TITLE = 36375, // 0x00008E17 + IDS_FIRMWARE_VERSION_PRE_TEXT = 36376, // 0x00008E18 + IDS_FIRMWARE_NEW_VERSION_OPTIONAL = 36377, // 0x00008E19 + IDS_FIRMWARE_VERSION_FORMAT = 36378, // 0x00008E1A + IDS_INVALID_MONITORED_FOLDER_TITLE = 36379, // 0x00008E1B + IDS_INVALID_MONITORED_FOLDER_MESSAGE = 36380, // 0x00008E1C + IDS_SYNC_PROMPT_PER_DEVICE = 36381, // 0x00008E1D + IDS_WIRELESS_TURN_OFF_BUTTON = 36382, // 0x00008E1E + IDS_WIRELESS_SYNC_NETWORK_TYPE = 36383, // 0x00008E1F + IDS_WIRELESS_ALREADY_CONFIGURED = 36384, // 0x00008E20 + IDS_WIRELESS_SYNC_DISABLED = 36385, // 0x00008E21 + IDS_WIRELESS_DEVICE_BUSY = 36386, // 0x00008E22 + IDS_WIRELESS_CHANGE_NETWORK_BUTTON = 36388, // 0x00008E24 + IDS_SHARE_MEDIA_XP_NON_ADMIN_MESSAGE = 36389, // 0x00008E25 + IDS_WIRELESS_SYNC_MORE_INFO = 36390, // 0x00008E26 + IDS_WIRELESS_SYNC_START_CONFIG = 36391, // 0x00008E27 + IDS_WIRELESS_SYNC_GET_CONNECTED_FAILED = 36392, // 0x00008E28 + IDS_FORGET_DEVICE_DIALOG_TITLE = 36393, // 0x00008E29 + IDS_FORGET_DEVICE_DIALOG_CONTENT = 36394, // 0x00008E2A + IDS_FIRMWARE_UPDATE_UNAVAILABLE_TITLE = 36395, // 0x00008E2B + IDS_DEVICE_RECOVERY_MODE = 36396, // 0x00008E2C + IDS_OPTION_FOR_USB_ONLY = 36397, // 0x00008E2D + IDS_BACKGROUND_NAME_0 = 36398, // 0x00008E2E + IDS_BACKGROUND_NAME_1 = 36399, // 0x00008E2F + IDS_BACKGROUND_NAME_2 = 36400, // 0x00008E30 + IDS_BACKGROUND_NAME_3 = 36401, // 0x00008E31 + IDS_BACKGROUND_NAME_4 = 36402, // 0x00008E32 + IDS_BACKGROUND_NAME_5 = 36403, // 0x00008E33 + IDS_DISPLAY_MENU_ITEM = 36404, // 0x00008E34 + IDS_BACKGROUND_TITLE = 36406, // 0x00008E36 + IDS_SCREEN_GRAPHICS_TITLE = 36407, // 0x00008E37 + IDS_MIN_SCREEN_QUALITY_DESCRIPTION = 36408, // 0x00008E38 + IDS_GENERAL_INFORMATION_HEADER = 36409, // 0x00008E39 + IDS_FILE_TYPES_DESCRIPTION_FORMAT = 36410, // 0x00008E3A + IDS_REGDEVICES_REMOVE_BUTTON = 36411, // 0x00008E3B + IDS_WIRELESS_SYNC_PRE_SETUP_FAILED = 36413, // 0x00008E3D + IDS_WIRELESS_SYNC_POST_SETUP_FAILED = 36414, // 0x00008E3E + IDS_WIRELESS_SYNC_GENERIC_SETUP_FAILED = 36415, // 0x00008E3F + IDS_XBOX360_NAME_AND_SERIAL_NUMBER = 36416, // 0x00008E40 + IDS_WIRELESS_CLEAR_UUID_FAILED_TITLE = 36417, // 0x00008E41 + IDS_WIRELESS_CLEAR_UUID_FAILED = 36418, // 0x00008E42 + IDS_GO_TO_APP_LABEL = 36419, // 0x00008E43 + IDS_CONFIGURE_LABEL = 36420, // 0x00008E44 + IDS_CHECKING_FOR_UPDATES = 36421, // 0x00008E45 + IDS_EXISTING_PARTNERSHIP_DESCRIPTION = 36422, // 0x00008E46 + IDS_ASSOCIATE_YOUR_ZUNE_DESCRIPTION1 = 36423, // 0x00008E47 + IDS_ASSOCIATE_YOUR_ZUNE_DESCRIPTION2 = 36424, // 0x00008E48 + IDS_SPACE_RESERVATION_DESCRIPTION = 36425, // 0x00008E49 + IDS_INVALID_MEDIA_FOLDER_TITLE = 36426, // 0x00008E4A + IDS_INVALID_MEDIA_FOLDER_MESSAGE = 36427, // 0x00008E4B + IDS_WIRELESS_SYNC_WLAN_UUID_FAILED = 36428, // 0x00008E4C + IDS_ACCOUNT_MUST_LOGON_TEXT = 36429, // 0x00008E4D + IDS_ACCOUNT_MENU_ITEM = 36430, // 0x00008E4E + IDS_NO_SYNC_OPTIONS_INFO = 36431, // 0x00008E4F + IDS_SCAN_REMOVED_FILES_BUTTON = 36432, // 0x00008E50 + IDS_SMART_SYNC_EXPLANATION = 36433, // 0x00008E51 + IDS_REGDEVICES_CANT_REMOVE = 36434, // 0x00008E52 + IDS_PODCAST_SETTINGS_HEADER = 36435, // 0x00008E53 + IDS_PODCAST_SETTINGS_DESCRIPTION = 36436, // 0x00008E54 + IDS_SOUNDS_TITLE = 36437, // 0x00008E55 + IDS_SOUNDS_DESCRIPTION = 36438, // 0x00008E56 + IDS_DONT_SYNC_DISLIKED_CONTENT = 36441, // 0x00008E59 + IDS_TRANSCODE_AUDIO_LABEL = 36442, // 0x00008E5A + IDS_TRANSCODE_AUDIO_NOSUPPORT_OPTION = 36444, // 0x00008E5C + IDS_TRANSCODE_VIDEO_LABEL = 36445, // 0x00008E5D + IDS_TRANSCODE_VIDEO_PLAYBACK_OPTION = 36446, // 0x00008E5E + IDS_TRANSCODE_VIDEO_TV_OUT_OPTION = 36447, // 0x00008E5F + IDS_SAVE_CHANGES_DIALOG_TITLE = 36450, // 0x00008E62 + IDS_SAVE_CHANGES_DIALOG_TEXT = 36451, // 0x00008E63 + IDS_SYNC_GROUPS_SETTINGS_HEADER = 36452, // 0x00008E64 + IDS_SYNC_GROUPS_EXPLANATORY_TEXT = 36453, // 0x00008E65 + IDS_ADD_NEW_SYNC_GROUP_BUTTON = 36454, // 0x00008E66 + IDS_ALL_MUSIC_SYNC_GROUP = 36455, // 0x00008E67 + IDS_ALL_VIDEO_SYNC_GROUP = 36456, // 0x00008E68 + IDS_ALL_PHOTOS_SYNC_GROUP = 36457, // 0x00008E69 + IDS_ALL_PODCASTS_SYNC_GROUP = 36458, // 0x00008E6A + IDS_ALL_FRIENDS_SYNC_GROUP = 36459, // 0x00008E6B + IDS_SYNC_GROUP_ITEMS_AND_SIZE = 36460, // 0x00008E6C + IDS_SYNC_GROUP_PENDING = 36462, // 0x00008E6E + IDS_SONGS = 36463, // 0x00008E6F + IDS_VIDEOS = 36464, // 0x00008E70 + IDS_PICTURES = 36465, // 0x00008E71 + IDS_PODCASTS = 36466, // 0x00008E72 + IDS_FRIENDS = 36467, // 0x00008E73 + IDS_DELETE_SYNC_GROUP_BUTTON = 36468, // 0x00008E74 + IDS_DELETE_SYNC_GROUP_MENUITEM = 36469, // 0x00008E75 + IDS_EDIT_SYNC_GROUP_BUTTON = 36470, // 0x00008E76 + IDS_EDIT_SYNC_GROUP_MENUITEM = 36471, // 0x00008E77 + IDS_REMOVE_SYNC_GROUP_DIALOG_TITLE = 36474, // 0x00008E7A + IDS_REMOVE_SINGLE_SYNC_GROUP_DIALOG_TEXT = 36475, // 0x00008E7B + IDS_REMOVE_MULTIPLE_SYNC_GROUP_DIALOG_TEXT = 36476, // 0x00008E7C + IDS_SYNC_SETTINGS_HEADER = 36480, // 0x00008E80 + IDS_DEVICE_OPTIONS_HEADER = 36481, // 0x00008E81 + IDS_SYNC_ALL_OPTION_MUSIC = 36482, // 0x00008E82 + IDS_LET_ME_CHOOSE_OPTION_MUSIC = 36483, // 0x00008E83 + IDS_MUSIC = 36484, // 0x00008E84 + IDS_COMPLEX_SYNC_GROUP_DIALOG_TITLE = 36485, // 0x00008E85 + IDS_COMPLEX_SYNC_GROUP_SOURCE_HEADER = 36487, // 0x00008E87 + IDS_NEW_COMPLEX_SYNC_GROUP_NAME = 36488, // 0x00008E88 + IDS_COMPLEX_SYNC_SCHEMA_MUSIC = 36489, // 0x00008E89 + IDS_COMPLEX_SYNC_SCHEMA_VIDEO = 36490, // 0x00008E8A + IDS_COMPLEX_SYNC_SCHEMA_PHOTO = 36491, // 0x00008E8B + IDS_TRANSCODE_AUDIO_EXCEEDS_OPTION = 36492, // 0x00008E8C + IDS_TRANSCODE_AUDIO_SOURCE_QUALITY = 36493, // 0x00008E8D + IDS_TRANSCODE_AUDIO_DEVICE_QUALITY = 36494, // 0x00008E8E + IDS_UNCHECK_SYNC_GROUP_MENUITEM = 36495, // 0x00008E8F + IDS_CHECK_SYNC_GROUP_MENUITEM = 36496, // 0x00008E90 + IDS_OVERFILL_EXPLANATORY_TEXT = 36497, // 0x00008E91 + IDS_PODCAST_EPISODES = 36498, // 0x00008E92 + IDS_CUT = 36499, // 0x00008E93 + IDS_COPY = 36500, // 0x00008E94 + IDS_PASTE = 36501, // 0x00008E95 + IDS_DELETE = 36502, // 0x00008E96 + IDS_SELECTALL = 36503, // 0x00008E97 + IDS_OPTION_FOR_USB_WIRELESS_SETTINGS = 36504, // 0x00008E98 + IDS_COMPLEX_SYNC_GROUP_VIDEO_ARTIST_LABEL = 36505, // 0x00008E99 + IDS_COMPLEX_SYNC_GROUP_LIMIT_ITEMS = 36506, // 0x00008E9A + IDS_COMPLEX_SYNC_GROUP_TV_SERIES_LABEL = 36507, // 0x00008E9B + IDS_COMPLEX_SYNC_GROUP_FILTERBY_HEADER = 36508, // 0x00008E9C + IDS_REGDEVICES_CONFIRM_REMOVE = 36509, // 0x00008E9D + IDS_REMOVE_SYNC_ALL_GROUP_DIALOG_TEXT = 36510, // 0x00008E9E + IDS_RENDER_PROMPT_AFTER_D3D_SWITCH = 36511, // 0x00008E9F + IDS_MEDIA_FOLDER_TEXT_NO_MARKETPLACE = 36512, // 0x00008EA0 + IDS_SYNC_FRIENDS_NOTICE_TITLE = 36516, // 0x00008EA4 + IDS_SYNC_FRIENDS_NOTICE = 36517, // 0x00008EA5 + IDS_SAVE_CHANGES_ON_BACK_DIALOG_TEXT = 36518, // 0x00008EA6 + IDS_KEEP_0_OPTION = 36519, // 0x00008EA7 + IDS_REMOVE_FOLDER_TITLE = 36520, // 0x00008EA8 + IDS_REMOVE_FOLDER_TEXT = 36521, // 0x00008EA9 + IDS_HEADER_CONTROL = 36524, // 0x00008EAC + IDS_SYNC_OPTION_SETTING_SMART_SYNC = 36525, // 0x00008EAD + IDS_CHANNELS = 36528, // 0x00008EB0 + IDS_ENABLE_DEVICE_PURCHASE = 36531, // 0x00008EB3 + IDS_THE_SOCIAL_HEADER = 36532, // 0x00008EB4 + IDS_BILLING_ZUNE_PASS_HEADER = 36533, // 0x00008EB5 + IDS_BILLING_DOWNLOAD_HISTORY_HEADER = 36534, // 0x00008EB6 + IDS_BILLING_RENTAL_HISTORY_HEADER = 36535, // 0x00008EB7 + IDS_BILLING_PURCHASE_POINTS_HEADER = 36536, // 0x00008EB8 + IDS_BILLING_CC_VISA = 36537, // 0x00008EB9 + IDS_BILLING_CC_MASTERCARD = 36538, // 0x00008EBA + IDS_BILLING_CC_AMEX = 36539, // 0x00008EBB + IDS_BILLING_CC_DISCOVER = 36540, // 0x00008EBC + IDS_BILLING_CC_JCB = 36541, // 0x00008EBD + IDS_BILLING_CC_DINERS = 36542, // 0x00008EBE + IDS_BILLING_CC_KLCC = 36543, // 0x00008EBF + IDS_BILLING_USA_STATES = 36544, // 0x00008EC0 + IDS_BILLING_COUNTRIES = 36545, // 0x00008EC1 + IDS_BILLING_EDIT_CC_NAME = 36546, // 0x00008EC2 + IDS_BILLING_EDIT_CC_CCTYPE = 36547, // 0x00008EC3 + IDS_BILLING_EDIT_CC_CCTYPE_EMPTY = 36548, // 0x00008EC4 + IDS_BILLING_EDIT_CC_CCNUMBER = 36549, // 0x00008EC5 + IDS_BILLING_EDIT_CC_CCEXPIRES = 36550, // 0x00008EC6 + IDS_BILLING_EDIT_CC_CCEXPIRES_FORMAT = 36551, // 0x00008EC7 + IDS_BILLING_EDIT_CC_CCVNUMBER = 36552, // 0x00008EC8 + IDS_BILLING_EDIT_CC_CCVNUMBER_HELP_BTN = 36553, // 0x00008EC9 + IDS_BILLING_EDIT_CC_STREET1 = 36554, // 0x00008ECA + IDS_BILLING_EDIT_CC_STREET2 = 36555, // 0x00008ECB + IDS_BILLING_EDIT_CC_CITY = 36556, // 0x00008ECC + IDS_BILLING_EDIT_CC_POSTALCODE = 36557, // 0x00008ECD + IDS_BILLING_EDIT_CC_STATE = 36558, // 0x00008ECE + IDS_BILLING_EDIT_CC_STATE_EMPTY = 36559, // 0x00008ECF + IDS_BILLING_EDIT_CC_COUNTRY = 36560, // 0x00008ED0 + IDS_BILLING_EDIT_CC_REQUIRED = 36561, // 0x00008ED1 + IDS_BILLING_EDIT_CC_ADD_BTN = 36562, // 0x00008ED2 + IDS_BILLING_EDIT_CC_ADD_HEADER = 36563, // 0x00008ED3 + IDS_BILLING_EDIT_CC_ADD_LINK = 36564, // 0x00008ED4 + IDS_BILLING_PAYMENT_CHOICE_EMPTY_HEADER = 36565, // 0x00008ED5 + IDS_BILLING_PAYMENT_CHOICE_HEADER = 36566, // 0x00008ED6 + IDS_BILLING_BUY_POINTS_HELP_BTN = 36567, // 0x00008ED7 + IDS_BILLING_BUY_POINTS_HEADER1 = 36568, // 0x00008ED8 + IDS_BILLING_BUY_POINTS_HEADER2 = 36569, // 0x00008ED9 + IDS_BILLING_BUY_POINTS_DESC1 = 36570, // 0x00008EDA + IDS_BILLING_BUY_POINTS_DESC2 = 36571, // 0x00008EDB + IDS_BILLING_BUY_PASS_HELP = 36572, // 0x00008EDC + IDS_BILLING_BUY_PASS_HEADER = 36573, // 0x00008EDD + IDS_BILLING_BUY_PASS_DESC1 = 36574, // 0x00008EDE + IDS_BILLING_BUY_PASS_DESC2 = 36575, // 0x00008EDF + IDS_BILLING_SERVICE_NOT_AVAILABLE = 36576, // 0x00008EE0 + IDS_FIRMWARE_UPDATE_NOT_AVAIL_OFFLINE = 36577, // 0x00008EE1 + IDS_FIRMWARE_UPDATE_NOT_AVAIL_UNKNOWN = 36578, // 0x00008EE2 + IDS_BILLING_OFFER_PRICE = 36580, // 0x00008EE4 + IDS_BILLING_PURCHASE_FAILED = 36582, // 0x00008EE6 + IDS_BILLING_ADD_CREDIT_CARD_FAILED = 36583, // 0x00008EE7 + IDS_BILLING_HIDDEN_CERDIT_CARD = 36584, // 0x00008EE8 + IDS_BILLING_EDIT_CC_PHONE = 36585, // 0x00008EE9 + IDS_BILLING_BUY_POINTS_SUCCESS = 36586, // 0x00008EEA + IDS_BILLING_BUY_PASS_SUCCESS = 36587, // 0x00008EEB + IDS_BILLING_BUY_BTN = 36588, // 0x00008EEC + IDS_BILLING_EDIT_CC_PHONE_EXT = 36589, // 0x00008EED + IDS_BILLING_CURRENT_SUBSCRIPTION = 36590, // 0x00008EEE + IDS_DUPLICATE_DIALOG_TITLE = 36591, // 0x00008EEF + IDS_DUPLICATE_DIALOG_TEXT_SINGLE = 36592, // 0x00008EF0 + IDS_DUPLICATE_DIALOG_TEXT_MULTIPLE = 36593, // 0x00008EF1 + IDS_DUPLICATE_TOOLTIP_SINGLE = 36594, // 0x00008EF2 + IDS_DUPLICATE_TOOLTIP_MULTIPLE = 36595, // 0x00008EF3 + IDS_CRITICAL_UPDATE_AVAILABLE = 36596, // 0x00008EF4 + IDS_SHOW_NOWPLAYING_ON_IDLE_TITLE = 36599, // 0x00008EF7 + IDS_SHOW_NOWPLAYING_ON_IDLE_DESCRIPTION = 36600, // 0x00008EF8 + IDS_ACCOUNT_CLEAR_SUBSCRIPTION_DESC = 36601, // 0x00008EF9 + IDS_ACCOUNT_CLEAR_SUBSCRIPTION_CONFIRM = 36602, // 0x00008EFA + IDS_ACCOUNT_CLEAR_SUBSCRIPTION_TITLE = 36603, // 0x00008EFB + IDS_ACCOUNT_CLEAR_SUBSCRIPTION_BUTTON = 36604, // 0x00008EFC + IDS_ACCOUNT_CLEAR_SUB_FAIL_TITLE = 36605, // 0x00008EFD + IDS_ACCOUNT_CLEAR_SUB_FAIL_MESSAGE = 36606, // 0x00008EFE + IDS_USER_RATINGS_SETTING_TITLE = 36607, // 0x00008EFF + IDS_USER_RATINGS_SETTING_DESCRIPTION = 36608, // 0x00008F00 + IDS_COMMON_RATINGS_ALL_USERS_OPTION = 36609, // 0x00008F01 + IDS_PERSONAL_RATINGS_EACH_USER_OPTION = 36610, // 0x00008F02 + IDS_APPLY_RATINGS_DIALOG_DESCRIPTION = 36614, // 0x00008F06 + IDS_ALL_CHANNELS_SYNC_GROUP = 36615, // 0x00008F07 + IDS_ALL_AUDIOBOOKS_SYNC_GROUP = 36616, // 0x00008F08 + IDS_ALL_GUEST_SYNC_GROUP = 36617, // 0x00008F09 + IDS_SCHEMA_SIZE = 36619, // 0x00008F0B + IDS_EXPAND_SYNC_GROUP_SCHEMA = 36620, // 0x00008F0C + IDS_COLLAPSE_SYNC_GROUP_SCHEMA = 36621, // 0x00008F0D + IDS_SCHEMA_IS_IN_MANUAL_MESSAGE = 36622, // 0x00008F0E + IDS_SCHEMA_IS_IN_SYNC_ALL_MESSAGE = 36623, // 0x00008F0F + IDS_CANNOT_MANAGE_AUDIOBOOKS_MESSAGE = 36624, // 0x00008F10 + IDS_BILLING_SERVICE_UNAVAILABLE = 36625, // 0x00008F11 + IDS_BILLING_CURRENT_SUBSCRIPTION_ENDING = 36626, // 0x00008F12 + IDS_BILLING_SUBSCRIPTION_ENDING_TITLE = 36627, // 0x00008F13 + IDS_BILLING_SUBSCRIPTION_ENDING_WARNING = 36628, // 0x00008F14 + IDS_BILLING_SUBSCRIPTION_ENDED_TITLE = 36629, // 0x00008F15 + IDS_BILLING_SUBSCRIPTION_ENDED_WARNING = 36630, // 0x00008F16 + IDS_BILLING_RENEW_SUBSCRIPTION = 36631, // 0x00008F17 + IDS_GAMES_REINSTALL_HEADER = 36632, // 0x00008F18 + IDS_GAMES_REINSTALL_DESCRIPTION = 36633, // 0x00008F19 + IDS_REINSTALL_GAMES_BUTTON = 36634, // 0x00008F1A + IDS_ACCOUNT_INBOX_COUNT = 36635, // 0x00008F1B + IDS_ACCOUNT_CART_COUNT = 36636, // 0x00008F1C + IDS_ACCOUNT_RENEW_DATE = 36637, // 0x00008F1D + IDS_ACCOUNT_EXPIRE_DATE = 36638, // 0x00008F1E + IDS_ACCOUNT_ZUNE_PASS_HEADER = 36639, // 0x00008F1F + IDS_BACKGROUND_NAME_6 = 36640, // 0x00008F20 + IDS_BILLING_EDIT_CC_CCVNUMBER_HELP = 36641, // 0x00008F21 + IDS_BILLING_EDIT_CC_CCVNUMBER_HELP_TITLE = 36642, // 0x00008F22 + IDS_BILLING_SUBSCRIPTION_OPTIONS_HEADER = 36643, // 0x00008F23 + IDS_LINK_DEVICE_ON_CHANGE_DIALOG_TEXT = 36644, // 0x00008F24 + IDS_GAMES_INSTALL_CHECKBOX_DESCRIPTION = 36645, // 0x00008F25 + IDS_ACCOUNT_CLEAR_SUB_NO_DIRECTORY = 36646, // 0x00008F26 + IDS_BILLING_CURRENT_SUBSCRIPTION_RENEW = 36647, // 0x00008F27 + IDS_SYNC_OPTION_MEDIA_MUSIC = 36648, // 0x00008F28 + IDS_SYNC_OPTION_MEDIA_VIDEOS = 36649, // 0x00008F29 + IDS_SYNC_OPTION_MEDIA_PICTURES = 36650, // 0x00008F2A + IDS_SYNC_OPTION_MEDIA_PODCASTS = 36651, // 0x00008F2B + IDS_SYNC_OPTION_MEDIA_CHANNELS = 36652, // 0x00008F2C + IDS_SYNC_OPTION_MEDIA_FRIENDS = 36653, // 0x00008F2D + IDS_ACCOUNT_CLEAR_SUBSCRIPTION_HEADER = 36655, // 0x00008F2F + IDS_SYNC_GROUP_SETTINGS_BUTTON = 36656, // 0x00008F30 + IDS_MAX_SCREEN_QUALITY_DESCRIPTION = 36657, // 0x00008F31 + IDS_WWW_ZUNE_NET_SUPPORT_URL = 36658, // 0x00008F32 + IDS_DEVICE_USAGE_DATA_HEADER = 36659, // 0x00008F33 + IDS_DEVICE_USAGE_DATA_CHECK = 36660, // 0x00008F34 + IDS_DEVICE_USAGE_DATA_INFO_HEADER = 36661, // 0x00008F35 + IDS_DEVICE_USAGE_DATA_INFO = 36662, // 0x00008F36 + IDS_DUPLICATE_ENTRIES_SETTING = 36663, // 0x00008F37 + IDS_SHOW_DUPLICATES = 36664, // 0x00008F38 + IDS_BILLING_EDIT_LINK = 36665, // 0x00008F39 + IDS_BILLING_CANCEL_PASS = 36666, // 0x00008F3A + IDS_BILLING_CONTACT_INFO_NEEDED_TITLE = 36667, // 0x00008F3B + IDS_BILLING_CONTACT_INFO_NEEDED = 36668, // 0x00008F3C + IDS_GAMES_INSTALL_INFO_LINK = 36670, // 0x00008F3E + IDS_GAMES_INSTALL_INFO_LINK_URL = 36671, // 0x00008F3F + IDS_SCREEN_GRAPHICS_HEADER = 36672, // 0x00008F40 + IDS_SCREEN_GRAPHICS_BASIC = 36673, // 0x00008F41 + IDS_SCREEN_GRAPHICS_ADVANCED = 36674, // 0x00008F42 + IDS_SCREEN_GRAPHICS_ADVANCED_ANIMATION = 36675, // 0x00008F43 + IDS_SCREEN_GRAPHICS_PREMIUM = 36676, // 0x00008F44 + IDS_SCREEN_QUALITY_MIN = 36677, // 0x00008F45 + IDS_SCREEN_QUALITY_MAX = 36678, // 0x00008F46 + IDS_SYNC_ALL_OPTION_VIDEOS = 36680, // 0x00008F48 + IDS_SYNC_ALL_OPTION_PICTURES = 36681, // 0x00008F49 + IDS_SYNC_ALL_OPTION_PODCASTS = 36682, // 0x00008F4A + IDS_SYNC_ALL_OPTION_CHANNELS = 36683, // 0x00008F4B + IDS_SYNC_ALL_OPTION_FRIENDS = 36684, // 0x00008F4C + IDS_LET_ME_CHOOSE_OPTION_VIDEOS = 36685, // 0x00008F4D + IDS_LET_ME_CHOOSE_OPTION_PICTURES = 36686, // 0x00008F4E + IDS_LET_ME_CHOOSE_OPTION_PODCASTS = 36687, // 0x00008F4F + IDS_LET_ME_CHOOSE_OPTION_CHANNELS = 36688, // 0x00008F50 + IDS_LET_ME_CHOOSE_OPTION_FRIENDS = 36689, // 0x00008F51 + IDS_SHOW_DUPLICATES_FAILED = 36690, // 0x00008F52 + IDS_SUBSCRIBED_BUTTON = 36691, // 0x00008F53 + IDS_SYNC_OPTION_SETTING_LEARN_MORE = 36692, // 0x00008F54 + IDS_SYNC_OPTION_SETTING_LEARN_MORE_URL = 36693, // 0x00008F55 + IDS_SYNC_OPTION_SETTING_MANUAL_SYNC = 36694, // 0x00008F56 + IDS_BROWSE_BUTTON = 36696, // 0x00008F58 + IDS_VIEW_STARTUPPAGE_TITLE = 36697, // 0x00008F59 + IDS_VIEW_STARTUPPAGE_HEADER = 36698, // 0x00008F5A + IDS_VIEW_STARTUPPAGE_QUICKPLAY_CHOICE = 36699, // 0x00008F5B + IDS_VIEW_STARTUPPAGE_COLLECTION_CHOICE = 36700, // 0x00008F5C + IDS_VIEW_STARTUPPAGE_MARKETPLACE_CHOICE = 36701, // 0x00008F5D + IDS_VIEW_STARTUPPAGE_SOCIAL_CHOICE = 36702, // 0x00008F5E + IDS_ACCOUNT_CREATION_HEADER = 36703, // 0x00008F5F + IDS_ACCOUNT_CREATION_EMAIL_STEP = 36704, // 0x00008F60 + IDS_ACCOUNT_CREATION_EMAIL_STEP_HEADER = 36705, // 0x00008F61 + IDS_ACCOUNT_CREATION_EMAIL_STEP_DESC = 36706, // 0x00008F62 + IDS_ACCOUNT_CREATION_EMAIL_ENTRY = 36707, // 0x00008F63 + IDS_ACCOUNT_CREATION_PASSPORT_STEP = 36708, // 0x00008F64 + IDS_ACCOUNT_CREATION_PASSPORT_STEP_DESC = 36709, // 0x00008F65 + IDS_ACCOUNT_CREATION_CREDENTIALS_HEADER = 36710, // 0x00008F66 + IDS_ACCOUNT_CREATION_CREDENTIALS_ID = 36711, // 0x00008F67 + IDS_ACCOUNT_CREATION_CREDENTIALS_PASS_1 = 36712, // 0x00008F68 + IDS_ACCOUNT_CREATION_CREDENTIALS_PASS_2 = 36713, // 0x00008F69 + IDS_ACCOUNT_CREATION_SECRET_HEADER = 36714, // 0x00008F6A + IDS_ACCOUNT_CREATION_SECRET_DESC = 36715, // 0x00008F6B + IDS_ACCOUNT_CREATION_SECRET_QUESTION = 36716, // 0x00008F6C + IDS_ACCOUNT_CREATION_SECRET_ANSWER = 36717, // 0x00008F6D + IDS_ACCOUNT_CREATION_SECRET_ANSWER_HELP = 36718, // 0x00008F6E + IDS_ACCOUNT_CREATION_HIP_HEADER = 36719, // 0x00008F6F + IDS_ACCOUNT_CREATION_HIP_DESC = 36720, // 0x00008F70 + IDS_ACCOUNT_CREATION_HIP_PICTURE = 36721, // 0x00008F71 + IDS_ACCOUNT_CREATION_HIP_PICTURE_HELP = 36722, // 0x00008F72 + IDS_ACCOUNT_CREATION_HIP_CHARACTERS = 36723, // 0x00008F73 + IDS_ACCOUNT_CREATION_TOS_HEADER = 36724, // 0x00008F74 + IDS_ACCOUNT_CREATION_TOS_DESC = 36725, // 0x00008F75 + IDS_ACCOUNT_CREATION_TOS_LINK = 36726, // 0x00008F76 + IDS_ACCOUNT_CREATION_PRS_LINK = 36727, // 0x00008F77 + IDS_ACCOUNT_CREATION_GET_LIVE_ID_LINK = 36728, // 0x00008F78 + IDS_ACCOUNT_CREATION_RESETTING_PASS_LINK = 36729, // 0x00008F79 + IDS_ACCOUNT_CREATION_HIP_LINK = 36730, // 0x00008F7A + IDS_FWUPDATE_CHECK_TITLE = 36731, // 0x00008F7B + IDS_FWUPDATE_CHECK_DESCRIPTION = 36732, // 0x00008F7C + IDS_FWUPDATE_CHECK_TEXT = 36733, // 0x00008F7D + IDS_FWUPDATE_DOWNLOAD_TITLE = 36734, // 0x00008F7E + IDS_FWUPDATE_DOWNLOAD_DESCRIPTION = 36735, // 0x00008F7F + IDS_FWUPDATE_DOWNLOAD_TEXT = 36736, // 0x00008F80 + IDS_FWUPDATE_INSTALL_TITLE = 36737, // 0x00008F81 + IDS_FWUPDATE_INSTALL_DESCRIPTION = 36738, // 0x00008F82 + IDS_FWUPDATE_INSTALL_TEXT = 36739, // 0x00008F83 + IDS_FWUPDATE_REBOOT_TITLE = 36740, // 0x00008F84 + IDS_FWUPDATE_REBOOT_DESCRIPTION = 36741, // 0x00008F85 + IDS_FWUPDATE_REBOOT_TEXT = 36742, // 0x00008F86 + IDS_FIRMWARE_ZUNE_FIRMWARE_EULA_TOPIC = 36746, // 0x00008F8A + IDS_ACCOUNT_CREATION_COUNTRY_ENTRY = 36747, // 0x00008F8B + IDS_ACCOUNT_CREATION_LANGUAGE_ENTRY = 36748, // 0x00008F8C + IDS_ACCOUNT_CREATION_DOB_ENTRY = 36749, // 0x00008F8D + IDS_ACCOUNT_CREATION_ZUNE_TOS_DESC = 36751, // 0x00008F8F + IDS_ACCOUNT_CREATION_SOCIAL_PROP_HEADER = 36752, // 0x00008F90 + IDS_ACCOUNT_CREATION_SOCIAL_PROP_DESC = 36753, // 0x00008F91 + IDS_ACCOUNT_CREATION_ZUNE_COMM_HEADER = 36754, // 0x00008F92 + IDS_ACCOUNT_CREATION_ZUNE_COMM_DESC = 36755, // 0x00008F93 + IDS_ACCOUNT_CREATION_ZUNE_PARTNER_HEADER = 36756, // 0x00008F94 + IDS_ACCOUNT_CREATION_ZUNE_PARTNER_DESC = 36757, // 0x00008F95 + IDS_ACCOUNT_CREATION_PARENTAL_INPUT_HEAD = 36758, // 0x00008F96 + IDS_ACCOUNT_CREATION_PARENT_EMAIL_ENTRY = 36759, // 0x00008F97 + IDS_ACCOUNT_CREATION_START_PARENT_HEADER = 36760, // 0x00008F98 + IDS_ACCOUNT_CREATION_START_PARENT_DESC = 36761, // 0x00008F99 + IDS_ACCOUNT_CREATION_PARENT_HAVEMAIL_HEAD = 36762, // 0x00008F9A + IDS_ACCOUNT_CREATION_ZUNE_TAG_HEADER = 36763, // 0x00008F9B + IDS_ACCOUNT_CREATION_ZUNE_TAG_DESC = 36764, // 0x00008F9C + IDS_ACCOUNT_CREATION_ZUNE_TAG_ENTRY = 36765, // 0x00008F9D + IDS_ACCOUNT_CREATION_ZUNE_TAG_ENTRY_HELP = 36766, // 0x00008F9E + IDS_ACCOUNT_CREATION_ZUNE_TAG_ALT_HEAD = 36767, // 0x00008F9F + IDS_ACCOUNT_CREATION_ZUNE_TAG_ALT_DESC = 36768, // 0x00008FA0 + IDS_ACCOUNT_CREATION_BLOCK = 36769, // 0x00008FA1 + IDS_ACCOUNT_CREATION_EVERYONE = 36770, // 0x00008FA2 + IDS_ACCOUNT_CREATION_FRIENDS_ONLY = 36771, // 0x00008FA3 + IDS_ACCOUNT_CREATION_EMAIL_HAVEMAIL_HEAD = 36772, // 0x00008FA4 + IDS_ACCOUNT_CREATION_EMAIL_HAVEMAIL_DESC = 36773, // 0x00008FA5 + IDS_ACCOUNT_CREATION_EMAIL_NOMAIL_HEAD = 36774, // 0x00008FA6 + IDS_ACCOUNT_CREATION_EMAIL_NOMAIL_DESC = 36775, // 0x00008FA7 + IDS_ACCOUNT_CREATION_ACCOUNT_INFO_STEP = 36776, // 0x00008FA8 + IDS_I_ACCEPT_BUTTON = 36777, // 0x00008FA9 + IDS_ACCOUNT_CREATION_FIRST_NAME = 36778, // 0x00008FAA + IDS_ACCOUNT_CREATION_LAST_NAME = 36779, // 0x00008FAB + IDS_ACCOUNT_CREATION_MOBILE_PHONE = 36780, // 0x00008FAC + IDS_ACCOUNT_CREATION_PARENT_CONTACT_HEAD = 36781, // 0x00008FAD + IDS_ACCOUNT_CREATION_CONTACT_HEAD = 36782, // 0x00008FAE + IDS_FIRMWARE_UPDATE_DO_NOT_DISCONNECT = 36784, // 0x00008FB0 + IDS_FIRMWARE_UPDATE_SUCCESS = 36785, // 0x00008FB1 + IDS_FIRMWARE_PLEASE_WAIT = 36786, // 0x00008FB2 + IDS_MANUAL_OPTION_MUSIC = 36787, // 0x00008FB3 + IDS_MANUAL_OPTION_VIDEOS = 36788, // 0x00008FB4 + IDS_MANUAL_OPTION_PICTURES = 36789, // 0x00008FB5 + IDS_ACCOUNT_CREATION_PARENT_AGE_HEADER = 36790, // 0x00008FB6 + IDS_ACCOUNT_CREATION_NAME_FORMAT = 36791, // 0x00008FB7 + IDS_ACCOUNT_CREATION_ALLOW = 36792, // 0x00008FB8 + IDS_ACCOUNT_CREATION_ZUNE_FAMILY_HEADER = 36793, // 0x00008FB9 + IDS_ACCOUNT_CREATION_ZUNE_CHILD_PURCHASE_HEAD = 36794, // 0x00008FBA + IDS_ACCOUNT_CREATION_ZUNE_CHILD_PURCHASE_DESC = 36795, // 0x00008FBB + IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_HEAD = 36796, // 0x00008FBC + IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_DESC = 36797, // 0x00008FBD + IDS_ACCOUNT_CREATION_ZUNE_CHILD_NEWFRIEND_HEAD = 36798, // 0x00008FBE + IDS_ACCOUNT_CREATION_ZUNE_CHILD_NEWFRIEND_DESC = 36799, // 0x00008FBF + IDS_ACCOUNT_CREATION_ZUNE_SOCIAL_COMM_DESC = 36800, // 0x00008FC0 + IDS_ACCOUNT_CREATION_ZUNE_CHILD_COMM_DESC = 36801, // 0x00008FC1 + IDS_ACCOUNT_CREATION_ZUNE_PROFILE_HEAD = 36802, // 0x00008FC2 + IDS_ACCOUNT_CREATION_ZUNE_PROFILE_DESC = 36803, // 0x00008FC3 + IDS_ACCOUNT_CREATION_ZUNE_CHILD_PROFILE_DESC = 36804, // 0x00008FC4 + IDS_ACCOUNT_CREATION_ZUNE_FRIENDS_HEAD = 36805, // 0x00008FC5 + IDS_ACCOUNT_CREATION_ZUNE_FRIENDS_DESC = 36806, // 0x00008FC6 + IDS_ACCOUNT_CREATION_ZUNE_CHILD_FRIENDS_DESC = 36807, // 0x00008FC7 + IDS_ACCOUNT_CREATION_ZUNE_CHILD_MUSIC_DESC = 36808, // 0x00008FC8 + IDS_ACCOUNT_EDIT_CONTACT_INFO_BUTTON = 36809, // 0x00008FC9 + IDS_ACCOUNT_EDIT_CONTACT_INFO_DETAIL = 36810, // 0x00008FCA + IDS_ACCOUNT_FINISHED_DESCRIPTION = 36811, // 0x00008FCB + IDS_ACCOUNT_CREATION_SET_TILE_TITLE = 36812, // 0x00008FCC + IDS_ACCOUNT_CREATION_SET_TILE_DESC = 36813, // 0x00008FCD + IDS_ACCOUNT_CREATION_SUPER_FRIENDS_TITLE = 36814, // 0x00008FCE + IDS_ACCOUNT_CREATION_SUPER_FRIENDS_DESC = 36815, // 0x00008FCF + IDS_DEVICE_PRIVACY_RECOMMENDED = 36816, // 0x00008FD0 + IDS_DEVICE_PRIVACY_RECOMMENDED_LABEL = 36817, // 0x00008FD1 + IDS_DEVICE_PRIVACY_RECOMMENDED_DETAILS = 36818, // 0x00008FD2 + IDS_DEVICE_PRIVACY_CUSTOMIZE = 36819, // 0x00008FD3 + IDS_DEVICE_PRIVACY_CUSTOMIZE_LABEL = 36820, // 0x00008FD4 + IDS_DEVICE_PRIVACY_CUSTOMIZE_DETAILS = 36821, // 0x00008FD5 + IDS_FUE_SIGN_IN_HEADER = 36822, // 0x00008FD6 + IDS_FUE_SIGN_IN_LABEL = 36823, // 0x00008FD7 + IDS_ACCOUNT_CREATION_FREE_TRIAL_TITLE = 36824, // 0x00008FD8 + IDS_ACCOUNT_CREATION_FREE_TRIAL_DESC = 36825, // 0x00008FD9 + IDS_BILLING_PREPAID_CODE = 36826, // 0x00008FDA + IDS_BILLING_PREPAID_CODE_DESCRIPTION = 36827, // 0x00008FDB + IDS_BILLING_PREPAID_CODE_TITLE = 36828, // 0x00008FDC + IDS_BILLING_PREPAID_CODE_HEADER = 36829, // 0x00008FDD + IDS_BILLING_TRIAL_DESCRIPTION = 36830, // 0x00008FDE + IDS_BILLING_TRIAL_TITLE = 36831, // 0x00008FDF + IDS_BILLING_SIGN_UP = 36832, // 0x00008FE0 + IDS_BILLING_EDIT_CC_EDIT_HEADER = 36833, // 0x00008FE1 + IDS_WIRELESS_SYNC_NETWORK_INFO = 36834, // 0x00008FE2 + IDS_WIRELESS_SYNC_ENABLED = 36835, // 0x00008FE3 + IDS_CLOSE_BUTTON = 36836, // 0x00008FE4 + IDS_ACCOUNT_CREATION_ERROR_TITLE = 36837, // 0x00008FE5 + IDS_ACCOUNT_CREATION_ERROR_DESC = 36838, // 0x00008FE6 + IDS_ACCOUNT_CREATION_PASSWORD_DESC = 36839, // 0x00008FE7 + IDS_ASSOCIATE_FILE_TYPES = 36840, // 0x00008FE8 + IDS_CHANGE_PRIVACY_SETTINGS = 36841, // 0x00008FE9 + IDS_FILE_TYPES_AUDIO = 36843, // 0x00008FEB + IDS_FILE_TYPES_VIDEO = 36844, // 0x00008FEC + IDS_CHOOSE_MEDIA_LOCATIONS = 36846, // 0x00008FEE + IDS_CHANGE_WHERE_ZUNE_STORES_MEDIA = 36847, // 0x00008FEF + IDS_ACCOUNT_CREATION_EMAIL_SUGGEST_TITLE = 36848, // 0x00008FF0 + IDS_ACCOUNT_CREATION_EMAIL_SUGGEST_DESC = 36849, // 0x00008FF1 + IDS_ENABLE_ZUNE_MARKETPLACE_HEADER = 36851, // 0x00008FF3 + IDS_ENABLE_ZUNE_MARKETPLACE_TEXT = 36852, // 0x00008FF4 + IDS_SKIP_FOR_NOW_OPTION = 36853, // 0x00008FF5 + IDS_ENABLE_ZUNE_MARKETPLACE_OPTION = 36854, // 0x00008FF6 + IDS_CHOOSE_MEDIA_TYPES_TO_SYNC = 36855, // 0x00008FF7 + IDS_PICK_A_NAME_HEADER = 36856, // 0x00008FF8 + IDS_SELECT_YOUR_PRIVACY_OPTIONS_HEADER = 36857, // 0x00008FF9 + IDS_SELECT_YOUR_PRIVACY_OPTIONS_TEXT = 36858, // 0x00008FFA + IDS_WEB_LINK_DIVIDER = 36859, // 0x00008FFB + IDS_ENABLE_MARKETPLACE_ON_DEVICE_HEADER = 36860, // 0x00008FFC + IDS_DEVICE_MARKETPLACE_ENABLED = 36861, // 0x00008FFD + IDS_EDIT_OS_LIBRARY_BUTTON = 36862, // 0x00008FFE + IDS_DISABLE_MARKETPLACE_BUTTON = 36863, // 0x00008FFF + IDS_SHARE_NAME_EMPTY = 36864, // 0x00009000 + IDS_SYNC_ALL_OPTION_APPLICATIONS = 36865, // 0x00009001 + IDS_LET_ME_CHOOSE_OPTION_APPLICATIONS = 36866, // 0x00009002 + IDS_MANUAL_OPTION_APPLICATIONS = 36867, // 0x00009003 + IDS_WIRELESS_SYNC_GENERIC_ERROR = 36868, // 0x00009004 + IDS_FIRMWARE_UPDATE_ERROR_TITLE = 36869, // 0x00009005 + IDS_FIRMWARE_UPDATE_ERROR_FRIENDLY = 36870, // 0x00009006 + IDS_FIRMWARE_UPDATE_ERROR_NOTICE1 = 36871, // 0x00009007 + IDS_FIRMWARE_UPDATE_ERROR_NOTICE2 = 36872, // 0x00009008 + IDS_ALL_APPLICATIONS_SYNC_GROUP = 36873, // 0x00009009 + IDS_APPLICATIONS = 36874, // 0x0000900A + IDS_METADATA_MENU_ITEM = 36875, // 0x0000900B + IDS_ACCOUNT_CREATION_SUCCESS_NEW = 36876, // 0x0000900C + IDS_ACCOUNT_CREATION_SUCCESS_EXISTING = 36877, // 0x0000900D + IDS_FWUPDATE_VERIFY_TITLE = 36878, // 0x0000900E + IDS_FWUPDATE_VERIFY_DESCRIPTION = 36879, // 0x0000900F + IDS_FWUPDATE_VERIFY_TEXT = 36880, // 0x00009010 + IDS_BILLING_CA_PROVINCES = 36881, // 0x00009011 + IDS_ACCOUNT_CONTACT_INFO_ERROR_TITLE = 36884, // 0x00009014 + IDS_ACCOUNT_CONTACT_INFO_ERROR_DESC = 36885, // 0x00009015 + IDS_ACCOUNT_CONTACT_INFO_SUCCESS_DESC = 36886, // 0x00009016 + IDS_ACCOUNT_PRIVACY_UPDATE_ERROR_TITLE = 36887, // 0x00009017 + IDS_ACCOUNT_PRIVACY_UPDATE_ERROR_DESC = 36888, // 0x00009018 + IDS_ACCOUNT_PRIVACY_UPDATE_SUCCESS_DESC = 36889, // 0x00009019 + IDS_ACCOUNT_NEWSLTR_UPDATE_ERROR_TITLE = 36890, // 0x0000901A + IDS_ACCOUNT_NEWSLTR_UPDATE_ERROR_DESC = 36891, // 0x0000901B + IDS_ACCOUNT_NEWSLTR_UPDATE_SUCCESS_DESC = 36892, // 0x0000901C + IDS_ACCOUNT_CREATION_SECRET_QUESTIONS = 36893, // 0x0000901D + IDS_ACCOUNT_PURCHASE_ERROR_TITLE = 36897, // 0x00009021 + IDS_ACCOUNT_PURCHASE_ERROR_DESC = 36898, // 0x00009022 + IDS_ACCOUNT_PURCHASE_SUCCESS_DESC = 36899, // 0x00009023 + IDS_BILLING_ADD_CC_NO_CHARGE_TRIAL = 36901, // 0x00009025 + IDS_BILLING_USE_NEW_CC = 36902, // 0x00009026 + IDS_BILLING_SELECT_A_CC = 36903, // 0x00009027 + IDS_BILLING_SELECT_A_CC_TRIAL = 36904, // 0x00009028 + IDS_BILLING_PREPAID_CODE_UNSUPPORTED = 36905, // 0x00009029 + IDS_BILLING_PREPAID_CODE_INVALID = 36906, // 0x0000902A + IDS_BILLING_PREPAID_CODE_DEFAULT = 36907, // 0x0000902B + IDS_BILLING_PREPAID_CODE_BILLING_OFFER = 36908, // 0x0000902C + IDS_BILLING_PREPAID_CODE_POINTS_TITLE = 36909, // 0x0000902D + IDS_BILLING_PREPAID_CODE_ZUNE_PASS_TITLE = 36910, // 0x0000902E + IDS_BILLING_PREPAID_CODE_ERROR_TITLE = 36911, // 0x0000902F + IDS_BILLING_PREPAID_CODE_ERROR_DESC = 36912, // 0x00009030 + IDS_BILLING_PREPAID_CODE_DEFAULT_SUCCESS = 36913, // 0x00009031 + IDS_BILLING_PREPAID_CODE_POINTS_SUCCESS = 36914, // 0x00009032 + IDS_BILLING_PREPAID_CODE_PASS_SUCCESS = 36915, // 0x00009033 + IDS_ACCOUNT_CREATION_CREDENTIALS_PARENT = 36916, // 0x00009034 + IDS_ACCOUNT_TOS_STEP_TITLE = 36917, // 0x00009035 + IDS_ACCOUNT_TOS_STEP_DESC = 36918, // 0x00009036 + IDS_ACCOUNT_TOS_ERROR_TITLE = 36919, // 0x00009037 + IDS_ACCOUNT_TOS_ERROR_DESC = 36920, // 0x00009038 + IDS_ACCOUNT_TOS_ERROR_SUCCESS_DESC = 36921, // 0x00009039 + IDS_ACCOUNT_TOS_STEP_PARENT_NEEDED = 36922, // 0x0000903A + IDS_REGDEVICES_COMPUTERS_DATE = 36923, // 0x0000903B + IDS_REGDEVICES_DEVICES_DATE = 36924, // 0x0000903C + IDS_ACCOUNT_CREATION_HIP_REFRESH = 36925, // 0x0000903D + IDS_BILLING_CURRENT_SUBSCRIPTION_RADIO_BUTTON = 36926, // 0x0000903E + IDS_ACCOUNT_RENEW_DATE_CHANGE = 36929, // 0x00009041 + IDS_SPACE_RESERVATION_DESCRIPTION_NO_MARKETPLACE = 36930, // 0x00009042 + IDS_FIRMWARE_AVAILABLE_VERSION = 36931, // 0x00009043 + IDS_FIRMWARE_NEW_VERSION_REQUIRED = 36932, // 0x00009044 + IDS_FIRMWARE_NOTICE = 36933, // 0x00009045 + IDS_FIRMWARE_UPDATE_IN_PROGRESS_HEADER = 36934, // 0x00009046 + IDS_FIRMWARE_UPDATE_SUCCESSFUL_HEADER = 36935, // 0x00009047 + IDS_FIRMWARE_UPDATE_SUCCESS_NOTICE = 36936, // 0x00009048 + IDS_FIRMWARE_UPDATE_STATUS = 36937, // 0x00009049 + IDS_ACCOUNT_CREATION_SELECT_VALUE = 36938, // 0x0000904A + IDS_WIZARD_GENERIC_ERROR = 36939, // 0x0000904B + IDS_SYNC_CHAN_FRIEND_DISABLED_EXPLANATION = 36940, // 0x0000904C + IDS_SYNC_OPTIONS_LESS_OPTIONS = 36941, // 0x0000904D + IDS_SYNC_OPTIONS_MORE_OPTIONS = 36942, // 0x0000904E + IDS_SYNC_OPTION_MEDIA_APPS = 36943, // 0x0000904F + IDS_BILLING_PURCHASE_HISTORY_HEADER = 36944, // 0x00009050 + IDS_BACKGROUND_NAME_7 = 36945, // 0x00009051 + IDS_BACKGROUND_NAME_8 = 36946, // 0x00009052 + IDS_BACKGROUND_NAME_9 = 36947, // 0x00009053 + IDS_BACKGROUND_NAME_10 = 36948, // 0x00009054 + IDS_ZUNE_MARKETPLACE_IS_ENABLED_TEXT = 36949, // 0x00009055 + IDS_FIRMWARE_MANDATE = 36950, // 0x00009056 + IDS_SHARE_TURN_ON_INSTRUCTIONS = 36951, // 0x00009057 + IDS_SHARE_TURN_OFF_INSTRUCTIONS = 36952, // 0x00009058 + IDS_REMOVE_FOLDER_WARNING = 36953, // 0x00009059 + IDS_ZUNE_MARKETPLACE_LINKEDTO = 36954, // 0x0000905A + IDS_ENABLE_ZUNE_SOCIAL_TEXT_NO_MP = 36955, // 0x0000905B + IDS_ACCOUNT_CREATION_FINISH = 36956, // 0x0000905C + IDS_ACCOUNT_CREATION_STATUS_CREATION = 36957, // 0x0000905D + IDS_ACCOUNT_CREATION_ZUNE_SOCIAL_COMM_HEADER = 36958, // 0x0000905E + IDS_ACCOUNT_ZUNE_PASS_HEADER_WITH_TRACKS = 36959, // 0x0000905F + IDS_METADATA_AND_RATINGS_MENU_ITEM = 36960, // 0x00009060 + IDS_BILLING_PREPAID_CODE_MEDIA_BUY_DESCRIPTION = 36961, // 0x00009061 + IDS_BILLING_PREPAID_CODE_MEDIA_RENT_DESCRIPTION = 36962, // 0x00009062 + IDS_BILLING_PREPAID_CODE_EXPIRED = 36963, // 0x00009063 + IDS_OPTION_FOR_SUPPORTED_ONLY = 36964, // 0x00009064 + IDS_BILLING_PREPAID_CODE_MEDIA_BUY_DESCRIPTION_SD = 36965, // 0x00009065 + IDS_BILLING_PREPAID_CODE_MEDIA_BUY_DESCRIPTION_HD = 36966, // 0x00009066 + IDS_BILLING_PREPAID_CODE_MEDIA_BUY_DESCRIPTION_SD_HD = 36967, // 0x00009067 + IDS_BILLING_PREPAID_CODE_MEDIA_RENT_DESCRIPTION_SD = 36968, // 0x00009068 + IDS_BILLING_PREPAID_CODE_MEDIA_RENT_DESCRIPTION_HD = 36969, // 0x00009069 + IDS_BILLING_PREPAID_CODE_MEDIA_RENT_DESCRIPTION_SD_HD = 36970, // 0x0000906A + IDS_SYNC_CHAN_DISABLED_EXPLANATION = 36971, // 0x0000906B + IDS_SYNC_FRIEND_DISABLED_EXPLANATION = 36972, // 0x0000906C + IDS_UPDATE_METADATA_FEATURES_CHECK = 36973, // 0x0000906D + IDS_DEVICE_USAGE_DATA_SOCIAL_REPORTS = 36974, // 0x0000906E + IDS_DEVICE_USAGE_DATA_REPORTS = 36975, // 0x0000906F + IDS_MONITOR_DESCRIPTION_WIN7 = 36976, // 0x00009070 + IDS_MONITORED_FOLDERS_LIST_WIN7 = 36977, // 0x00009071 + IDS_DEVICE_PRIVACY_MENU_ITEM = 36978, // 0x00009072 + IDS_ACCOUNT_CREATION_EVERYONE_MEDIA = 36981, // 0x00009075 + IDS_ACCOUNT_CREATION_FRIENDS_ONLY_MEDIA = 36982, // 0x00009076 + IDS_ACCOUNT_CREATION_DONT_SHARE_MEDIA = 36983, // 0x00009077 + IDS_BILLING_PREPAID_CODE_MEDIA_REVOKED = 36984, // 0x00009078 + IDS_NAME_PHONE_HEADER = 36985, // 0x00009079 + IDS_NAMEPHONE_DESC = 36986, // 0x0000907A + IDS_NAMEPHONE_DESC2 = 36987, // 0x0000907B + IDS_FIRMWARE_NOTICE_PHONE = 36988, // 0x0000907C + IDS_FIRMWARE_UPDATE_AVAILABLE_TITLE = 36989, // 0x0000907D + IDS_REGDEVICES_APP_DEVICES_COL_HEADER = 36990, // 0x0000907E + IDS_REGDEVICES_APP_PAGE_TEXT = 36991, // 0x0000907F + IDS_REGDEVICES_APP_HEADER_TEXT = 36992, // 0x00009080 + IDS_REGDEVICES_APP_DEVICES_DATE = 36993, // 0x00009081 + IDS_ADD_BUTTON = 36994, // 0x00009082 + IDS_ACCEPT_BUTTON = 36995, // 0x00009083 + IDS_VIDEO_SUPPORT_LINK_TEXT = 36996, // 0x00009084 + IDS_REMOVE_PHOTO_FOLDER_WARNING = 36997, // 0x00009085 + IDS_ACCOUNT_CREATION_MORE_EMAIL_SETTINGS_HEAD = 36998, // 0x00009086 + IDS_ACCOUNT_CREATION_MORE_EMAIL_SETTINGS_DESC = 36999, // 0x00009087 + IDS_TYPE_ALBUM = 37000, // 0x00009088 + IDS_TYPE_CARD = 37001, // 0x00009089 + IDS_TYPE_FRIENDREQUEST = 37002, // 0x0000908A + IDS_TYPE_TEXT = 37003, // 0x0000908B + IDS_TYPE_MUSICVIDEO = 37004, // 0x0000908C + IDS_TYPE_PHOTOS = 37005, // 0x0000908D + IDS_TYPE_PLAYLIST = 37006, // 0x0000908E + IDS_TYPE_PODCASTEPISODE = 37007, // 0x0000908F + IDS_TYPE_PODCASTSERIES = 37008, // 0x00009090 + IDS_TYPE_SONG = 37009, // 0x00009091 + IDS_TYPE_VIDEO = 37010, // 0x00009092 + IDS_TYPE_UNKNOWN = 37011, // 0x00009093 + IDS_BUYALL = 37012, // 0x00009094 + IDS_DELETEMESSAGE = 37013, // 0x00009095 + IDS_REPLYMESSAGE = 37014, // 0x00009096 + IDS_BUYALBUM = 37015, // 0x00009097 + IDS_1DAY_AGO_BUTTON = 37016, // 0x00009098 + IDS_1WEEK_AGO_BUTTON = 37017, // 0x00009099 + IDS_4WEEKS_AGO_BUTTON = 37018, // 0x0000909A + IDS_LIST_VIEW_BUTTON = 37019, // 0x0000909B + IDS_INBOX_UNKNOWN_MESSAGE = 37020, // 0x0000909C + IDS_NO_UPDATES = 37021, // 0x0000909D + IDS_SHOW_UPDATES_HEADER = 37022, // 0x0000909E + IDS_BUY_LATER_HEADER = 37023, // 0x0000909F + IDS_INBOX_HEADER = 37024, // 0x000090A0 + IDS_TYPE_USERCARD = 37026, // 0x000090A2 + IDS_DOWNLOADPICTURES = 37027, // 0x000090A3 + IDS_PLAYPICTURES = 37028, // 0x000090A4 + IDS_INBOX_USERCARD_LINK = 37030, // 0x000090A6 + IDS_INBOX_FRIENDREQUEST_LINK = 37032, // 0x000090A8 + IDS_COMPOSEMESSAGE = 37033, // 0x000090A9 + IDS_GOTOPROFILE = 37034, // 0x000090AA + IDS_INBOX_PICTUREDOWNLOADFOLDER = 37035, // 0x000090AB + IDS_INBOX_SIGNIN_HEADER = 37036, // 0x000090AC + IDS_INBOX_SIGNIN_MESSAGE = 37037, // 0x000090AD + IDS_INBOX_EMPTY_HEADER = 37038, // 0x000090AE + IDS_DOWNLOADPICTURES_MENUITEM = 37039, // 0x000090AF + IDS_VIEWPICTURES_MENUITEM = 37040, // 0x000090B0 + IDS_INBOX_PODCAST_SUBSCRIBE_MENUITEM = 37041, // 0x000090B1 + IDS_INBOX_PODCAST_UNSUBSCRIBE_MENUITEM = 37042, // 0x000090B2 + IDS_INBOX_VIEW_PROFILE_MENUITEM = 37043, // 0x000090B3 + IDS_DELETEMESSAGE_MENUITEM = 37044, // 0x000090B4 + IDS_REPLYMESSAGE_MENUITEM = 37045, // 0x000090B5 + IDS_INBOX_FRIENDREQUEST_ACCEPT = 37046, // 0x000090B6 + IDS_INBOX_FRIENDREQUEST_REJECT = 37047, // 0x000090B7 + IDS_INBOX_FRIENDREQUEST_ACCEPT_MENUITEM = 37048, // 0x000090B8 + IDS_INBOX_FRIENDREQUEST_REJECT_MENUITEM = 37049, // 0x000090B9 + IDS_COMPOSE_MESSAGE_MAXLENGTH = 37050, // 0x000090BA + IDS_COMPOSE_MESSAGE_TITLE = 37051, // 0x000090BB + IDS_COMPOSE_MESSAGE_DEFAULT_ATTACHMENT = 37053, // 0x000090BD + IDS_COMPOSE_MESSAGE_ALBUM_ATTACHMENT = 37054, // 0x000090BE + IDS_COMPOSE_MESSAGE_ARTIST_ATTACHMENT = 37055, // 0x000090BF + IDS_COMPOSE_MESSAGE_TRACK_ATTACHMENT = 37056, // 0x000090C0 + IDS_COMPOSE_MESSAGE_PODCAST_ATTACHMENT = 37057, // 0x000090C1 + IDS_COMPOSE_MESSAGE_PLAYLIST_ATTACHMENT = 37058, // 0x000090C2 + IDS_COMPOSE_MESSAGE_FRIEND_ATTACHMENT = 37059, // 0x000090C3 + IDS_COMPOSE_MESSAGE_SEND = 37060, // 0x000090C4 + IDS_COMPOSE_MESSAGE_RECIPIENT_HELP = 37061, // 0x000090C5 + IDS_COMPOSE_MESSAGE_RECIPIENT = 37062, // 0x000090C6 + IDS_COMPOSE_MESSAGE = 37063, // 0x000090C7 + IDS_COMPOSE_MESSAGE_FRIENDS = 37064, // 0x000090C8 + IDS_COMPOSE_MESSAGE_ERROR_FRIENDS = 37065, // 0x000090C9 + IDS_DOWNLOAD_MESSAGES_NOTIFICATION = 37066, // 0x000090CA + IDS_DOWNLOAD_MESSAGES_ERROR = 37067, // 0x000090CB + IDS_FRIENDS_SIGNIN_HEADER = 37068, // 0x000090CC + IDS_FRIENDS_SIGNIN_MESSAGE = 37069, // 0x000090CD + IDS_FRIENDS_EMPTY_HEADER = 37070, // 0x000090CE + IDS_PROFILE_SIGNIN_HEADER = 37071, // 0x000090CF + IDS_PROFILE_YOURS_SIGNIN_HEADER = 37072, // 0x000090D0 + IDS_PROFILE_SIGNIN_MESSAGE = 37073, // 0x000090D1 + IDS_PROFILECARD_SEND_MESSAGE = 37076, // 0x000090D4 + IDS_FRIENDS_EMPTY_HEADER_ERROR = 37077, // 0x000090D5 + IDS_FRIENDS_SORT_ACTIVITY = 37078, // 0x000090D6 + IDS_COMPOSE_MESSAGE_FRIENDREQUEST_ATTACHMENT = 37079, // 0x000090D7 + IDS_PROFILE_INVITE_FRIENDS_LINK = 37080, // 0x000090D8 + IDS_PROFILECARD_VIEW_PROFILE = 37081, // 0x000090D9 + IDS_PROFILE_SEND_FRIENDS_REQUEST_LINK = 37082, // 0x000090DA + IDS_PROFILE_SEND_CARD_LINK = 37083, // 0x000090DB + IDS_PROFILE_SEND_MESSAGE_LINK = 37084, // 0x000090DC + IDS_PROFILE_VIEW_ON_ZUNENET_LINK = 37085, // 0x000090DD + IDS_PROFILE_RECENTLY_PLAYED_PIVOT = 37086, // 0x000090DE + IDS_PROFILE_MOST_PLAYED_ARTISTS_PIVOT = 37087, // 0x000090DF + IDS_PROFILE_FAVORITES_PIVOT = 37088, // 0x000090E0 + IDS_PROFILE_PLAY = 37089, // 0x000090E1 + IDS_PROFILE_PLAYS = 37090, // 0x000090E2 + IDS_PROFILE_NOPLAYS = 37091, // 0x000090E3 + IDS_FRIENDS_EMPTY_DEVICE_HEADER = 37092, // 0x000090E4 + IDS_PROFILECARD_ARTIST_LABEL = 37093, // 0x000090E5 + IDS_PROFILE_REPORT_ABUSE_LINK = 37094, // 0x000090E6 + IDS_PROFILE_PRIVACY_PLAYLISTS_FRIENDS = 37095, // 0x000090E7 + IDS_PROFILE_PRIVACY_PLAYLISTS_NOBODY = 37096, // 0x000090E8 + IDS_PROFILE_PRIVACY_FRIENDS_FRIENDS = 37097, // 0x000090E9 + IDS_PROFILE_PRIVACY_FRIENDS_NOBODY = 37098, // 0x000090EA + IDS_PROFILE_PLAYLIST_RECENT_EMPTY = 37099, // 0x000090EB + IDS_PROFILE_PLAYLIST_FAVORITES_EMPTY = 37100, // 0x000090EC + IDS_PROFILE_FRIENDS_EMPTY = 37101, // 0x000090ED + IDS_PROFILE_NOT_FOUND = 37102, // 0x000090EE + IDS_PROFILE_PLAYLIST_DOWNLOAD_ERROR = 37103, // 0x000090EF + IDS_PROFILE_FRIENDS_DOWNLOAD_ERROR = 37104, // 0x000090F0 + IDS_PROFILE_DOWNLOAD_ERROR = 37105, // 0x000090F1 + IDS_FRIENDS_HEADER = 37106, // 0x000090F2 + IDS_INBOX_TYPE_SUBJECT_FORMAT = 37107, // 0x000090F3 + IDS_SOCIAL_STATUS_OFFLINE = 37108, // 0x000090F4 + IDS_INBOX_MESSAGE_PICTURE_COLLECTION = 37109, // 0x000090F5 + IDS_PROFILE_SORT_RECENT_ACTIVITY_PIVOT = 37110, // 0x000090F6 + IDS_PROFILE_SORT_TAG_ASC_PIVOT = 37111, // 0x000090F7 + IDS_INBOX_VIEW_SENDERS_PROFILE_MENUITEM = 37112, // 0x000090F8 + IDS_INBOX_CONFIRM_FRIEND_REQUEST = 37113, // 0x000090F9 + IDS_INBOX_CONFIRM_FRIEND_REQUEST_TITLE = 37114, // 0x000090FA + IDS_PROFILE_ACCOUNT_SETTINGS_LINK = 37115, // 0x000090FB + IDS_PROFILE_FRIENDS_LABEL = 37116, // 0x000090FC + IDS_PROFILE_PAGING_CONTROL_RANGE_LABEL = 37117, // 0x000090FD + IDS_PROFILE_ACCOUNT_SETTINGS_MENU_ITEM = 37118, // 0x000090FE + IDS_PROFILE_FRIENDS_EMPTY_SELF = 37119, // 0x000090FF + IDS_PROFILE_PLAYLIST_FAVS_EMPTY_SELF = 37120, // 0x00009100 + IDS_FRIENDS_SEND_REQUEST_MENUITEM = 37121, // 0x00009101 + IDS_FRIENDS_SYNC_REQUEST_WARNING = 37122, // 0x00009102 + IDS_PROFILE_BADGES_PIVOT = 37123, // 0x00009103 + IDS_PROFILE_BADGES_EMPTY = 37124, // 0x00009104 + IDS_PROFILE_PRIVACY_BADGES_NOBODY = 37125, // 0x00009105 + IDS_PROFILE_BADGES_DOWNLOAD_ERROR = 37126, // 0x00009106 + IDS_TYPE_FORUM = 37127, // 0x00009107 + IDS_INBOX_FORUM_MESSAGE = 37128, // 0x00009108 + IDS_INBOX_FORUM_LINK = 37129, // 0x00009109 + IDS_INBOX_FORUM_MENUITEM = 37130, // 0x0000910A + IDS_PROFILE_DELETE_FRIENDS_LINK = 37134, // 0x0000910E + IDS_PROFILE_EDIT_BIO = 37135, // 0x0000910F + IDS_PROFILE_EDIT_DISPLAYNAME = 37136, // 0x00009110 + IDS_PROFILE_EDIT_LOCATION = 37137, // 0x00009111 + IDS_PROFILE_EDIT_STATUS = 37138, // 0x00009112 + IDS_PROFILE_EDIT_DIALOG_TITLE = 37139, // 0x00009113 + IDS_PROFILE_BIOGRAPHY_PIVOT = 37140, // 0x00009114 + IDS_PROFILE_BIO_EMPTY = 37141, // 0x00009115 + IDS_PROFILE_BIO_EMPTY_SELF = 37142, // 0x00009116 + IDS_MENUBAR_PROFILE_PLAY = 37143, // 0x00009117 + IDS_MENUBAR_PROFILE_PLAYS = 37144, // 0x00009118 + IDS_MENUBAR_PROFILE_CREATE_ACCOUNT = 37145, // 0x00009119 + IDS_MESSAGE_SENT_NOTIFICATION = 37146, // 0x0000911A + IDS_FAVORITE_MGMT_NOTIFICATION = 37147, // 0x0000911B + IDS_FAVORITES_MGMT_NOTIFICATION = 37148, // 0x0000911C + IDS_CONFIRM_FRIEND_DELETE = 37149, // 0x0000911D + IDS_CONFIRM_FRIEND_DELETE_TITLE = 37150, // 0x0000911E + IDS_TYPE_NOTIFICATION = 37151, // 0x0000911F + IDS_INBOX_BADGE_NOTIFICATION_MENUITEM = 37152, // 0x00009120 + IDS_PROFILE_EDIT = 37153, // 0x00009121 + IDS_INBOX_BADGE_NOTIFICATION_BUTTON = 37154, // 0x00009122 + IDS_INBOX_COMMENT_NOTIFICATION_MENUITEM = 37155, // 0x00009123 + IDS_INBOX_COMMENT_NOTIFICATION_BUTTON = 37156, // 0x00009124 + IDS_INBOX_VIEW_VIDEOX_MENUITEM = 37157, // 0x00009125 + IDS_INBOX_VIEW_VIDEOX_BUTTON = 37158, // 0x00009126 + IDS_INBOX_VIEW_ON_WEB_BUTTON = 37159, // 0x00009127 + IDS_MENUBAR_PROFILE_PLAYS_NONE = 37160, // 0x00009128 + IDS_COMPOSE_MESSAGE_VIDEO_ATTACHMENT = 37161, // 0x00009129 + IDS_PROFILECARD_LOADING_PLAYLISTS = 37162, // 0x0000912A + IDS_PROFILE_EDIT_TILE_DIALOG_TITLE = 37163, // 0x0000912B + IDS_PROFILE_EDIT_BACKGROUND_DIALOG_TITLE = 37164, // 0x0000912C + IDS_PROFILE_EDIT_TILE_MENU_ITEM = 37165, // 0x0000912D + IDS_PROFILE_EDIT_BACKGROUNG_MENU_ITEM = 37166, // 0x0000912E + IDS_INBOX_MESSAGE_COUNT_SINGULAR = 37167, // 0x0000912F + IDS_INBOX_MESSAGE_COUNT_MULTIPLE = 37168, // 0x00009130 + IDS_INBOX_SORT_DESCENDING_RECEIVED = 37169, // 0x00009131 + IDS_INBOX_SORT_ASCENDING_SUBJECT = 37170, // 0x00009132 + IDS_INBOX_SORT_ASCENDING_SENDER = 37171, // 0x00009133 + IDS_INBOX_SORT_ASCENDING_TYPE = 37172, // 0x00009134 + IDS_FRIENDS_SUPER_FRIENDS_TITLE = 37173, // 0x00009135 + IDS_FRIENDS_SUPER_FRIENDS_DESCRIPTION = 37174, // 0x00009136 + IDS_FRIENDS_SUPER_FRIEND_ADD = 37175, // 0x00009137 + IDS_FRIENDS_SUPER_FRIEND_REMOVE = 37176, // 0x00009138 + IDS_INBOX_EXPIRE_TEXT = 37177, // 0x00009139 + IDS_PROFILE_COMMENTS_PIVOT = 37178, // 0x0000913A + IDS_PROFILE_COMMENTS_EMPTY = 37179, // 0x0000913B + IDS_PROFILE_COMMENTS_DOWNLOAD_ERROR = 37180, // 0x0000913C + IDS_PROFILE_COMMENTS_PRIVATE = 37181, // 0x0000913D + IDS_PROFILE_COMMENTS_UNREAD = 37182, // 0x0000913E + IDS_COMMENTS_POST_TIME = 37183, // 0x0000913F + IDS_COMMENTS_ADD_LINK = 37184, // 0x00009140 + IDS_COMMENTS_ADD = 37185, // 0x00009141 + IDS_COMMENTS_DELETE = 37186, // 0x00009142 + IDS_COMMENTS_ADD_OVERLAY = 37187, // 0x00009143 + IDS_PROFILE_EDIT_SELECT_IMAGE = 37188, // 0x00009144 + IDS_PROFILE_EDIT_IMAGE_FAIL_TITLE = 37189, // 0x00009145 + IDS_PROFILE_EDIT_TILE = 37190, // 0x00009146 + IDS_PROFILE_EDIT_BACKGROUND = 37191, // 0x00009147 + IDS_TYPE_MOVIE = 37192, // 0x00009148 + IDS_TYPE_TRAILER = 37193, // 0x00009149 + IDS_COMPOSE_MESSAGE_MOVIE_ATTACHMENT = 37194, // 0x0000914A + IDS_COMPOSE_MESSAGE_TRAILER_ATTACHMENT = 37195, // 0x0000914B + IDS_VIEW_IN_INBOX = 37196, // 0x0000914C + IDS_COMPOSE_MESSAGE_RECIPIENT_HELP_NO_EMAIL = 37197, // 0x0000914D + IDS_TYPE_APP = 37198, // 0x0000914E + IDS_COMPOSE_MESSAGE_ERROR_FRIENDS_NO_EMAIL = 37199, // 0x0000914F + IDS_COMPOSE_MESSAGE_ERROR_TOO_MANY_TRACKS = 37200, // 0x00009150 + IDS_SYNC_PROMPT_PHONE = 37201, // 0x00009151 + IDS_SYNC_PROMPT_PER_DEVICE_PHONE = 37202, // 0x00009152 + IDS_PODCAST_KEEP_SERIES_EPISODES_PHONE = 37203, // 0x00009153 + IDS_PODCAST_SYNC_NOTE_PHONE = 37204, // 0x00009154 + IDS_FRIEND_HEADER = 37205, // 0x00009155 + IDS_INBOX_LOAD_DETAILS_FAILURE_404 = 37208, // 0x00009158 + IDS_INBOX_LOAD_DETAILS_FAILURE = 37209, // 0x00009159 + IDS_COMMENTS_POST_TIME_NO_LINK = 37210, // 0x0000915A + IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_HEAD2 = 37211, // 0x0000915B + IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_DESC2 = 37212, // 0x0000915C + IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_HEAD3 = 37213, // 0x0000915D + IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_DESC3 = 37214, // 0x0000915E + IDS_ACCOUNT_CREATION_ZUNE_CHILD_EXPLICIT_LINK = 37215, // 0x0000915F + IDS_BUY_ALBUM_BUTTON = 38000, // 0x00009470 + IDS_MORE_INFO_BUTTON = 38001, // 0x00009471 + IDS_ALL_SONGS_BUTTON = 38002, // 0x00009472 + IDS_ALL_ALBUMS_BUTTON = 38004, // 0x00009474 + IDS_POPULARITY_SORT = 38005, // 0x00009475 + IDS_TITLE_SORT = 38006, // 0x00009476 + IDS_YEAR_SORT = 38007, // 0x00009477 + IDS_IN_NEWSSTAND_BUTTON = 38008, // 0x00009478 + IDS_ONLINE_BUTTON = 38009, // 0x00009479 + IDS_PLAYLISTS_BUTTON = 38010, // 0x0000947A + IDS_TOP_SONGS_BUTTON = 38011, // 0x0000947B + IDS_HOT100_BUTTON = 38012, // 0x0000947C + IDS_TOP200_BUTTON = 38013, // 0x0000947D + IDS_ZUNE_TOP_ALBUMS_BUTTON = 38014, // 0x0000947E + IDS_ZUNE_TOP_SONGS_BUTTON = 38015, // 0x0000947F + IDS_SUB_GENRES_BUTTON = 38016, // 0x00009480 + IDS_GENRE_BUTTON = 38017, // 0x00009481 + IDS_NEW_RELEASES_BUTTON = 38018, // 0x00009482 + IDS_NEWSSTAND_BUTTON = 38019, // 0x00009483 + IDS_TOP_ALBUMS_BUTTON = 38020, // 0x00009484 + IDS_TOP_ARTISTS_BUTTON = 38021, // 0x00009485 + IDS_TOP_PLAYLISTS_BUTTON = 38022, // 0x00009486 + IDS_VIEW_ALL_BUTTON = 38023, // 0x00009487 + IDS_TELL_FRIEND_BUTTON = 38024, // 0x00009488 + IDS_POINTS_COLUMN_HEADER = 38029, // 0x0000948D + IDS_PURCHASE_HEADER = 38030, // 0x0000948E + IDS_PURCHASE_BUTTON = 38031, // 0x0000948F + IDS_PURCHASE_BUY_POINTS_BUTTON = 38032, // 0x00009490 + IDS_PURCHASE_NO_REFUNDS = 38033, // 0x00009491 + IDS_PURCHASE_INSUFFICIENT_POINTS = 38035, // 0x00009493 + IDS_PURCHASE_IN_PROGRESS = 38036, // 0x00009494 + IDS_PURCHASE_BALANCE = 38037, // 0x00009495 + IDS_PURCHASE_UNKNOWN_ERROR = 38038, // 0x00009496 + IDS_DOWNLOAD_ALBUM_BUTTON = 38039, // 0x00009497 + IDS_TELL_A_FRIEND = 38040, // 0x00009498 + IDS_HELP_FOOTER_BUTTON = 38041, // 0x00009499 + IDS_PRIVACY_STATEMENT_FOOTER_BUTTON = 38042, // 0x0000949A + IDS_LEGAL_FOOTER_BUTTON = 38043, // 0x0000949B + IDS_GIVE_FEEDBACK_FOOTER_BUTTON = 38045, // 0x0000949D + IDS_BUY_AVAILABLE_MENUITEM = 38047, // 0x0000949F + IDS_DOWNLOAD_ALBUM_MENUITEM = 38048, // 0x000094A0 + IDS_ALREADY_PURCHASED = 38059, // 0x000094AB + IDS_SERVICE_OFFLINE = 38060, // 0x000094AC + IDS_NO_CONNECTION = 38061, // 0x000094AD + IDS_PURCHASE_CALC_TOTAL = 38062, // 0x000094AE + IDS_PURCHASE_NO_ITEMS = 38063, // 0x000094AF + IDS_SERIES_OFFICIAL_WEBSITE_BUTTON = 38064, // 0x000094B0 + IDS_SERVICE_404 = 38065, // 0x000094B1 + IDS_CART_TITLE = 38066, // 0x000094B2 + IDS_CART_SIGNIN_HEADER = 38067, // 0x000094B3 + IDS_CART_EMPTY_HEADER = 38068, // 0x000094B4 + IDS_CART_DOWNLOAD_ERROR = 38069, // 0x000094B5 + IDS_BUY_ONLINE = 38070, // 0x000094B6 + IDS_REMOVE_ALL_ITEMS = 38071, // 0x000094B7 + IDS_REMOVE_ITEM = 38072, // 0x000094B8 + IDS_CART_GROUPHEADER_NOT_AVAILABLE = 38073, // 0x000094B9 + IDS_LOADING = 38074, // 0x000094BA + IDS_REMOVE_MENUITEM = 38075, // 0x000094BB + IDS_CART_GROUPHEADER_NOT_AVAIL_NO_MKTPLC = 38076, // 0x000094BC + IDS_CART_FULL = 38077, // 0x000094BD + IDS_CART_TOO_MANY_NEW_ITEMS = 38078, // 0x000094BE + IDS_DOWNLOADS_TITLE = 38079, // 0x000094BF + IDS_CART_FULL_STATUS = 38080, // 0x000094C0 + IDS_CART_FULL_MORE_DEVICE_ITEMS_SINGULAR = 38081, // 0x000094C1 + IDS_CART_FULL_MORE_DEVICE_ITEMS_PLURAL = 38082, // 0x000094C2 + IDS_PURCHASE_FREE = 38083, // 0x000094C3 + IDS_PURCHASE_FREE_TRACKS_AND_NO_REFUNDS = 38084, // 0x000094C4 + IDS_PURCHASE_FREE_TRACK_BALANCE = 38085, // 0x000094C5 + IDS_ACCOUNT_FREE_TRACK_BALANCE = 38086, // 0x000094C6 + IDS_PURCHASE_FREE_TRACK_HEADER = 38087, // 0x000094C7 + IDS_PURCHASE_FREE_TRACK_TEXT_SINGULAR = 38088, // 0x000094C8 + IDS_PURCHASE_FREE_TRACK_TEXT_MULTIPLE = 38089, // 0x000094C9 + IDS_PURCHASE_FREE_TRACK_DOWNLOAD = 38090, // 0x000094CA + IDS_PURCHASE_FREE_TRACK_PURCHASE = 38091, // 0x000094CB + IDS_CONCERTS_BUTTON = 38092, // 0x000094CC + IDS_CONCERTS_TITLE = 38093, // 0x000094CD + IDS_CONCERTS_COLUMN_HEADER_CITY = 38094, // 0x000094CE + IDS_CONCERTS_COLUMN_HEADER_VENUE = 38095, // 0x000094CF + IDS_PURCHASE_POINTS_IN_PROGRESS = 38097, // 0x000094D1 + IDS_SERVICE_410 = 38098, // 0x000094D2 + IDS_SERVICE_UPGRADE_NOW = 38099, // 0x000094D3 + IDS_PURCHASE_FREE_TRACK_RESTORE_TEXT = 38102, // 0x000094D6 + IDS_ALBUM_VIEW_DECADE_EMPTY = 38103, // 0x000094D7 + IDS_NEWINZUNE_HEADER = 38105, // 0x000094D9 + IDS_NEWINZUNE_TEXT1 = 38106, // 0x000094DA + IDS_NEWINZUNE_TEXT2 = 38107, // 0x000094DB + IDS_BROWSE_EMPTY = 38108, // 0x000094DC + IDS_PURCHASE_SD_CHOICE = 38109, // 0x000094DD + IDS_PURCHASE_HD_CHOICE = 38110, // 0x000094DE + IDS_RENT_SD_CHOICE = 38113, // 0x000094E1 + IDS_RENT_HD_CHOICE = 38114, // 0x000094E2 + IDS_RENT_BUTTON = 38115, // 0x000094E3 + IDS_BIO_NO_TRACKS = 38116, // 0x000094E4 + IDS_ACCOUNT_FREE_TRACK_BALANCE_SHORT = 38117, // 0x000094E5 + IDS_ACCOUNT_FREE_TRACK_EXPIRE_SHORT = 38118, // 0x000094E6 + IDS_WATCH_NOW_CHOICE = 38119, // 0x000094E7 + IDS_DOWNLOAD_NOW_CHOICE = 38120, // 0x000094E8 + IDS_RENT_TERMS = 38121, // 0x000094E9 + IDS_RENT_CHOOSER_TITLE = 38122, // 0x000094EA + IDS_RENT_HEADER = 38123, // 0x000094EB + IDS_RENT_TARGET_PC = 38124, // 0x000094EC + IDS_RENT_TARGET_DEVICE = 38125, // 0x000094ED + IDS_RENT_CHANGE_TARGET_DEVICE = 38126, // 0x000094EE + IDS_PURCHASE_SUGGESTED_SONGS = 38127, // 0x000094EF + IDS_PURCHASE_SUGGESTED_SONGS_NOTICE = 38128, // 0x000094F0 + IDS_PURCHASE_USE_CREDITS_BUTTON = 38129, // 0x000094F1 + IDS_RENT_TARGET_NAMED_DEVICE = 38130, // 0x000094F2 + IDS_PODCAST_FREE = 38131, // 0x000094F3 + IDS_PLAYLIST_TOTALINFO_SONGS_TOTAL = 38132, // 0x000094F4 + IDS_PLAYLIST_AUTHOR_TAG = 38133, // 0x000094F5 + IDS_PURCHASE_POINTS = 38134, // 0x000094F6 + IDS_PURCHASE_POINTS_TRAILING = 38135, // 0x000094F7 + IDS_PURCHASE_RENTAL_IN_PROGRESS = 38136, // 0x000094F8 + IDS_PURCHASE_NO_REFUNDS_KNOWN_BLACKOUT = 38137, // 0x000094F9 + IDS_PURCHASE_NO_REFUNDS_UNKNOWN_BLACKOUT = 38138, // 0x000094FA + IDS_PURCHASE_SD_DESC_AND_CONDITIONS = 38139, // 0x000094FB + IDS_PURCHASE_HD_DESC_AND_CONDITIONS = 38140, // 0x000094FC + IDS_PURCHASE_FREE_NO_CHARGE = 38141, // 0x000094FD + IDS_BANDWIDTHTEST_HDCAPABLE = 38142, // 0x000094FE + IDS_BANDWIDTHTEST_SDCAPABLE = 38143, // 0x000094FF + IDS_BANDWIDTHTEST_BELOWMINIMUM = 38144, // 0x00009500 + IDS_BANDWIDTHTEST_TESTFAILED = 38145, // 0x00009501 + IDS_BADNWIDTHTEST_PROGRESSTEXT = 38146, // 0x00009502 + IDS_BANDWIDTHTEST_TRYAGAIN = 38147, // 0x00009503 + IDS_BANDWIDTHTEST_TRYAGAIN_TOOLTIP = 38149, // 0x00009505 + IDS_BANDWIDTHTEST_TITLE = 38150, // 0x00009506 + IDS_SERIES_INFO = 38151, // 0x00009507 + IDS_BANDWIDTHTEST_BELOWMINHD = 38152, // 0x00009508 + IDS_BANDWIDTHTEST_COMPLETE_TITLE = 38153, // 0x00009509 + IDS_BANDWIDTHTEST_FAILED_TITLE = 38154, // 0x0000950A + IDS_APP_COLUMN_HEADER = 38155, // 0x0000950B + IDS_PRICE_COLUMN_HEADER = 38156, // 0x0000950C + IDS_PURCHASE_SELECTED_PAYMENT_METHOD = 38157, // 0x0000950D + IDS_PURCHASE_CHANGE_PAYMENT_METHOD_BTN = 38158, // 0x0000950E + IDS_PURCHASE_PAYMENT_METHOD_ADDED = 38159, // 0x0000950F + IDS_PURCHASE_TOTAL = 38160, // 0x00009510 + IDS_CONFIRM_PURCHASE_POINTS_HEADER = 38161, // 0x00009511 + IDS_CONFIRM_PURCHASE_POINTS_TEXT = 38162, // 0x00009512 + IDS_RIGHTS_COLUMN_HEADER = 38163, // 0x00009513 + IDS_ALREADY_PURCHASED_NO_ACTION = 38164, // 0x00009514 + IDS_PLAYLIST_MORE_INFO_LINK = 38166, // 0x00009516 + IDS_CART_CANT_ADD_ITEMS = 38167, // 0x00009517 + IDS_MARKETPLACE_CULTURE_MISMATCH_TITLE = 38168, // 0x00009518 + IDS_MARKETPLACE_CULTURE_MISMATCH = 38169, // 0x00009519 + IDS_PURCHASE_BALANCE_REQUEST_FAILED = 38171, // 0x0000951B + IDS_SERVICE_407 = 38172, // 0x0000951C + IDS_PURCHASE_SUCCESS_HEADER = 38173, // 0x0000951D + IDS_PURCHASE_FREE_APP_BUTTON = 38174, // 0x0000951E + IDS_CURRENCY_WITH_TAX = 38175, // 0x0000951F + IDS_MARKETPLACE_STATUS_TEXT = 38176, // 0x00009520 + IDS_MARKETPLACE_STATUS_URL = 38177, // 0x00009521 + IDS_SEARCH_ALBUMS_HEADER = 39000, // 0x00009858 + IDS_SEARCH_ARTISTS_HEADER = 39001, // 0x00009859 + IDS_SEARCH_MARKETPLACE_HEADER = 39002, // 0x0000985A + IDS_SEARCH_COLLECTION_HEADER = 39003, // 0x0000985B + IDS_SEARCH_EPISODES_HEADER = 39005, // 0x0000985D + IDS_SEARCH_SERIES_HEADER = 39006, // 0x0000985E + IDS_SEARCH_HEADER = 39007, // 0x0000985F + IDS_SEARCH_SONGS_HEADER = 39008, // 0x00009860 + IDS_SEARCH_OTHER_VIDEOS_HEADER = 39009, // 0x00009861 + IDS_FOUND_ITEM_BUTTON2 = 39012, // 0x00009864 + IDS_SEE_ALL_BUTTON = 39013, // 0x00009865 + IDS_HIDE_ALL_BUTTON = 39014, // 0x00009866 + IDS_VIDEO_TYPE_MUSICVIDEO = 39015, // 0x00009867 + IDS_SEARCH_STATUS_OFFLINE = 39018, // 0x0000986A + IDS_FOUND_ITEM_BUTTON1 = 39019, // 0x0000986B + IDS_SEARCH_PLAYLISTS_HEADER = 39020, // 0x0000986C + IDS_SEARCH_COLLECTION_NORESULTS = 39021, // 0x0000986D + IDS_SEARCH_MARKETPLACE_NORESULTS = 39022, // 0x0000986E + IDS_SEARCH_TV_HEADER = 39025, // 0x00009871 + IDS_SEARCH_MUSICVIDEOS_HEADER = 39026, // 0x00009872 + IDS_SEARCH_FILTER_RESULTS_HEADER = 39027, // 0x00009873 + IDS_SEARCH_FILTER_ALL = 39028, // 0x00009874 + IDS_SEARCH_FILTER_ARTISTS = 39029, // 0x00009875 + IDS_SEARCH_FILTER_ALBUMS = 39030, // 0x00009876 + IDS_SEARCH_FILTER_SONGS = 39031, // 0x00009877 + IDS_SEARCH_FILTER_MUSIC_VIDEOS = 39032, // 0x00009878 + IDS_SEARCH_FILTER_TV_SHOWS = 39033, // 0x00009879 + IDS_SEARCH_FILTER_MOVIES = 39034, // 0x0000987A + IDS_SEARCH_FILTER_OTHER_VIDEO = 39035, // 0x0000987B + IDS_SEARCH_FILTER_PODCASTS = 39036, // 0x0000987C + IDS_SEARCH_FILTER_PLAYLISTS = 39037, // 0x0000987D + IDS_SEARCH_FILTER_CHANNELS = 39038, // 0x0000987E + IDS_SEARCH_FILTER_SOCIAL_USERS = 39039, // 0x0000987F + IDS_SEARCH_PROFILE_HEADER = 39040, // 0x00009880 + IDS_SEARCH_FIND_IN_SOCIAL = 39041, // 0x00009881 + IDS_SEARCH_MOVIES_HEADER = 39042, // 0x00009882 + IDS_SEARCH_CHANNELS_HEADER = 39043, // 0x00009883 + IDS_SEARCH_MARKETPLACE_GAMES_LINK = 39044, // 0x00009884 + IDS_SEARCH_MARKETPLACE_GAMES_KEYWORDS = 39045, // 0x00009885 + IDS_SEARCH_WINDOWS_PHONE_APPS_HEADER = 39046, // 0x00009886 + IDS_SEARCH_FILTER_WINDOWS_PHONE_APPS = 39047, // 0x00009887 + IDS_SUBSCRIBE_BUTTON = 40000, // 0x00009C40 + IDS_UNSUBSCRIBE_BUTTON = 40001, // 0x00009C41 + IDS_EPISODE_DESCRIPTION = 40002, // 0x00009C42 + IDS_SERIES_DESCRIPTION = 40003, // 0x00009C43 + IDS_EPISODE_COUNT = 40004, // 0x00009C44 + IDS_EXPLICIT_TEXT = 40005, // 0x00009C45 + IDS_SERIES_SETTINGS_BUTTON = 40006, // 0x00009C46 + IDS_OFFICIAL_WEBSITE_BUTTON = 40007, // 0x00009C47 + IDS_MARKETPLACE_SITE_BUTTON = 40008, // 0x00009C48 + IDS_MEDIA_TYPE_AUDIO = 40009, // 0x00009C49 + IDS_MEDIA_TYPE_VIDEO = 40010, // 0x00009C4A + IDS_MEDIA_TYPE_IMAGE = 40011, // 0x00009C4B + IDS_PODCAST_UNSUBSCRIBE_QUESTION = 40012, // 0x00009C4C + IDS_PODCAST_UNSUBSCRIBE_SAVE = 40013, // 0x00009C4D + IDS_PODCAST_UNSUBSCRIBE_DELETE = 40014, // 0x00009C4E + IDS_PODCAST_UNSUBSCRIBE_REMEMBER = 40015, // 0x00009C4F + IDS_PODCAST_SUBSCRIBE_TITLE = 40016, // 0x00009C50 + IDS_PODCAST_SETTINGS_TITLE = 40017, // 0x00009C51 + IDS_PODCAST_SERIES_SETTINGS_MENUITEM = 40019, // 0x00009C53 + IDS_PODCAST_EMPTY_TITLE = 40020, // 0x00009C54 + IDS_PODCAST_EMPTY_DESCRIPTION = 40021, // 0x00009C55 + IDS_PODCAST_MARKETPLACE_HUB_BUTTON = 40022, // 0x00009C56 + IDS_PODCAST_ADD_URL_BUTTON = 40023, // 0x00009C57 + IDS_PODCAST_CONFIRM_DIALOG_TITLE = 40024, // 0x00009C58 + IDS_PODCAST_CONFIRM_DIALOG_MESSAGE = 40025, // 0x00009C59 + IDS_PODCAST_SUBSCRIBED_NOTIFICATION = 40026, // 0x00009C5A + IDS_PODCAST_REFRESH_START_NOTIFICATION = 40027, // 0x00009C5B + IDS_PODCAST_REFRESH_END_NOTIFICATION = 40028, // 0x00009C5C + IDS_PODCAST_EPISODE_ERROR_DIALOG_TITLE = 40029, // 0x00009C5D + IDS_PODCAST_SERIES_ERROR_DIALOG_TITLE = 40030, // 0x00009C5E + IDS_PODCAST_SERIES_ERROR_MENU_ITEM = 40031, // 0x00009C5F + IDS_PODCAST_SERIES_UNSUBSCRIBE_MENU_ITEM = 40032, // 0x00009C60 + IDS_PODCAST_SERIES_RESUBSCRIBE_MENU_ITEM = 40033, // 0x00009C61 + IDS_PODCAST_MARK_AS_PLAYED_MENUITEM = 40034, // 0x00009C62 + IDS_PODCAST_MARK_AS_UNPLAYED_MENUITEM = 40035, // 0x00009C63 + IDS_PODCAST_KEEP_UNTIL_I_DELETE_MENUITEM = 40036, // 0x00009C64 + IDS_PODCAST_MARKETPLACE_SERIES_PAGE_MENUITEM = 40037, // 0x00009C65 + IDS_PODCAST_CANCEL_DOWNLOAD_MENUITEM = 40038, // 0x00009C66 + IDS_PODCAST_CHECK_FOR_UPDATES_MENUITEM = 40039, // 0x00009C67 + IDS_ENTER_URL_BUTTON = 40040, // 0x00009C68 + IDS_ENTER_URL_DIALOG_TITLE = 40041, // 0x00009C69 + IDS_ENTER_URL_DIALOG_TEXT = 40042, // 0x00009C6A + IDS_PODCAST_ADD_URL_SERIES_BUTTON = 40043, // 0x00009C6B + IDS_PODCAST_SUBSCRIPTION_ERROR = 40044, // 0x00009C6C + IDS_PODCAST_COPYRIGHT_REPLACEMENT = 40045, // 0x00009C6D + IDS_PODCAST_DELETE_SERIES_MENUITEM = 40046, // 0x00009C6E + IDS_PODCAST_DELETE_SERIES_DIALOG_TITLE = 40047, // 0x00009C6F + IDS_PODCAST_IN_COLLECTION_BUTTON = 40048, // 0x00009C70 + IDS_PODCAST_DELETE_QUESTION_1_ITEM = 40049, // 0x00009C71 + IDS_PODCAST_DELETE_QUESTION_N_ITEM = 40050, // 0x00009C72 + IDS_PODCAST_IN_COLLECTION_MENUITEM = 40051, // 0x00009C73 + IDS_PODCAST_REPORT_A_CONCERN_MENUITEM = 40052, // 0x00009C74 + IDS_PODCAST_REPORT_A_CONCERN_BUTTON = 40053, // 0x00009C75 + IDS_PODCAST_EXPLICIT_CONTENT_CAPTION = 40054, // 0x00009C76 + IDS_PODCAST_EXPLICIT_CONTENT_DOWNLOAD_MESSAGE = 40055, // 0x00009C77 + IDS_PODCAST_EXPLICIT_CONTENT_SUBSCRIBE_MESSAGE = 40056, // 0x00009C78 + IDS_PODCAST_SIGN_IN_TITLE = 40057, // 0x00009C79 + IDS_PODCAST_SIGN_IN_USERNAME = 40058, // 0x00009C7A + IDS_PODCAST_SIGN_IN_CONNECTING = 40059, // 0x00009C7B + IDS_PODCAST_SIGN_IN_HTTP_WARNING = 40060, // 0x00009C7C + IDS_PODCAST_SIGN_IN_HELP = 40061, // 0x00009C7D + IDS_PODCAST_SIGN_IN_SAVE = 40062, // 0x00009C7E + IDS_PODCAST_SIGN_IN_HOST_NAME = 40063, // 0x00009C7F + IDS_PODCAST_SIGN_IN_REALM_NAME = 40064, // 0x00009C80 + IDS_CHANNELS_EMPTY_TITLE = 40067, // 0x00009C83 + IDS_CHANNELS_EMPTY_DESCRIPTION = 40068, // 0x00009C84 + IDS_CHANNELS_MARKETPLACE_HUB_BUTTON = 40069, // 0x00009C85 + IDS_PLAYLIST_SUBSCRIPTION_ERROR = 40070, // 0x00009C86 + IDS_CHANNEL_SAVE_PLAYLIST_BUTTON = 40071, // 0x00009C87 + IDS_CHANNEL_MORE_CHANNELS_BUTTON = 40072, // 0x00009C88 + IDS_CHANNEL_MORE_INFO_BUTTON = 40073, // 0x00009C89 + IDS_CHANNEL_UNSUBSCRIBE_CONFIRM = 40074, // 0x00009C8A + IDS_CHANNEL_ERROR_DIALOG_TITLE = 40075, // 0x00009C8B + IDS_CHANNEL_ERROR_MENU_ITEM = 40076, // 0x00009C8C + IDS_CHANNEL_UNSUBSCRIBE_MENU_ITEM = 40077, // 0x00009C8D + IDS_CHANNEL_RESUBSCRIBE_MENU_ITEM = 40078, // 0x00009C8E + IDS_CHANNEL_CHECK_FOR_UPDATES_MENUITEM = 40079, // 0x00009C8F + IDS_CHANNEL_ERROR_TOOLTIP = 40080, // 0x00009C90 + IDS_CHANNEL_SAVE_AS_PLAYLIST_MENU_ITEM = 40081, // 0x00009C91 + IDS_CHANNEL_ADD_TO_COLLECTION_MENU_ITEM = 40082, // 0x00009C92 + IDS_CHANNEL_WHAT_IS_A_CHANNEL = 40083, // 0x00009C93 + IDS_CHANNEL_LAST_MODIFIED = 40084, // 0x00009C94 + IDS_CHANNEL_GENRE_CATEGORY_SEPARATOR = 40085, // 0x00009C95 + IDS_CHANNEL_DESCRIPTION = 40086, // 0x00009C96 + IDS_CHANNEL_DESCRIPTION_HEADING = 40087, // 0x00009C97 + IDS_CHANNEL_TRACKS_AND_MINUTES = 40088, // 0x00009C98 + IDS_CHANNEL_LAST_MODIFIED_ONLY = 40089, // 0x00009C99 + IDS_CHANNEL_SIGN_IN_TITLE = 40090, // 0x00009C9A + IDS_CHANNEL_SIGN_IN_TEXT = 40091, // 0x00009C9B + IDS_CHANNEL_KEEP_LISTENING_TITLE = 40092, // 0x00009C9C + IDS_CHANNEL_KEEP_LISTENING_TEXT = 40093, // 0x00009C9D + IDS_PODCAST_SIGN_IN_BASIC_AUTH = 40094, // 0x00009C9E + IDS_PODCAST_SIGN_IN_DIGEST_AUTH = 40095, // 0x00009C9F + IDS_PODCAST_SIGN_IN_NEGOTIATE_AUTH = 40096, // 0x00009CA0 + IDS_PODCAST_SIGN_IN_NTLM_AUTH = 40097, // 0x00009CA1 + IDS_PODCAST_SIGN_IN_INSECURE_AUTH_WARNING = 40098, // 0x00009CA2 + IDS_CHANNEL_UNSUBSCRIBE_CONFIRM_MULTIPLE = 40099, // 0x00009CA3 + IDS_CHANNEL_ADD_A_CHANNEL = 40100, // 0x00009CA4 + IDS_CHANNEL_MANUAL_SUBSCRIBE_NEED_SIGNIN_TITLE = 40101, // 0x00009CA5 + IDS_CHANNEL_MANUAL_SUBSCRIBE_NEED_SIGNIN_TEXT = 40102, // 0x00009CA6 + IDS_CHANNEL_SUBSCRIBE_DIALOG = 40103, // 0x00009CA7 + IDS_CHANNEL_NO_ZUNE_PASS_TITLE = 40104, // 0x00009CA8 + IDS_CHANNEL_NO_ZUNE_PASS_TEXT = 40105, // 0x00009CA9 + IDS_CHANNEL_NO_ZUNE_PASS_PERSONAL_TEXT = 40106, // 0x00009CAA + IDS_CHANNEL_EXPLICIT_CONTENT_CAPTION = 40107, // 0x00009CAB + IDS_CHANNEL_EXPLICIT_CONTENT_DOWNLOAD_MESSAGE = 40108, // 0x00009CAC + IDS_CHANNEL_EXPLICIT_CONTENT_SUBSCRIBE_MESSAGE = 40109, // 0x00009CAD + IDS_CHANNEL_SAVE_PLAYLIST_SUCCESS = 40110, // 0x00009CAE + IDS_CHANNEL_SAVE_PLAYLIST_FAILURE = 40111, // 0x00009CAF + IDS_CHANNEL_WHATS_THIS = 40112, // 0x00009CB0 + IDS_CHANNEL_SUBSCRIBED_NOTIFICATION = 40113, // 0x00009CB1 + IDS_CHANNEL_REFRESH_START_NOTIFICATION = 40114, // 0x00009CB2 + IDS_CHANNEL_REFRESH_END_NOTIFICATION = 40115, // 0x00009CB3 + IDS_CHANNEL_UPDATE_DAILY = 40116, // 0x00009CB4 + IDS_CHANNEL_UPDATE_WEEKLY = 40117, // 0x00009CB5 + IDS_CHANNEL_UPDATE_MONTHLY = 40118, // 0x00009CB6 + IDS_CHANNEL_UPDATE_RANDOM = 40119, // 0x00009CB7 + IDS_CHANNEL_LOG_ON_BUTTON = 40120, // 0x00009CB8 + IDS_CHANNEL_MACHINE_LIMIT_EXCEEDED_TITLE = 40121, // 0x00009CB9 + IDS_CHANNEL_MACHINE_LIMIT_EXCEEDED_WARNING = 40122, // 0x00009CBA + IDS_CHANNEL_DESCRIPTION_PERSONAL_GENRE = 40123, // 0x00009CBB + IDS_CHANNEL_DESCRIPTION_PERSONAL_NEWRELEASE = 40124, // 0x00009CBC + IDS_PODCAST_EMPTY_DEVICE_TITLE = 40125, // 0x00009CBD + IDS_CHANNELS_EMPTY_DEVICE_TITLE = 40126, // 0x00009CBE + IDS_PODCAST_REPORT_A_CONCERN_COPYRIGHT = 40127, // 0x00009CBF + IDS_PODCAST_REPORT_A_CONCERN_COPYRIGHT_URL = 40128, // 0x00009CC0 + IDS_PODCAST_REPORT_A_CONCERN_DONE_TITLE = 40129, // 0x00009CC1 + IDS_PODCAST_REPORT_A_CONCERN_DONE_DESC = 40130, // 0x00009CC2 + IDS_DEVICE_UP_TO_DATE = 41000, // 0x0000A028 + IDS_NAMED_DEVICE_UP_TO_DATE = 41001, // 0x0000A029 + IDS_STOP_SYNC_BUTTON = 41002, // 0x0000A02A + IDS_SYNC_ERROR_NOTIFICATION = 41003, // 0x0000A02B + IDS_DEVICE_NAME_EMPTY = 41006, // 0x0000A02E + IDS_DEVICE_NAME_TOO_LONG = 41007, // 0x0000A02F + IDS_START_SYNC_BUTTON = 41008, // 0x0000A030 + IDS_NO_DEVICE = 41009, // 0x0000A031 + IDS_SWITCH_RELATIONSHIP_BUTTON = 41010, // 0x0000A032 + IDS_ADDED_1_TRACK = 41011, // 0x0000A033 + IDS_ADDED_N_TRACKS = 41012, // 0x0000A034 + IDS_ADDED_1_ALBUM = 41013, // 0x0000A035 + IDS_ADDED_N_ALBUMS = 41014, // 0x0000A036 + IDS_ADDED_1_ARTIST = 41015, // 0x0000A037 + IDS_ADDED_N_ARTISTS = 41016, // 0x0000A038 + IDS_ADDED_1_ITEM = 41017, // 0x0000A039 + IDS_ADDED_N_ITEMS = 41018, // 0x0000A03A + IDS_SYNC_TO_DEVICE_MENUITEM = 41019, // 0x0000A03B + IDS_SYNC_DEFAULT_DEVICE_WORD = 41020, // 0x0000A03C + IDS_DELETE_FROM_DEVICE_MENUITEM = 41021, // 0x0000A03D + IDS_ITEMS_SYNCED_TITLE = 41022, // 0x0000A03E + IDS_ITEMS_SYNCED_DESCRIPTION = 41023, // 0x0000A03F + IDS_ITEMS_SYNCED_STATUS = 41024, // 0x0000A040 + IDS_ITEMS_REMAINING_TITLE = 41025, // 0x0000A041 + IDS_ITEMS_REMAINING_DESCRIPTION = 41026, // 0x0000A042 + IDS_ITEMS_REMAINING_STATUS = 41027, // 0x0000A043 + IDS_ITEMS_REMOVED_TITLE = 41028, // 0x0000A044 + IDS_ITEMS_REMOVED_DESCRIPTION = 41029, // 0x0000A045 + IDS_ITEMS_REMOVED_STATUS = 41030, // 0x0000A046 + IDS_ITEMS_FAILED_TITLE = 41031, // 0x0000A047 + IDS_ITEMS_FAILED_DESCRIPTION = 41032, // 0x0000A048 + IDS_ITEMS_FAILED_STATUS = 41033, // 0x0000A049 + IDS_DEVICE_IS_CONNECTED = 41034, // 0x0000A04A + IDS_DEVICE_IS_NOT_CONNECTED = 41035, // 0x0000A04B + IDS_DEVICE_IS_SYNCING = 41036, // 0x0000A04C + IDS_DEVICE_STATUS_HEADER_MUSIC = 41037, // 0x0000A04D + IDS_DEVICE_STATUS_HEADER_VIDEO = 41038, // 0x0000A04E + IDS_DEVICE_STATUS_HEADER_PHOTO = 41039, // 0x0000A04F + IDS_DEVICE_STATUS_HEADER_PODCAST = 41040, // 0x0000A050 + IDS_DEVICE_SETTINGS_NAME = 41042, // 0x0000A052 + IDS_DEVICE_SETTINGS_OPTIONS = 41043, // 0x0000A053 + IDS_DEVICE_SETTINGS_WIRELESS = 41044, // 0x0000A054 + IDS_DEVICE_SETTINGS_CONVERSION = 41045, // 0x0000A055 + IDS_DEVICE_SETTINGS_RESERVATION = 41046, // 0x0000A056 + IDS_ADDED_1_PHOTO = 41049, // 0x0000A059 + IDS_ADDED_N_PHOTOS = 41050, // 0x0000A05A + IDS_ADDED_1_VIDEO = 41051, // 0x0000A05B + IDS_ADDED_N_VIDEOS = 41052, // 0x0000A05C + IDS_ADDED_1_PODCAST = 41053, // 0x0000A05D + IDS_ADDED_N_PODCASTS = 41054, // 0x0000A05E + IDS_ADDED_1_PODCAST_EPISODE = 41055, // 0x0000A05F + IDS_ADDED_N_PODCAST_EPISODES = 41056, // 0x0000A060 + IDS_PLEASE_CONNECT_TO_SEE_STATUS = 41057, // 0x0000A061 + IDS_FREE_SPACE_REMAINING_IN_MB = 41058, // 0x0000A062 + IDS_FREE_SPACE_REMAINING_IN_GB = 41059, // 0x0000A063 + IDS_SYNC_GROUPS_HEADER = 41060, // 0x0000A064 + IDS_ALL_SYNCED_ITEMS = 41061, // 0x0000A065 + IDS_INDIVIDUAL_TRACKS = 41062, // 0x0000A066 + IDS_INDIVIDUAL_EPISODES = 41063, // 0x0000A067 + IDS_INDIVIDUAL_PHOTOS = 41064, // 0x0000A068 + IDS_COMPUTER_ICON_TOOLTIP = 41065, // 0x0000A069 + IDS_REVERSE_SYNC_MENUITEM = 41066, // 0x0000A06A + IDS_REMOVE_SYNC_RULE = 41071, // 0x0000A06F + IDS_EXCLUDE_ITEM = 41072, // 0x0000A070 + IDS_UNEXCLUDE_ITEM = 41073, // 0x0000A071 + IDS_DEVICE_OUT_OF_SPACE_TITLE = 41074, // 0x0000A072 + IDS_DEVICE_OUT_OF_SPACE_MESSAGE = 41075, // 0x0000A073 + IDS_MUSIC_GAS_GAUGE_FORMAT = 41077, // 0x0000A075 + IDS_VIDEO_GAS_GAUGE_FORMAT = 41078, // 0x0000A076 + IDS_PHOTO_GAS_GAUGE_FORMAT = 41079, // 0x0000A077 + IDS_PODCAST_GAS_GAUGE_FORMAT = 41080, // 0x0000A078 + IDS_OTHER_GAS_GAUGE_FORMAT = 41081, // 0x0000A079 + IDS_TOTAL_GAS_GAUGE_FORMAT = 41082, // 0x0000A07A + IDS_FREE_GAS_GAUGE_FORMAT = 41083, // 0x0000A07B + IDS_GAS_GAUGE_SIZE_IN_MB = 41084, // 0x0000A07C + IDS_GAS_GAUGE_SIZE_IN_GB = 41085, // 0x0000A07D + IDS_COMPUTER_ICON_DROP_TARGET_TOOLTIP = 41086, // 0x0000A07E + IDS_BOTTOM_TOOLBAR_NO_DEVICE = 41091, // 0x0000A083 + IDS_BOTTOM_TOOLBAR_NO_DEFAULT = 41092, // 0x0000A084 + IDS_BOTTOM_TOOLBAR_DEVICE_MANUAL = 41093, // 0x0000A085 + IDS_BOTTOM_TOOLBAR_PLAYLIST = 41094, // 0x0000A086 + IDS_ARTIST_RULE_BASE = 41095, // 0x0000A087 + IDS_ALBUM_RULE_BASE = 41096, // 0x0000A088 + IDS_FOLDER_RULE_BASE = 41097, // 0x0000A089 + IDS_PODCAST_SERIES_RULE_BASE = 41098, // 0x0000A08A + IDS_GAS_GAUGE_SIZE_IN_KB = 41100, // 0x0000A08C + IDS_ALL_PICTURE_ITEMS = 41101, // 0x0000A08D + IDS_ALL_PODCAST_ITEMS = 41102, // 0x0000A08E + IDS_BOTTOM_TOOLBAR_DEVICE_AUTO = 41103, // 0x0000A08F + IDS_CHANGE_TO_PREVIOUS_DEVICE = 41104, // 0x0000A090 + IDS_CHANGE_TO_NEXT_DEVICE = 41105, // 0x0000A091 + IDS_SYNC_CANCELLED = 41107, // 0x0000A093 + IDS_CANNOT_SYNC = 41108, // 0x0000A094 + IDS_CANNOT_SYNC_TOOLTIP = 41109, // 0x0000A095 + IDS_DEVICE_HUNG = 41110, // 0x0000A096 + IDS_DEVICE_ENUMERATION_FAILED_TITLE = 41111, // 0x0000A097 + IDS_DEVICE_ENUMERATION_FAILED_BODY = 41112, // 0x0000A098 + IDS_START_SYNC_MENUITEM = 41113, // 0x0000A099 + IDS_STOP_SYNC_MENUITEM = 41114, // 0x0000A09A + IDS_DEVICE_STATUS_HEADER_NSR_MUSIC = 41115, // 0x0000A09B + IDS_DEVICE_STATUS_HEADER_NSR_VIDEO = 41116, // 0x0000A09C + IDS_DEVICE_STATUS_HEADER_FNF_MUSIC = 41117, // 0x0000A09D + IDS_DEVICE_STATUS_HEADER_FNF_VIDEO = 41118, // 0x0000A09E + IDS_DEVICE_STATUS_HEADER_FNF_PHOTO = 41119, // 0x0000A09F + IDS_DEVICE_STATUS_HEADER_FNF_PODCAST = 41120, // 0x0000A0A0 + IDS_SYNC_ERROR_OPTION_ERROR_DETAILS = 41121, // 0x0000A0A1 + IDS_SYNC_ERROR_MISSING_FILE_OPTION_ERROR_BROWSE = 41122, // 0x0000A0A2 + IDS_SYNC_ERROR_MISSING_FILE_OPTION_ERROR_DELETE_ITEM = 41123, // 0x0000A0A3 + IDS_SYNC_ERROR_MISSING_FILE_OPTION_ERROR_DELETE_ALL = 41124, // 0x0000A0A4 + IDS_SYNC_ERROR_OPTION_ERROR_EXCLUDE_ITEM = 41125, // 0x0000A0A5 + IDS_SYNC_ERROR_OPTION_ERROR_EXCLUDE_ALL = 41126, // 0x0000A0A6 + IDS_VIEW_SYNC_OPTIONS_BUTTON = 41127, // 0x0000A0A7 + IDS_HANDLE_DEVICE_OUT_OF_SPACE_BUTTON = 41128, // 0x0000A0A8 + IDS_OUT_OF_SPACE_GAS_GAUGE_FORMAT = 41129, // 0x0000A0A9 + IDS_TRACK_RULE_BASE = 41131, // 0x0000A0AB + IDS_GENRE_RULE_BASE = 41132, // 0x0000A0AC + IDS_PLAYLIST_RULE_BASE = 41133, // 0x0000A0AD + IDS_VIDEO_RULE_BASE = 41134, // 0x0000A0AE + IDS_PHOTO_RULE_BASE = 41135, // 0x0000A0AF + IDS_PODCAST_EPISODE_RULE_BASE = 41136, // 0x0000A0B0 + IDS_FRIEND_RULE_BASE = 41137, // 0x0000A0B1 + IDS_DEVICE_STATUS_HEADER_OTHER_MUSIC = 41138, // 0x0000A0B2 + IDS_DEVICE_STATUS_HEADER_OTHER_VIDEO = 41139, // 0x0000A0B3 + IDS_DEVICE_STATUS_HEADER_OTHER_PHOTO = 41140, // 0x0000A0B4 + IDS_DEVICE_STATUS_HEADER_OTHER_PODCAST = 41141, // 0x0000A0B5 + IDS_GUEST_OUT_OF_SPACE_MESSAGE = 41143, // 0x0000A0B7 + IDS_DIALOG_TITLE_LINK_TO_SYNC_FRIENDS = 41144, // 0x0000A0B8 + IDS_DIALOG_TEXT_LINK_TO_SYNC_FRIENDS = 41145, // 0x0000A0B9 + IDS_DIALOG_BUTTON_LINK_TO_SYNC_FRIENDS = 41146, // 0x0000A0BA + IDS_ADDED_1_FRIEND = 41147, // 0x0000A0BB + IDS_ADDED_N_FRIENDS = 41148, // 0x0000A0BC + IDS_ADDED_1_PLAYLIST = 41149, // 0x0000A0BD + IDS_ADDED_N_PLAYLISTS = 41150, // 0x0000A0BE + IDS_ADDED_1_GENRE = 41151, // 0x0000A0BF + IDS_ADDED_N_GENRES = 41152, // 0x0000A0C0 + IDS_ADDED_1_FOLDER = 41153, // 0x0000A0C1 + IDS_ADDED_N_FOLDERS = 41154, // 0x0000A0C2 + IDS_ITEMS_REVERSE_SYNCED_TITLE = 41155, // 0x0000A0C3 + IDS_ITEMS_REVERSE_SYNCED_STATUS = 41156, // 0x0000A0C4 + IDS_SIDELOADER_IS_BLOCKING_STATUS = 41157, // 0x0000A0C5 + IDS_FRIEND_GAS_GAUGE_FORMAT = 41158, // 0x0000A0C6 + IDS_CHANNEL_GAS_GAUGE_FORMAT = 41159, // 0x0000A0C7 + IDS_AUDIOBOOK_GAS_GAUGE_FORMAT = 41160, // 0x0000A0C8 + IDS_DEVICE_SIGN_IN_FAILURE_TITLE = 41161, // 0x0000A0C9 + IDS_DEVICE_SIGN_IN_FAILURE_TEXT = 41162, // 0x0000A0CA + IDS_DEVICE_CREDS_GUID_MISMATCH_TITLE = 41163, // 0x0000A0CB + IDS_DEVICE_CREDS_GUID_MISMATCH_TEXT = 41164, // 0x0000A0CC + IDS_ENTER_CREDENTIALS = 41165, // 0x0000A0CD + IDS_BOTTOM_TOOLBAR_DEVICE_DISCONNECTED = 41166, // 0x0000A0CE + IDS_DEVICE_STATUS_SOCIAL_DESC_NO_ASSOC = 41168, // 0x0000A0D0 + IDS_PLEASE_CONNECT_TO_SEE_CONTENTS = 41169, // 0x0000A0D1 + IDS_SIDELOADER_IS_BLOCKING_CONTENTS = 41170, // 0x0000A0D2 + IDS_NOT_OUT_OF_SPACE_GAS_GAUGE_FORMAT = 41171, // 0x0000A0D3 + IDS_ADDED_1_CHANNEL = 41172, // 0x0000A0D4 + IDS_ADDED_N_CHANNELS = 41173, // 0x0000A0D5 + IDS_DEVICE_STATUS_HEADER_FRIEND = 41174, // 0x0000A0D6 + IDS_DEVICE_STATUS_HEADER_CHANNEL = 41175, // 0x0000A0D7 + IDS_DEVICE_STATUS_HEADER_OTHER_FRIEND = 41176, // 0x0000A0D8 + IDS_DEVICE_STATUS_HEADER_OTHER_CHANNEL = 41177, // 0x0000A0D9 + IDS_DEVICE_STATUS_SOCIAL_DESC_ASSOC = 41178, // 0x0000A0DA + IDS_ITEMS_REVERSE_SYNCED_DESCRIPTION = 41181, // 0x0000A0DD + IDS_DEVICE_STATUS_HEADER_PLAYLIST = 41182, // 0x0000A0DE + IDS_DEVICE_STATUS_HEADER_OTHER_PLAYLIST = 41183, // 0x0000A0DF + IDS_DEVICE_SUMMARY_FRIENDLY_NAME_HEADER = 41185, // 0x0000A0E1 + IDS_DEVICE_SUMMARY_LINKED_ACCOUNT_HEADER = 41186, // 0x0000A0E2 + IDS_SYNC_PROGRESS_PERCENTAGE_AND_MESSAGE = 41187, // 0x0000A0E3 + IDS_SYNC_PROGRESS_MESSAGE_ONLY = 41188, // 0x0000A0E4 + IDS_SYNC_PROGRESS_LAST_SYNCED_TIME = 41189, // 0x0000A0E5 + IDS_DEVICE_SUMMARY_DEVICE_UPDATE_TITLE = 41190, // 0x0000A0E6 + IDS_DEVICE_SUMMARY_CURRENT_FW_VERSION_HEADER = 41191, // 0x0000A0E7 + IDS_DEVICE_SUMMARY_AVAILABLE_FW_VERSION_HEADER = 41192, // 0x0000A0E8 + IDS_DEVICE_SUMMARY_INSTALL_UPDATE = 41193, // 0x0000A0E9 + IDS_EXPAND_SYNC_RESULTS = 41195, // 0x0000A0EB + IDS_COLLAPSE_SYNC_RESULTS = 41196, // 0x0000A0EC + IDS_TOTAL_GAS_GAUGE_FORMAT_STYLED = 41197, // 0x0000A0ED + IDS_SYNC_ERROR_OPTION_ERROR_FIND_COLLECTION_ITEM = 41198, // 0x0000A0EE + IDS_SYNC_ERROR_OPTION_ERROR_FIND_MARKETPLACE_ITEM = 41199, // 0x0000A0EF + IDS_SYNC_ERROR_OPTION_ERROR_DELETE_ITEM = 41200, // 0x0000A0F0 + IDS_ITEMS_REVERSE_REMAINING_TITLE = 41202, // 0x0000A0F2 + IDS_ITEMS_REVERSE_REMAINING_DESCRIPTION = 41203, // 0x0000A0F3 + IDS_ITEMS_REVERSE_REMAINING_STATUS = 41204, // 0x0000A0F4 + IDS_DEVICE_NAME_INVALID_CHARS = 41205, // 0x0000A0F5 + IDS_APPLICATION_GAS_GAUGE_FORMAT = 41206, // 0x0000A0F6 + IDS_DEVICE_STATUS_HEADER_APPLICATION = 41207, // 0x0000A0F7 + IDS_DEVICE_STATUS_HEADER_OTHER_APPLICATION = 41208, // 0x0000A0F8 + IDS_APPLICATION_RULE_BASE = 41210, // 0x0000A0FA + IDS_DEVICE_DOES_NOT_SUPPORT_APPLICATIONS_TITLE = 41211, // 0x0000A0FB + IDS_DEVICE_DOES_NOT_SUPPORT_APPLICATIONS_MESSAGE = 41212, // 0x0000A0FC + IDS_DEVICE_DOES_NOT_SUPPORT_APPLICATIONS_LINK = 41213, // 0x0000A0FD + IDS_DEVICE_SUMMARY_RELATIONSHIP_HEADER = 41214, // 0x0000A0FE + IDS_DEVICE_SUMMARY_GUEST_RELATIONSHIP = 41215, // 0x0000A0FF + IDS_SYNCITEM_TITLE_SEPARATOR = 41216, // 0x0000A100 + IDS_SYNCITEM_METADATUM_SEPARATOR = 41217, // 0x0000A101 + IDS_DEVICE_RENTAL_LEGACY_NOT_SUPPORTED = 41218, // 0x0000A102 + IDS_DEVICE_RENTAL_GUEST_DEVICE = 41219, // 0x0000A103 + IDS_BOTTOM_TOOLBAR_DEVICE_NO_APPS = 41220, // 0x0000A104 + IDS_DEVICE_RENTAL_GUEST_NOT_SUPPORTED = 41221, // 0x0000A105 + IDS_DEVICE_RENTAL_LEGACY_DEVICE = 41222, // 0x0000A106 + IDS_DEVICE_RENTAL_ERROR_HEADER = 41223, // 0x0000A107 + IDS_SYNC_TYPE_UNSUPPORTED_TITLE = 41224, // 0x0000A108 + IDS_SYNC_USERCARDS_UNSUPPORTED_MESSAGE = 41225, // 0x0000A109 + IDS_SYNC_CHANNELS_UNSUPPORTED_MESSAGE = 41226, // 0x0000A10A + IDS_SYNC_HDRENTAL_UNSUPPORTED_MESSAGE = 41227, // 0x0000A10B + IDS_SYNC_RENTAL_UNSUPPORTED_MESSAGE = 41228, // 0x0000A10C + IDS_PMX_CACHED_CONTENT_WARNING = 41229, // 0x0000A10D + IDS_PMX_CACHED_CONTENT_URL = 41230, // 0x0000A10E + IDS_BOTTOM_TOOLBAR_USERCARDS_UNSUPPORTED = 41231, // 0x0000A10F + IDS_BOTTOM_TOOLBAR_CHANNELS_UNSUPPORTED = 41232, // 0x0000A110 + IDS_BOTTOM_TOOLBAR_RENTALS_UNSUPPORTED = 41233, // 0x0000A111 + IDS_BOTTOM_TOOLBAR_HDRENTALS_UNSUPPORTED = 41234, // 0x0000A112 + IDS_ADDED_REVERSE_1_PHOTO = 41240, // 0x0000A118 + IDS_ADDED_REVERSE_N_PHOTOS = 41241, // 0x0000A119 + IDS_ADDED_REVERSE_1_VIDEO = 41242, // 0x0000A11A + IDS_ADDED_REVERSE_N_VIDEOS = 41243, // 0x0000A11B + IDS_DEVICE_SETTINGS_PICTURES = 41244, // 0x0000A11C + IDS_ITEMS_REVERSE_FAILED_TITLE = 41245, // 0x0000A11D + IDS_ITEMS_REVERSE_FAILED_DESCRIPTION = 41246, // 0x0000A11E + IDS_ITEMS_REVERSE_FAILED_STATUS = 41247, // 0x0000A11F + IDS_HOW_TO_SYNC_TO_ZUNE_DEVICES = 41248, // 0x0000A120 + IDS_HOW_TO_SYNC_TO_PHONE_DEVICES = 41250, // 0x0000A122 + IDS_DEVICE_STATUS_HEADER_FNF_APPLICATION = 41252, // 0x0000A124 + IDS_SYNC_COMPLETED = 41254, // 0x0000A126 + IDS_DEVICE_SUMMARY_AVAILABLE_UPDATE_HEADER = 41255, // 0x0000A127 + IDS_EXCLUDE_ITEM_WARNING_TITLE = 41256, // 0x0000A128 + IDS_EXCLUDE_ITEM_WARNING_TEXT = 41257, // 0x0000A129 + IDS_DEVICE_STATUS_HEADER_ENC_MUSIC = 41258, // 0x0000A12A + IDS_DEVICE_STATUS_HEADER_ENC_VIDEO = 41259, // 0x0000A12B + IDS_DEVICE_SIGN_IN_FAILURE_TEXT_UNKNONW_ZUNETAG = 41260, // 0x0000A12C + IDS_DEVICE_CREDS_GUID_MISMATCH_TEXT_UNKNONW_ZUNETAG = 41261, // 0x0000A12D + IDS_DEVICE_SETTINGS_MORE_ON_WEB = 41262, // 0x0000A12E + IDS_DEVICE_SUMMARY_INSTALLING_UPDATE_HEADER = 41263, // 0x0000A12F + IDS_DEVICE_SUMMARY_UPDATE_FAILED_HEADER = 41264, // 0x0000A130 + IDS_DEVICE_SUMMARY_UPDATES_INSTALLED_NUMBER = 41265, // 0x0000A131 + IDS_PLAYBACK_CANNOT_PLAY = 42000, // 0x0000A410 + IDS_PLAYBACK_CANNOT_PAUSE = 42001, // 0x0000A411 + IDS_PLAYBACK_ERROR = 42002, // 0x0000A412 + IDS_PLAY = 42003, // 0x0000A413 + IDS_PAUSE = 42004, // 0x0000A414 + IDS_PREVIOUS = 42005, // 0x0000A415 + IDS_NEXT = 42006, // 0x0000A416 + IDS_MUTE = 42007, // 0x0000A417 + IDS_UNMUTE = 42008, // 0x0000A418 + IDS_REPEAT_ON = 42009, // 0x0000A419 + IDS_REPEAT_OFF = 42010, // 0x0000A41A + IDS_SHUFFLE_ON = 42011, // 0x0000A41B + IDS_SHUFFLE_OFF = 42012, // 0x0000A41C + IDS_PLAYBACK_COMPONENT_MISSING = 42013, // 0x0000A41D + IDS_PLAY_ALL = 42014, // 0x0000A41E + IDS_MENUITEM_ADD_TO_NOW_PLAYING = 42015, // 0x0000A41F + IDS_STOP = 42016, // 0x0000A420 + IDS_MENUITEM_ADD_TO_RECENT_PLAYLIST = 42017, // 0x0000A421 + IDS_MENUITEM_ADD_TO_DIALOG = 42018, // 0x0000A422 + IDS_NOW_PLAYING = 42019, // 0x0000A423 + IDS_VOLUME_LABEL = 42020, // 0x0000A424 + IDS_VOLUME_LABEL_MUTED = 42021, // 0x0000A425 + IDS_UPDATE_ALBUM_ART = 42022, // 0x0000A426 + IDS_NEXT_MESSAGE = 42023, // 0x0000A427 + IDS_PLAYLIST_BURN_LIST = 42024, // 0x0000A428 + IDS_MENUITEM_ADD_TO_BURNLIST = 42025, // 0x0000A429 + IDS_ADD_ALBUM_ART = 42026, // 0x0000A42A + IDS_CHOOSE_ALBUM_ART = 42027, // 0x0000A42B + IDS_ALBUM_ART_DIALOG_ALL_PICTURES = 42028, // 0x0000A42C + IDS_PLAYBACK_CANNOT_PLAY_TOOLTIP = 42029, // 0x0000A42D + IDS_VOLUME_TOOLTIP = 42030, // 0x0000A42E + IDS_DOWNLOAD_ERROR_TOOLTIP = 42031, // 0x0000A42F + IDS_DOWNLOAD_ERROR_TITLE = 42032, // 0x0000A430 + IDS_NOW_PLAYING_ICON_TOOLTIP = 42033, // 0x0000A431 + IDS_PLAYBACK_OPENING = 42034, // 0x0000A432 + IDS_PASTE_ALBUM_ART = 42035, // 0x0000A433 + IDS_NOWPLAYINGLIST_ON = 42036, // 0x0000A434 + IDS_NOWPLAYINGLIST_OFF = 42037, // 0x0000A435 + IDS_NOWPLAYING_TRACK_PLAYS = 42038, // 0x0000A436 + IDS_NOWPLAYING_ARTIST_PLAYS = 42039, // 0x0000A437 + IDS_NOWPLAYING_TOP_LISTENER_PLAYS = 42040, // 0x0000A438 + IDS_NOWPLAYING_ARTIST_BIO_FORMAT = 42041, // 0x0000A439 + IDS_NOWPLAYING_SHOW_ARTIST_BIO_LINK = 42042, // 0x0000A43A + IDS_NOWPLAYING_TOTALPLAYS_LINE1 = 42043, // 0x0000A43B + IDS_NOWPLAYING_TOTALPLAYS_LINE2 = 42044, // 0x0000A43C + IDS_NOWPLAYING_TOTALPLAYS_FORMAT = 42045, // 0x0000A43D + IDS_NOWPLAYING_TOTALPLAYS_LINE1_SINGULAR = 42046, // 0x0000A43E + IDS_NOWPLAYING_TOTALPLAYS_LINE2_SINGULAR = 42047, // 0x0000A43F + IDS_NOWPLAYING_TOTALPLAYS_SINGULAR = 42048, // 0x0000A440 + IDS_NOWPLAYING_TRACK_PLAYS_SINGULAR = 42049, // 0x0000A441 + IDS_NOWPLAYING_ARTIST_PLAYS_SINGULAR = 42050, // 0x0000A442 + IDS_NOWPLAYING_TOP_LISTENER_PLAYS_SINGULAR = 42051, // 0x0000A443 + IDS_NOWPLAYING_DURATION_FORMAT = 42052, // 0x0000A444 + IDS_NOWPLAYING_UNRATED_TOOLTIP = 42053, // 0x0000A445 + IDS_NOWPLAYING_LIKEIT_TOOLTIP = 42054, // 0x0000A446 + IDS_NOWPLAYING_DONTLIKEIT_TOOLTIP = 42055, // 0x0000A447 + IDS_FULLSCREEN_ON = 42056, // 0x0000A448 + IDS_FULLSCREEN_OFF = 42057, // 0x0000A449 + IDS_NOWPLAYING_ZUNEPASS_UPSELL = 42059, // 0x0000A44B + IDS_NOWPLAYING_FILTER_ZUNEPASS = 42060, // 0x0000A44C + IDS_BUFFERING = 42061, // 0x0000A44D + IDS_PLAYBACK_UNKNOWN_CONCURRENT_STREAMING_RESTRICTION = 42062, // 0x0000A44E + IDS_NOWPLAYING_ZUNEPASS_NOTRIAL_UPSELL = 42063, // 0x0000A44F + IDS_DIALOG_CANCEL = 43000, // 0x0000A7F8 + IDS_DIALOG_OK = 43001, // 0x0000A7F9 + IDS_DIALOG_YES = 43002, // 0x0000A7FA + IDS_DIALOG_NO = 43003, // 0x0000A7FB + IDS_DIALOG_WEBHELP = 43004, // 0x0000A7FC + IDS_DIALOG_ERROR_SUMMARY = 43005, // 0x0000A7FD + IDS_DIALOG_ERROR_CODE = 43006, // 0x0000A7FE + IDS_PROPERTIES_ARTIST = 43007, // 0x0000A7FF + IDS_PROPERTIES_ALBUM = 43008, // 0x0000A800 + IDS_PROPERTIES_LENGTH = 43009, // 0x0000A801 + IDS_PROPERTIES_BITRATE = 43010, // 0x0000A802 + IDS_PROPERTIES_LOCATION = 43011, // 0x0000A803 + IDS_PROPERTIES_COMPOSER = 43012, // 0x0000A804 + IDS_PROPERTIES_GENRE = 43013, // 0x0000A805 + IDS_PROPERTIES_MEDIARIGHTS = 43014, // 0x0000A806 + IDS_ABOUTDIALOG_TITLE = 43015, // 0x0000A807 + IDS_ABOUTDIALOG_COPYRIGHT_LINE1 = 43016, // 0x0000A808 + IDS_ABOUTDIALOG_COPYRIGHT_LINE2 = 43017, // 0x0000A809 + IDS_ABOUTDIALOG_COPYRIGHT_LINE3 = 43018, // 0x0000A80A + IDS_ABOUTDIALOG_VERSION_HEADER = 43019, // 0x0000A80B + IDS_ABOUTDIALOG_PRODUCT_ID = 43020, // 0x0000A80C + IDS_ABOUTDIALOG_WARNING = 43021, // 0x0000A80D + IDS_ABOUTDIALOG_TECHNICAL_SUPPORT_INFORMATION = 43022, // 0x0000A80E + IDS_ABOUT = 43023, // 0x0000A80F + IDS_LOGON_HEADER = 43024, // 0x0000A810 + IDS_LOGON_BUTTON = 43025, // 0x0000A811 + IDS_LOGON_STATUS = 43026, // 0x0000A812 + IDS_PASSWORD_HEADER = 43027, // 0x0000A813 + IDS_USERNAME_HEADER = 43028, // 0x0000A814 + IDS_REMEMBER_USERNAME = 43029, // 0x0000A815 + IDS_REMEMBER_PASSWORD = 43030, // 0x0000A816 + IDS_AUTO_LOGON = 43031, // 0x0000A817 + IDS_LOGON_CREDENTIALS_ERROR = 43032, // 0x0000A818 + IDS_LOGON_CONNECT_ERROR = 43033, // 0x0000A819 + IDS_LOGON_TAG_ERROR = 43034, // 0x0000A81A + IDS_LOGON_NOT_AGREED_ERROR = 43035, // 0x0000A81B + IDS_LOGON_ACCOUNT_SUSPENDED_ERROR = 43036, // 0x0000A81C + IDS_LOGON_SUBSCRIPTION_SUSPENDED_ERROR = 43037, // 0x0000A81D + IDS_LOGON_BILLING_ERROR = 43038, // 0x0000A81E + IDS_LOGON_UNKNOWN_ERROR = 43039, // 0x0000A81F + IDS_PERSISTED_USERS_HEADER = 43040, // 0x0000A820 + IDS_CREATE_ACCOUNT_BUTTON = 43041, // 0x0000A821 + IDS_POINTS_TOTAL_FORMAT = 43042, // 0x0000A822 + IDS_CONTEXT_ACCTMGMT_MENUITEM = 43044, // 0x0000A824 + IDS_CONTEXT_FAMILYSETTINGS_MENUITEM = 43045, // 0x0000A825 + IDS_CONTEXT_PRIVACYSETTINGS_MENUITEM = 43046, // 0x0000A826 + IDS_CONTEXT_CHANGEPASSWORD_MENUITEM = 43047, // 0x0000A827 + IDS_CONTEXT_ZUNEPASS_MENUITEM = 43048, // 0x0000A828 + IDS_CONTEXT_PURCHPOINTS_MENUITEM = 43049, // 0x0000A829 + IDS_CONTEXT_REDEEMCODE_MENUITEM = 43050, // 0x0000A82A + IDS_CONTEXT_PCANDDEVICES_MENUITEM = 43051, // 0x0000A82B + IDS_CONTEXT_DOWNLOADHISTORY_MENUITEM = 43052, // 0x0000A82C + IDS_LOGON_STATUS_BUTTON = 43053, // 0x0000A82D + IDS_REMOVE_PERSISTED_USER = 43060, // 0x0000A834 + IDS_VIEW_TERMS_OF_SERVICE = 43061, // 0x0000A835 + IDS_ABOUTDIALOG_GDI_MODE_NOTICE = 43062, // 0x0000A836 + IDS_PROPERTIES_MEDIATYPE = 43063, // 0x0000A837 + IDS_PROPERTIES_RESOLUTION = 43064, // 0x0000A838 + IDS_PROPERTIES_DIMENSIONS = 43065, // 0x0000A839 + IDS_PROPERTIES_DIMENSIONS_FORMAT = 43066, // 0x0000A83A + IDS_PROPERTIES_FILENAME = 43067, // 0x0000A83B + IDS_PROPERTIES_BITRATE_FORMAT = 43068, // 0x0000A83C + IDS_PROPERTIES_FILESIZE = 43069, // 0x0000A83D + IDS_PROPERTIES_SERIES_TITLE = 43070, // 0x0000A83E + IDS_PROPERTIES_SERIES_URL = 43071, // 0x0000A83F + IDS_PROPERTIES_PUBLISHED_DATE = 43072, // 0x0000A840 + IDS_PROPERTIES_EPISODE_URL = 43073, // 0x0000A841 + IDS_PROPERTIES_RELEASE_YEAR = 43074, // 0x0000A842 + IDS_SUBSCRIPTION_MACHINE_LIMIT_EXCEEDED_TITLE = 43075, // 0x0000A843 + IDS_SUBSCRIPTION_MACHINE_LIMIT_EXCEEDED_WARNING = 43076, // 0x0000A844 + IDS_SIGNIN_BILLING_VIOLATION_TITLE = 43077, // 0x0000A845 + IDS_SIGNIN_BILLING_VIOLATION_MESSAGE = 43078, // 0x0000A846 + IDS_PROPERTIES_COPYRIGHT = 43079, // 0x0000A847 + IDS_PROPERTIES_DATE_ADDED = 43080, // 0x0000A848 + IDS_MERGE_CONFIRMATION_TITLE = 43081, // 0x0000A849 + IDS_MERGE_CONFIRM_ARTIST_TO_ARTIST = 43082, // 0x0000A84A + IDS_MERGE_CONFIRM_ARTISTS_TO_ARTIST = 43083, // 0x0000A84B + IDS_MERGE_CONFIRM_ALBUM_TO_ARTIST = 43084, // 0x0000A84C + IDS_MERGE_CONFIRM_ALBUMS_TO_ARTIST = 43085, // 0x0000A84D + IDS_MERGE_CONFIRM_ALBUM_TO_ALBUM = 43086, // 0x0000A84E + IDS_MERGE_CONFIRM_ALBUMS_TO_ALBUM = 43087, // 0x0000A84F + IDS_MERGE_CONFIRM_TRACK_TO_ALBUM = 43088, // 0x0000A850 + IDS_MERGE_CONFIRM_TRACKS_TO_ALBUM = 43089, // 0x0000A851 + IDS_MERGE_CONFIRM_TRACK_TO_ARTIST = 43090, // 0x0000A852 + IDS_MERGE_CONFIRM_TRACKS_TO_ARTIST = 43091, // 0x0000A853 + IDS_EMI_SINGLE_DIALOG_TITLE = 43092, // 0x0000A854 + IDS_EMI_MULTI_DIALOG_TITLE = 43093, // 0x0000A855 + IDS_EMI_CONFIRMMULTIEDIT_DIALOG_TITLE = 43094, // 0x0000A856 + IDS_EMI_CONFIRMMULTIEDIT_PROMPT = 43095, // 0x0000A857 + IDS_EMI_CONFIRMMULTIEDITSONG_DIALOG_TITLE = 43096, // 0x0000A858 + IDS_EMI_CONFIRMMULTIEDITSONG_PROMPT = 43097, // 0x0000A859 + IDS_EMI_HIDESONGS_BUTTON = 43098, // 0x0000A85A + IDS_EMI_SHOWSONGS_BUTTON = 43099, // 0x0000A85B + IDS_EMI_MULTIPLETITLES = 43100, // 0x0000A85C + IDS_EMI_MULTIPLEARTISTS = 43101, // 0x0000A85D + IDS_EMI_MULTIPLEYEARS = 43102, // 0x0000A85E + IDS_EMI_MULTIPLEGENRES = 43103, // 0x0000A85F + IDS_EMI_MULTIPLECONDUCTORS = 43104, // 0x0000A860 + IDS_EMI_MULTIPLECOMPOSERS = 43105, // 0x0000A861 + IDS_ESI_SINGLE_DIALOG_TITLE = 43106, // 0x0000A862 + IDS_ESI_MULTI_DIALOG_TITLE = 43107, // 0x0000A863 + IDS_EMI_TAG_TITLE = 43108, // 0x0000A864 + IDS_EMI_TAG_SONGTITLE = 43109, // 0x0000A865 + IDS_EMI_TAG_ALBUMTITLE = 43110, // 0x0000A866 + IDS_EMI_TAG_ARTIST = 43111, // 0x0000A867 + IDS_EMI_TAG_SONGARTIST = 43112, // 0x0000A868 + IDS_EMI_TAG_ALBUMARTIST = 43113, // 0x0000A869 + IDS_EMI_TAG_GENRE = 43114, // 0x0000A86A + IDS_EMI_TAG_COMPOSER = 43115, // 0x0000A86B + IDS_EMI_TAG_CONDUCTOR = 43116, // 0x0000A86C + IDS_EMI_TAG_YEAR = 43117, // 0x0000A86D + IDS_EMI_TAG_TRACK = 43118, // 0x0000A86E + IDS_EMI_TAG_DISC = 43119, // 0x0000A86F + IDS_EMI_TRACK_HEADER = 43120, // 0x0000A870 + IDS_EMI_TITLE_HEADER = 43121, // 0x0000A871 + IDS_EMI_SONGARTIST_HEADER = 43122, // 0x0000A872 + IDS_EMI_COMPOSER_HEADER = 43123, // 0x0000A873 + IDS_EMI_GENRE_HEADER = 43124, // 0x0000A874 + IDS_EMI_DISC_HEADER = 43125, // 0x0000A875 + IDS_CAC_DIALOG_TITLE = 43126, // 0x0000A876 + IDS_CAC_ALBUMSONGS = 43127, // 0x0000A877 + IDS_CAC_ACCEPTCHANGES = 43128, // 0x0000A878 + IDS_CAC_ALBUMDETAIL_SINGULAR = 43129, // 0x0000A879 + IDS_CAC_ALBUMDETAIL_PLURAL = 43130, // 0x0000A87A + IDS_CAC_EDIT = 43131, // 0x0000A87B + IDS_MERGE_CONFIRM_GENRE_TO_GENRE = 43132, // 0x0000A87C + IDS_MERGE_CONFIRM_GENRES_TO_GENRE = 43133, // 0x0000A87D + IDS_MERGE_CONFIRM_ALBUM_TO_GENRE = 43134, // 0x0000A87E + IDS_MERGE_CONFIRM_ALBUMS_TO_GENRE = 43135, // 0x0000A87F + IDS_MERGE_CONFIRM_TRACK_TO_GENRE = 43136, // 0x0000A880 + IDS_MERGE_CONFIRM_TRACKS_TO_GENRE = 43137, // 0x0000A881 + IDS_EMI_CONFIRMMULTIEDITVIDEO_DIALOG_TITLE = 43138, // 0x0000A882 + IDS_EMI_CONFIRMMULTIEDITVIDEO_PROMPT = 43139, // 0x0000A883 + IDS_EMI_MULTIPLEDIRECTORS = 43140, // 0x0000A884 + IDS_EMI_MULTIPLEDESCRIPTIONS = 43141, // 0x0000A885 + IDS_EMI_SINGLE_VIDEO_DIALOG_TITLE = 43142, // 0x0000A886 + IDS_EMI_MULTI_VIDEO_DIALOG_TITLE = 43143, // 0x0000A887 + IDS_EMI_TAG_CATEGORY = 43144, // 0x0000A888 + IDS_EMI_TAG_SERIES_TITLE = 43145, // 0x0000A889 + IDS_EMI_TAG_SEASON_NUMBER = 43146, // 0x0000A88A + IDS_EMI_TAG_EPISODE_TITLE = 43147, // 0x0000A88B + IDS_EMI_TAG_EPISODE_NUMBER = 43148, // 0x0000A88C + IDS_EMI_TAG_DIRECTOR = 43149, // 0x0000A88D + IDS_EMI_TAG_RELEASE_DATE = 43150, // 0x0000A88E + IDS_EMI_TAG_DESCRIPTION = 43151, // 0x0000A88F + IDS_EMI_MULTIPLEDATES = 43153, // 0x0000A891 + IDS_EMI_FINDINFO = 43154, // 0x0000A892 + IDS_EMI_CHANGEIMAGE = 43155, // 0x0000A893 + IDS_FINDALBUMINFO_DIALOGTITLE = 43156, // 0x0000A894 + IDS_FINDALBUMINFO_TRACKCOUNTSONG = 43157, // 0x0000A895 + IDS_FINDALBUMINFO_TRACKCOUNTSONGS = 43158, // 0x0000A896 + IDS_FINDALBUMINFO_GENREDATE = 43159, // 0x0000A897 + IDS_FINDALBUMINFO_BUY = 43160, // 0x0000A898 + IDS_FINDALBUMINFO_EDIT = 43161, // 0x0000A899 + IDS_FINDALBUMINFO_SEARCH = 43162, // 0x0000A89A + IDS_FINDALBUMINFO_ALBUMSPIVOT = 43164, // 0x0000A89C + IDS_FINDALBUMINFO_ARTISTSPIVOT = 43165, // 0x0000A89D + IDS_FINDALBUMINFO_ARTISTALBUMSPIVOT = 43166, // 0x0000A89E + IDS_FINDALBUMINFO_CURRENTINFO = 43167, // 0x0000A89F + IDS_FINDALBUMINFO_NEWINFO = 43168, // 0x0000A8A0 + IDS_FINDALBUMINFO_SEARCHLABEL = 43169, // 0x0000A8A1 + IDS_FINDALBUMINFO_SONGMATCHFORMAT = 43171, // 0x0000A8A3 + IDS_FINDALBUMINFO_MATCHSONGS = 43173, // 0x0000A8A5 + IDS_FINDALBUMINFO_MATCHSONGSINSTRUCTIONS = 43174, // 0x0000A8A6 + IDS_FINDALBUMINFO_ALBUMSONGS = 43175, // 0x0000A8A7 + IDS_FINDALBUMINFO_NO_CONNECTION = 43176, // 0x0000A8A8 + IDS_FINDALBUMINFO_SERVICE_UNAVAILABLE = 43177, // 0x0000A8A9 + IDS_EMI_INVALIDITEMS = 43178, // 0x0000A8AA + IDS_FINDALBUMINFO_LOCAL_SONGS = 43179, // 0x0000A8AB + IDS_FINDALBUMINFO_AVAILABLE_SONGS = 43180, // 0x0000A8AC + IDS_FINDALBUMINFO_ORIGINAL_SONG_HEADER = 43181, // 0x0000A8AD + IDS_FINDALBUMINFO_AVAILABLE_SONG_HEADER = 43182, // 0x0000A8AE + IDS_FINDALBUMINFO_SELECT_SONG_TITLE = 43183, // 0x0000A8AF + IDS_FINDALBUMINFO_SEARCHING = 43184, // 0x0000A8B0 + IDS_FINDALBUMINFO_RETRIEVING_DATA = 43185, // 0x0000A8B1 + IDS_EMI_MULTIPLEDISCS = 43186, // 0x0000A8B2 + IDS_SOCIAL_LOG_ON_BUTTON = 43187, // 0x0000A8B3 + IDS_CONTEXT_GETZUNEPASS_MENUITEM = 43188, // 0x0000A8B4 + IDS_LOGON_HEADER_CONFIRM_PASSWORD = 43189, // 0x0000A8B5 + IDS_LOGON_BUTTON_CONFIRM = 43190, // 0x0000A8B6 + IDS_EMI_UPDATEFAILED_TITLE = 43191, // 0x0000A8B7 + IDS_EMI_UPDATEFAILED = 43192, // 0x0000A8B8 + IDS_VIEW_TERMS_OF_SERVICE_CLICKED = 43193, // 0x0000A8B9 + IDS_PROPERTIES_ARTISTS = 43194, // 0x0000A8BA + IDS_PROPERTIES_TRACK_NUMBER = 43195, // 0x0000A8BB + IDS_PROPERTIES_DISC_NUMBER = 43196, // 0x0000A8BC + IDS_PROPERTIES_CONDUCTOR = 43197, // 0x0000A8BD + IDS_CREATE_ACCOUNT_MORE_LINK = 43198, // 0x0000A8BE + IDS_NONPERSISTED_ACCOUNT_MORE_LINK = 43199, // 0x0000A8BF + IDS_PERSISTED_ACCOUNT_MORE_LINK = 43200, // 0x0000A8C0 + IDS_SWITCH_ACCOUNT_BUTTON = 43201, // 0x0000A8C1 + IDS_LOGON_DESCRIPTION = 43202, // 0x0000A8C2 + IDS_SWITCH_DESCRIPTION = 43203, // 0x0000A8C3 + IDS_SWITCH_HEADER = 43204, // 0x0000A8C4 + IDS_PROPERTIES_AUTHOR = 43205, // 0x0000A8C5 + IDS_EULA_DIALOG_TITLE = 43206, // 0x0000A8C6 + IDS_EULA_DIALOG_ACCEPT_DECLINE_TEXT = 43207, // 0x0000A8C7 + IDS_EULA_DIALOG_ACCEPT_BUTTON = 43208, // 0x0000A8C8 + IDS_EULA_DIALOG_DECLINE_BUTTON = 43209, // 0x0000A8C9 + IDS_LOGON_TOS_DIALOG_TITLE = 43210, // 0x0000A8CA + IDS_LOGON_TOS_DIALOG_DESCRIPTION = 43211, // 0x0000A8CB + IDS_PROPERTIES_BITRATE_UNITS = 43214, // 0x0000A8CE + IDS_VERIFY_SAVE_CREDS_BUTTON = 43215, // 0x0000A8CF + IDS_VERIFY_CREDS_ERROR = 43216, // 0x0000A8D0 + IDS_EXTERNAL_LINK_BLOCKED_HEADER = 43217, // 0x0000A8D1 + IDS_EXTERNAL_LINK_BLOCKED_GENERAL = 43218, // 0x0000A8D2 + IDS_EXTERNAL_LINK_BLOCKED_PODCAST = 43220, // 0x0000A8D4 + IDS_EXTERNAL_LINK_BLOCKED_VIDEO = 43221, // 0x0000A8D5 + IDS_EXTERNAL_LINK_BLOCKED_CHANNEL = 43222, // 0x0000A8D6 + IDS_PROPERTIES_VIDEO_ARTIST = 43223, // 0x0000A8D7 + IDS_DIALOG_ERROR_GENERIC_MESSAGE = 43224, // 0x0000A8D8 + IDS_PROPERTIES_DIMENSIONS_FORMAT_VIDEO = 43226, // 0x0000A8DA + IDS_CONTEXT_NEWSLTRSETTINGS_MENUITEM = 43227, // 0x0000A8DB + IDS_PROPERTIES_VERSION = 43228, // 0x0000A8DC + IDS_EXTERNAL_LINK_BLOCKED_APPS = 43229, // 0x0000A8DD + IDS_WARNING_DIALOG_HEADER = 43230, // 0x0000A8DE + IDS_FW_UPDATE_CLOSE_DIALOG_MESSAGE = 43231, // 0x0000A8DF + IDS_DIALOG_CLOSE_SOFTWARE = 43232, // 0x0000A8E0 + IDS_IMAGE_ALL_FILTER_NAME = 43233, // 0x0000A8E1 + IDS_IMAGE_JPEG_FILTER_NAME = 43234, // 0x0000A8E2 + IDS_IMAGE_PNG_FILTER_NAME = 43235, // 0x0000A8E3 + IDS_IMAGE_BITMAP_FILTER_NAME = 43236, // 0x0000A8E4 + IDS_IMAGE_GIF_FILTER_NAME = 43237, // 0x0000A8E5 + IDS_IMAGE_TIFF_FILTER_NAME = 43238, // 0x0000A8E6 + IDS_EULA_DIALOG_TEXTAREA_TITLE = 43239, // 0x0000A8E7 + IDS_SIGNIN_REGION_INVALID_TITLE = 43240, // 0x0000A8E8 + IDS_SIGNIN_REGION_INVALID_MESSAGE = 43241, // 0x0000A8E9 + IDS_SIGNIN_REGION_MISMATCH_TEXT = 43242, // 0x0000A8EA + IDS_EULA_DIALOG_TITLE_REQUIRED = 43243, // 0x0000A8EB + IDS_CONTEXT_ADD_CC_TO_ACCOUNT_MENUITEM = 43244, // 0x0000A8EC + IDS_FW_RESTORE_CLOSE_DIALOG_MESSAGE = 43246, // 0x0000A8EE + IDS_LABEL_TAKEDOWN_TITLE = 43247, // 0x0000A8EF + IDS_LABEL_TAKEDOWN_WARNING = 43248, // 0x0000A8F0 + IDS_EXTERNAL_LINK_BLOCKED_MUSIC = 43249, // 0x0000A8F1 + IDS_LABEL_TAKEDOWN_LINK = 43250, // 0x0000A8F2 + IDS_FORGOT_PASSWORD_LINK = 43251, // 0x0000A8F3 + IDS_FORGOT_PASSWORD_URL = 43252, // 0x0000A8F4 + IDS_PROXY_LOGIN_TITLE = 43253, // 0x0000A8F5 + IDS_PROXY_LOGIN_USERNAME_HEADER = 43254, // 0x0000A8F6 + IDS_PROXY_LOGIN_BAD_CREDENTIALS = 43255, // 0x0000A8F7 + IDS_EXTERNAL_LINK_BLOCKED_TV = 43256, // 0x0000A8F8 + IDS_DIALOG_ERROR_WEBHELP = 43257, // 0x0000A8F9 + IDS_EXTERNAL_LINK_BLOCKED_SUBSCRIPTION = 43259, // 0x0000A8FB + IDS_LOGON_NEW_USER_HEADER = 43260, // 0x0000A8FC + IDS_EMI_TAG_TITLE_YOMI = 43261, // 0x0000A8FD + IDS_EMI_TAG_ALBUMTITLE_YOMI = 43262, // 0x0000A8FE + IDS_EMI_TAG_ALBUMARTIST_YOMI = 43263, // 0x0000A8FF + IDS_EMI_TAG_ARTIST_YOMI = 43264, // 0x0000A900 + IDS_EMI_HIDESORT_BUTTON = 43265, // 0x0000A901 + IDS_EMI_SHOWSORT_BUTTON = 43266, // 0x0000A902 + IDS_FW_BACKUP_CLOSE_DIALOG_MESSAGE = 43267, // 0x0000A903 + IDS_NAME_SORT = 44000, // 0x0000ABE0 + IDS_DATETAKEN_SORT = 44001, // 0x0000ABE1 + IDS_PHOTO_PLAY_TOOLTIP = 44002, // 0x0000ABE2 + IDS_PHOTO_CONTINUE_TOOLTIP = 44003, // 0x0000ABE3 + IDS_PHOTO_PAUSE_TOOLTIP = 44004, // 0x0000ABE4 + IDS_PHOTO_PREVIOUS_TOOLTIP = 44005, // 0x0000ABE5 + IDS_PHOTO_NEXT_TOOLTIP = 44006, // 0x0000ABE6 + IDS_PHOTO_SHOWTRANSPORTS_TOOLTIP = 44007, // 0x0000ABE7 + IDS_PHOTO_PLAY_MENUITEM = 44008, // 0x0000ABE8 + IDS_PHOTO_PAUSE_MENUITEM = 44009, // 0x0000ABE9 + IDS_PHOTOS_0_1_HEADER = 44010, // 0x0000ABEA + IDS_PHOTOS_0_N_HEADER = 44011, // 0x0000ABEB + IDS_BUY_MORE_ARTIST = 44018, // 0x0000ABF2 + IDS_PHOTO_TRANSPORT_SHOWMUSIC_TOOLTIP = 44019, // 0x0000ABF3 + IDS_PHOTO_TRANSPORT_SHOWPHOTO_TOOLTIP = 44020, // 0x0000ABF4 + IDS_PHOTO_ADD_FOLDER_TITLE = 44024, // 0x0000ABF8 + IDS_PHOTO_ADD_FOLDER_DESCRIPTION = 44025, // 0x0000ABF9 + IDS_PHOTO_ADD_FOLDER_BUTTON = 44026, // 0x0000ABFA + IDS_PHOTOS_ALBUMS_HEADER = 44028, // 0x0000ABFC + IDS_PHOTOS_VIEW_IN_PHOTO_GALLERY = 44030, // 0x0000ABFE + IDS_PHOTOS_EDIT_AND_SHARE = 44031, // 0x0000ABFF + IDS_PHOTOS_UPSELL_PHOTO_GALLERY_TITLE = 44032, // 0x0000AC00 + IDS_PHOTOS_UPSELL_MOVIE_MAKER_TITLE = 44033, // 0x0000AC01 + IDS_PHOTOS_UPSELL_PHOTO_GALLERY_TEXT = 44034, // 0x0000AC02 + IDS_PHOTOS_UPSELL_MOVIE_MAKER_TEXT = 44035, // 0x0000AC03 + IDS_PHOTOS_UPSELL_DOWNLOAD = 44036, // 0x0000AC04 + IDS_PHOTOS_UPSELL_PHOTO_GALLERY_URL = 44037, // 0x0000AC05 + IDS_PHOTOS_UPSELL_MOVIE_MAKER_URL = 44038, // 0x0000AC06 + IDS_PHOTOS_PHOTO_GALLERY_PATH = 44039, // 0x0000AC07 + IDS_INVALID_FILE_CHARACTERS = 44040, // 0x0000AC08 + IDS_PHOTOS_EMPTY_FOLDER_LABEL = 44041, // 0x0000AC09 + IDS_PHOTOS_MOVIE_MAKER_TITLE = 44042, // 0x0000AC0A + IDS_PHOTOS_CREATE_MOVIE = 44043, // 0x0000AC0B + IDS_PHOTOS_MOVIE_MAKER_ARGS = 44044, // 0x0000AC0C + IDS_PHOTOS_MOVIE_MAKER_TOO_MANY_TITLE = 44045, // 0x0000AC0D + IDS_PHOTOS_MOVIE_MAKER_TOO_MANY_DESC = 44046, // 0x0000AC0E + IDS_PHOTOS_MOVIE_MAKER_DESC = 44047, // 0x0000AC0F + IDS_PHOTOS_AUTOUPLOADER_NOTIFICATION = 44050, // 0x0000AC12 + IDS_PHOTOS_AUTOUPLOADER_FIND_OUT_MORE = 44051, // 0x0000AC13 + IDS_PHOTOS_AUTOUPLOADER_VIEW_PICS = 44052, // 0x0000AC14 + IDS_PHOTOS_AUTOUPLOADER_VIEW_SETTINGS = 44053, // 0x0000AC15 + IDS_PHOTOS_FOLDER_NOTEXIST_LABEL = 44054, // 0x0000AC16 + IDS_PHOTOS_NO_FOLDER_SELECTED = 44055, // 0x0000AC17 + IDS_PHOTOS_MOVIE_MAKER_NO_PLAYLIST = 44056, // 0x0000AC18 + IDS_PHOTO_DELETE_PICTURES_TITLE = 44061, // 0x0000AC1D + IDS_PHOTO_DELETE_PICTURES_TEXT = 44062, // 0x0000AC1E + IDS_PHOTO_DELETE_PICTURES_SYNCED_TEXT = 44063, // 0x0000AC1F + IDS_PHOTO_DELETE_PICTURE_TEXT = 44068, // 0x0000AC24 + IDS_PHOTO_DELETE_PICTURE_SYNCED_TEXT = 44069, // 0x0000AC25 + IDS_PHOTO_DELETE_PICTURE_TITLE = 44071, // 0x0000AC27 + IDS_PHOTOS_VIEW_IN_PHOTO_GALLERY_MORELINK = 44073, // 0x0000AC29 + IDS_PHOTOS_AUTOUPLOADER_PICTURES_URL = 44074, // 0x0000AC2A + IDS_PHOTOS_AUTOUPLOADER_SETTINGS_URL = 44075, // 0x0000AC2B + IDS_PHOTOS_PHOTO_GALLERY_OPEN_FILE = 44076, // 0x0000AC2C + IDS_PHOTOS_PHOTO_GALLERY_OPEN_FOLDER = 44077, // 0x0000AC2D + IDS_PHOTOS_PERSONAL_VIDEOS_LINK = 44079, // 0x0000AC2F + IDS_PHOTOS_REVERSE_SYNC_CAMERA_ROLL = 44080, // 0x0000AC30 + IDS_PHOTOS_REVERSE_SYNC_SAVED_CONTENT = 44081, // 0x0000AC31 + IDS_DATE_ADDED_SORT = 45000, // 0x0000AFC8 + IDS_VIDEO_PLAY_MENUITEM = 45001, // 0x0000AFC9 + IDS_VIDEOS_HEADER = 45002, // 0x0000AFCA + IDS_EPISODE_TITLE_SORT = 45003, // 0x0000AFCB + IDS_SERIES_TITLE_SORT = 45004, // 0x0000AFCC + IDS_GENRE_SORT = 45005, // 0x0000AFCD + IDS_CATEGORY_SORT = 45006, // 0x0000AFCE + IDS_VIDEO_SERIES_GROUP_HEADER = 45007, // 0x0000AFCF + IDS_VIDEO_UNKNOWN_SERIES = 45008, // 0x0000AFD0 + IDS_VIDEO_UNKNOWN_GENRE = 45009, // 0x0000AFD1 + IDS_VIDEO_DETAILS = 45010, // 0x0000AFD2 + IDS_VIDEO_SELECT_ONE = 45011, // 0x0000AFD3 + IDS_VIDEO_EPISODE_NUMBER = 45012, // 0x0000AFD4 + IDS_VIDEO_GENRE = 45013, // 0x0000AFD5 + IDS_VIDEO_RELEASE_DATE = 45014, // 0x0000AFD6 + IDS_VIDEO_DIRECTOR = 45017, // 0x0000AFD9 + IDS_VIDEO_NETWORK = 45018, // 0x0000AFDA + IDS_VIDEO_GENRE_ACTION_ADVENTURE = 45019, // 0x0000AFDB + IDS_VIDEO_GENRE_COMEDY = 45020, // 0x0000AFDC + IDS_VIDEO_GENRE_DOCUMENTARY = 45021, // 0x0000AFDD + IDS_VIDEO_GENRE_DRAMA = 45022, // 0x0000AFDE + IDS_VIDEO_GENRE_FAMILY = 45023, // 0x0000AFDF + IDS_VIDEO_GENRE_FOREIGN_INDEPENDENT = 45024, // 0x0000AFE0 + IDS_VIDEO_GENRE_HORROR = 45025, // 0x0000AFE1 + IDS_VIDEO_GENRE_OTHER = 45026, // 0x0000AFE2 + IDS_VIDEO_GENRE_ROMANCE = 45027, // 0x0000AFE3 + IDS_VIDEO_GENRE_SCIFI_FANTASY = 45028, // 0x0000AFE4 + IDS_VIDEO_GENRE_THRILLER_MYSTERY = 45029, // 0x0000AFE5 + IDS_VIDEO_GENRE_DOCUMENTARY_BIO = 45030, // 0x0000AFE6 + IDS_VIDEO_GENRE_EDUCATIONAL = 45031, // 0x0000AFE7 + IDS_VIDEO_GENRE_FAMILY_CHILDREN = 45032, // 0x0000AFE8 + IDS_VIDEO_GENRE_MOVIES = 45033, // 0x0000AFE9 + IDS_VIDEO_GENRE_MUSIC = 45034, // 0x0000AFEA + IDS_VIDEO_GENRE_NEWS = 45035, // 0x0000AFEB + IDS_VIDEO_GENRE_SOAP = 45036, // 0x0000AFEC + IDS_VIDEO_GENRE_SPORTS = 45037, // 0x0000AFED + IDS_VIDEO_GENRE_REALITY_TV = 45038, // 0x0000AFEE + IDS_VIDEO_GENRE_ANIMATION = 45039, // 0x0000AFEF + IDS_VIDEO_GENRE_FAMILY_FRIENDS = 45040, // 0x0000AFF0 + IDS_VIDEO_GENRE_CREATIONS = 45041, // 0x0000AFF1 + IDS_VIDEO_UNKNOWN_ARTIST = 45042, // 0x0000AFF2 + IDS_VIDEO_DURATION = 45043, // 0x0000AFF3 + IDS_VIDEO_UNKNOWN_EPISODE = 45044, // 0x0000AFF4 + IDS_VIDEO_UNKNOWN_TITLE = 45045, // 0x0000AFF5 + IDS_VIDEO_RATING = 45046, // 0x0000AFF6 + IDS_VIDEO_TITLE_SORT = 45047, // 0x0000AFF7 + IDS_VIDEO_UNKNOWN_DATE = 45048, // 0x0000AFF8 + IDS_VIDEO_EPISODE_CAPTION = 45049, // 0x0000AFF9 + IDS_VIDEO_RENTAL_CAPTION = 45050, // 0x0000AFFA + IDS_DURATION_SHORT = 45051, // 0x0000AFFB + IDS_DURATION_LONG = 45052, // 0x0000AFFC + IDS_VIDEO_EXPIRATION_DAYS = 45053, // 0x0000AFFD + IDS_VIDEO_EXPIRATION_HOURS = 45054, // 0x0000AFFE + IDS_VIDEO_EXPIRED = 45055, // 0x0000AFFF + IDS_CONTENT_TYPE_SORT = 45056, // 0x0000B000 + IDS_VIDEO_PRODUCTION_COMPANY = 45057, // 0x0000B001 + IDS_VIDEO_PC_RENTAL_CAPTION = 45058, // 0x0000B002 + IDS_VIDEO_EXPIRATION_ONEDAY = 45059, // 0x0000B003 + IDS_VIDEO_EXPIRATION_ONEHOUR = 45060, // 0x0000B004 + IDS_VIDEO_EXPIRATION_MINUTES = 45061, // 0x0000B005 + IDS_VIDEO_HEADER = 45062, // 0x0000B006 + IDS_VIDEO_MBR_SHORTCUT_TOOLTIP = 45063, // 0x0000B007 + IDS_VIDEO_DEVICE_RENTAL_CAPTION = 45064, // 0x0000B008 + IDS_VIDEO_DEVICE_RENTAL_FORMAT = 45065, // 0x0000B009 + IDS_VIDEO_SUBTITLE = 45066, // 0x0000B00A + IDS_VIDEO_LANGUAGE = 45067, // 0x0000B00B + IDS_BURN_BUTTON = 46000, // 0x0000B3B0 + IDS_SHARE_BUTTON = 46001, // 0x0000B3B1 + IDS_SYNC_BUTTON = 46002, // 0x0000B3B2 + IDS_PLAYLIST_LAND_NOTIFICATION = 46003, // 0x0000B3B3 + IDS_PLAYLIST_CREATE = 46004, // 0x0000B3B4 + IDS_PLAYLIST_LAND_TITLE = 46005, // 0x0000B3B5 + IDS_NEW_PLAYLIST_NAME = 46006, // 0x0000B3B6 + IDS_DATEMODIFIED_ASCENDING_SORT = 46007, // 0x0000B3B7 + IDS_DATEMODIFIED_DESCENDING_SORT = 46008, // 0x0000B3B8 + IDS_ADDITIONAL_PLAYLISTS = 46009, // 0x0000B3B9 + IDS_PLAYLIST_DIALOG_TITLE = 46010, // 0x0000B3BA + IDS_PLAYLIST_DIALOG_SELECTPLAYLIST = 46011, // 0x0000B3BB + IDS_REMOVE_FROM_PLAYLIST = 46012, // 0x0000B3BC + IDS_PLAYLIST_ADDED_1_ITEM = 46013, // 0x0000B3BD + IDS_PLAYLIST_ADDED_N_ITEMS = 46014, // 0x0000B3BE + IDS_PLAYLIST_DIALOG_CREATEPLAYLIST = 46015, // 0x0000B3BF + IDS_NOW_PLAYING_LAND_TITLE = 46016, // 0x0000B3C0 + IDS_NOW_PLAYING_TOOLTIP = 46017, // 0x0000B3C1 + IDS_FIND_IN_COLLECTION = 46018, // 0x0000B3C2 + IDS_NOW_PLAYING_REMOVE = 46019, // 0x0000B3C3 + IDS_PLAYLIST_CREATEPLAYLIST_DIALOG_TITLE = 46020, // 0x0000B3C4 + IDS_PLAYLIST_NEW_DEFAULT = 46021, // 0x0000B3C5 + IDS_PLAYLIST_DUPLICATE_NAME = 46022, // 0x0000B3C6 + IDS_ADD_TO_BURN_MENUITEM = 46023, // 0x0000B3C7 + IDS_PLAYLIST_INVALID_NAME = 46024, // 0x0000B3C8 + IDS_PLAYLIST_RENAMEPLAYLIST_DIALOG_TITLE = 46025, // 0x0000B3C9 + IDS_FIND_VIDEO_IN_COLLECTION = 46028, // 0x0000B3CC + IDS_NOW_PLAYING_LINK_TO_MARKETPLACE = 46029, // 0x0000B3CD + IDS_NOW_PLAYING_FIND_IN_MARKETPLACE = 46030, // 0x0000B3CE + IDS_PLAYLIST_EMPTY = 46032, // 0x0000B3D0 + IDS_BURNLIST_EMPTY = 46033, // 0x0000B3D1 + IDS_CLEAR_BURN_LIST = 46034, // 0x0000B3D2 + IDS_DEFAULT_PLAYLIST_MENUITEM = 46035, // 0x0000B3D3 + IDS_VIDEO_ZOOM_FULL = 46036, // 0x0000B3D4 + IDS_VIDEO_ZOOM_NONE = 46037, // 0x0000B3D5 + IDS_VIDEO_ZOOM_X = 46038, // 0x0000B3D6 + IDS_NOW_PLAYING_LINK_TO_ZUNEDOTNET = 46039, // 0x0000B3D7 + IDS_NOW_PLAYING_FIND_IN_ZUNEDOTNET = 46040, // 0x0000B3D8 + IDS_AUTOPLAYLIST_DIALOG_TITLE = 46041, // 0x0000B3D9 + IDS_CREATEAUTOPLAYLIST_BUTTON = 46042, // 0x0000B3DA + IDS_AUTOPLAYLIST_NAME_LABEL = 46043, // 0x0000B3DB + IDS_NEW_AUTOPLAYLIST_NAME = 46044, // 0x0000B3DC + IDS_AUTOPLAYLIST_MUSIC_HEADER = 46045, // 0x0000B3DD + IDS_AUTOPLAYLIST_FILTERBY_HEADER = 46046, // 0x0000B3DE + IDS_AUTOPLAYLIST_MUSIC_ALL_OPTION = 46047, // 0x0000B3DF + IDS_AUTOPLAYLIST_MUSIC_LETMECHOOSE_OPTION = 46048, // 0x0000B3E0 + IDS_AUTOPLAYLIST_DONTFILTER_OPTION = 46049, // 0x0000B3E1 + IDS_AUTOPLAYLIST_FILTER_LETMECHOOSE_OPTION = 46050, // 0x0000B3E2 + IDS_AUTOPLAYLIST_ARRANGESONGS_LABEL = 46051, // 0x0000B3E3 + IDS_AUTOPLAYLIST_LIMITTO_LABEL = 46052, // 0x0000B3E4 + IDS_AUTOPLAYLIST_ARTIST_LABEL = 46053, // 0x0000B3E5 + IDS_AUTOPLAYLIST_COMPOSER_LABEL = 46054, // 0x0000B3E6 + IDS_AUTOPLAYLIST_GENRE_LABEL = 46055, // 0x0000B3E7 + IDS_AUTOPLAYLIST_CONTRIBUTINGARTIST_LABEL = 46056, // 0x0000B3E8 + IDS_AUTOPLAYLIST_ALBUM_LABEL = 46057, // 0x0000B3E9 + IDS_AUTOPLAYLIST_RATING_LABEL = 46058, // 0x0000B3EA + IDS_AUTOPLAYLIST_YEAR_LABEL = 46059, // 0x0000B3EB + IDS_AUTOPLAYLIST_YEAR_TO_LABEL = 46060, // 0x0000B3EC + IDS_AUTOPLAYLIST_RECENTLYADDED_LABEL = 46061, // 0x0000B3ED + IDS_AUTOPLAYLIST_RATING_CHOICE_ANY = 46062, // 0x0000B3EE + IDS_AUTOPLAYLIST_RATING_CHOICE_LIKE = 46063, // 0x0000B3EF + IDS_AUTOPLAYLIST_RATING_CHOICE_DONTLIKE = 46064, // 0x0000B3F0 + IDS_AUTOPLAYLIST_RATING_CHOICE_UNRATED = 46065, // 0x0000B3F1 + IDS_AUTOPLAYLIST_SORT_CHOICE_RANDOM = 46066, // 0x0000B3F2 + IDS_AUTOPLAYLIST_SORT_CHOICE_ARTIST = 46067, // 0x0000B3F3 + IDS_AUTOPLAYLIST_SORT_CHOICE_CONTRIBUTINGARTIST = 46068, // 0x0000B3F4 + IDS_AUTOPLAYLIST_SORT_CHOICE_COMPOSER = 46069, // 0x0000B3F5 + IDS_AUTOPLAYLIST_SORT_CHOICE_ALBUM = 46070, // 0x0000B3F6 + IDS_AUTOPLAYLIST_SORT_CHOICE_GENRE = 46071, // 0x0000B3F7 + IDS_AUTOPLAYLIST_SORT_CHOICE_DATEADDED = 46072, // 0x0000B3F8 + IDS_AUTOPLAYLIST_SORT_CHOICE_YEAR = 46073, // 0x0000B3F9 + IDS_AUTOPLAYLIST_SORT_CHOICE_SONG = 46074, // 0x0000B3FA + IDS_AUTOPLAYLIST_RECENTLYADDED_TODAY = 46076, // 0x0000B3FC + IDS_PLAYLIST_TOTALINFO_SONGS_MINUTES = 46077, // 0x0000B3FD + IDS_AUTOPLAYLIST_CREATE = 46078, // 0x0000B3FE + IDS_FIND_ARTIST_FRIENDS_IN_MARKETPLACE_LINK = 46079, // 0x0000B3FF + IDS_FIND_ARTIST_FRIENDS_IN_MARKETPLACE_MENU = 46080, // 0x0000B400 + IDS_PLAYLIST_GROUPHEADER_AUTO = 46081, // 0x0000B401 + IDS_PLAYLIST_GROUPHEADER_SUBSCRIPTION = 46083, // 0x0000B403 + IDS_NOW_PLAYING_SAVEASPLAYLIST = 46084, // 0x0000B404 + IDS_NEW_NOWPLAYING_PLAYLIST_NAME = 46085, // 0x0000B405 + IDS_PLAYLIST_DUPLICATE_NAME_OVERWRITE = 46086, // 0x0000B406 + IDS_PLAYLIST_DIALOG_OVERWRITE = 46087, // 0x0000B407 + IDS_PLAYLIST_SEQUENCE_DIALOG_TITLE = 46088, // 0x0000B408 + IDS_PLAYLIST_SEQUENCE_DIALOG_TEXT = 46089, // 0x0000B409 + IDS_PLAYLIST_REMOVE_DUPLICATES_MENUITEM = 46090, // 0x0000B40A + IDS_AUTOPLAYLIST_LIMIT_NONE = 46091, // 0x0000B40B + IDS_AUTOPLAYLIST_LIMIT_ITEMS = 46092, // 0x0000B40C + IDS_AUTOPLAYLIST_LIMIT_TIME = 46093, // 0x0000B40D + IDS_AUTOPLAYLIST_YEAR_ALL = 46094, // 0x0000B40E + IDS_AUTOPLAYLIST_YEAR_NOW = 46095, // 0x0000B40F + IDS_AUTOPLAYLIST_EMPTY = 46096, // 0x0000B410 + IDS_AUTOPLAYLIST_EDIT_LINK = 46097, // 0x0000B411 + IDS_AUTOPLAYLIST_CREATED = 46098, // 0x0000B412 + IDS_AUTOPLAYLIST_INTRO_TEXT = 46099, // 0x0000B413 + IDS_AUTOPLAYLIST_CRITERION_INCLUDE = 46100, // 0x0000B414 + IDS_AUTOPLAYLIST_CRITERION_EXCLUDE = 46101, // 0x0000B415 + IDS_AUTOPLAYLIST_SORT_CHOICE_MOSTPLAYED = 46102, // 0x0000B416 + IDS_AUTOPLAYLIST_SORT_CHOICE_LEASTPLAYED = 46103, // 0x0000B417 + IDS_AUTOPLAYLIST_SONGPLAYS_LABEL = 46104, // 0x0000B418 + IDS_AUTOPLAYLIST_SONGPLAYS_CHOICE_NONE = 46105, // 0x0000B419 + IDS_AUTOPLAYLIST_SONGPLAYS_CHOICE_NEVERPLAYED = 46106, // 0x0000B41A + IDS_AUTOPLAYLIST_SONGPLAYS_CHOICE_LESSTHAN = 46107, // 0x0000B41B + IDS_AUTOPLAYLIST_SONGPLAYS_CHOICE_MORETHAN = 46108, // 0x0000B41C + IDS_AUTOPLAYLIST_RATING_CHOICE_LIKEORUNRATED = 46109, // 0x0000B41D + IDS_AUTOPLAYLIST_SELECT_LABEL_EXCLUDE = 46110, // 0x0000B41E + IDS_PLAYLIST_EMPTY_NO_MARKETPLACE = 46111, // 0x0000B41F + IDS_BURNLIST_EMPTY_NO_MARKETPLACE = 46112, // 0x0000B420 + IDS_NOW_PLAYING_EMPTY_LINK_TO_MARKETPLACE = 46113, // 0x0000B421 + IDS_NOW_PLAYING_EMPTY_FIND_IN_MARKETPLACE = 46114, // 0x0000B422 + IDS_NOW_PLAYING_EMPTY_LINK_TO_ZUNEDOTNET = 46115, // 0x0000B423 + IDS_NOW_PLAYING_EMPTY_FIND_IN_ZUNEDOTNET = 46116, // 0x0000B424 + IDS_NOW_PLAYING_TRACK_LINK_TO_MARKETPLACE = 46117, // 0x0000B425 + IDS_NOW_PLAYING_TRACK_FIND_IN_MARKETPLACE = 46118, // 0x0000B426 + IDS_NOW_PLAYING_TRACK_LINK_TO_ZUNEDOTNET = 46119, // 0x0000B427 + IDS_NOW_PLAYING_TRACK_FIND_IN_ZUNEDOTNET = 46120, // 0x0000B428 + IDS_PLAYLIST_TOTALINFO_SONG_MINUTES = 46121, // 0x0000B429 + IDS_PLAYLIST_TOTALINFO_SONGS_MINUTE = 46122, // 0x0000B42A + IDS_PLAYLIST_TOTALINFO_SONG_MINUTE = 46123, // 0x0000B42B + IDS_NEW_PLAYLIST_BUTTON = 46124, // 0x0000B42C + IDS_NEW_AUTOPLAYLIST_BUTTON = 46125, // 0x0000B42D + IDS_ARTIST_FIND_IN_MARKETPLACE = 46126, // 0x0000B42E + IDS_VIDEO_FIND_IN_MARKETPLACE = 46127, // 0x0000B42F + IDS_PLAYLIST_REFRESH_MENUITEM = 46128, // 0x0000B430 + IDS_AUTOPLAYLIST_ARTIST_SELECT_LABEL = 46129, // 0x0000B431 + IDS_AUTOPLAYLIST_COMPOSER_SELECT_LABEL = 46130, // 0x0000B432 + IDS_AUTOPLAYLIST_GENRE_SELECT_LABEL = 46131, // 0x0000B433 + IDS_AUTOPLAYLIST_VIDEO_ARTIST_SELECT_LABEL = 46132, // 0x0000B434 + IDS_AUTOPLAYLIST_SERIES_SELECT_LABEL = 46133, // 0x0000B435 + IDS_AUTOPLAYLIST_RECENTLY_ADDED_SELECT_LABEL = 46134, // 0x0000B436 + IDS_QUICKMIXPLAYLIST_CREATE = 46135, // 0x0000B437 + IDS_QUICKMIXPLAYLIST_DIALOG_TEXT = 46136, // 0x0000B438 + IDS_QUICKMIXPLAYLIST_DIALOG_AUTOREFRESH_CHOICE = 46137, // 0x0000B439 + IDS_QUICKMIXPLAYLIST_DIALOG_EDIT_TITLE = 46138, // 0x0000B43A + IDS_QUICKMIXPLAYLIST_PLAYLIST_CONTENTS = 46139, // 0x0000B43B + IDS_QUICKMIXPLAYLIST_LOCAL_CONTENT_ONLY = 46140, // 0x0000B43C + IDS_QUICKMIXPLAYLIST_MIXED_CONTENT = 46141, // 0x0000B43D + IDS_QUICKMIXPLAYLIST_MP_CONTENT_ONLY = 46142, // 0x0000B43E + IDS_QUICKMIXPLAYLIST_CONTENTS_DESCRIPTION = 46143, // 0x0000B43F + IDS_QUICKMIXPLAYLIST_DURATION = 46144, // 0x0000B440 + IDS_QUICKMIXPLAYLIST_REFRESH_RATE = 46147, // 0x0000B443 + IDS_QUICKMIXPLAYLIST_AUTO_REFRESH = 46148, // 0x0000B444 + IDS_QUICKMIXPLAYLIST_DAYS = 46150, // 0x0000B446 + IDS_PLAYLIST_EDIT_PLAYLIST_LABEL = 46151, // 0x0000B447 + IDS_PLAYLIST_REFRESH_LABEL = 46152, // 0x0000B448 + IDS_PLAYLIST_SEND_LABEL = 46153, // 0x0000B449 + IDS_PLAYLIST_TOTAL_SONG = 46154, // 0x0000B44A + IDS_PLAYLIST_TOTAL_SONGS = 46155, // 0x0000B44B + IDS_QUICKMIXPLAYLIST_MIXED_CONTENT_DISABLED = 46156, // 0x0000B44C + IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE = 46157, // 0x0000B44D + IDS_QUICKMIX_CREATION_UNAVAILABLE_TITLE = 46158, // 0x0000B44E + IDS_QUICKMIX_SONG_CREATION_UNAVAILABLE_TEXT = 46159, // 0x0000B44F + IDS_QUICKMIX_ALBUM_CREATION_UNAVAILABLE_TEXT = 46160, // 0x0000B450 + IDS_QUICKMIX_ARTIST_CREATION_UNAVAILABLE_TEXT = 46161, // 0x0000B451 + IDS_QUICKMIX_CREATION_UNAVAILABLE_METADATA_DISABLED_TEXT = 46162, // 0x0000B452 + IDS_QUICKMIX_PROGRESS_HEADER_TEXT = 46163, // 0x0000B453 + IDS_QUICKMIX_PROGRESS_TEXT = 46164, // 0x0000B454 + IDS_QUICKMIX_PROGRESS_BAR_TITLE = 46165, // 0x0000B455 + IDS_QUICKMIX_PROGRESS_BAR_NO_TIME_TITLE = 46166, // 0x0000B456 + IDS_QUICKMIX_WEBHELPLINK_URL = 46167, // 0x0000B457 + IDS_QUICKMIX_NOTIFICATION_BOOTSTRAP_READY_TITLE = 46168, // 0x0000B458 + IDS_QUICKMIX_NOTIFICATION_BOOTSTRAP_READY_TEXT = 46169, // 0x0000B459 + IDS_QUICKMIX_NOTIFICATION_MOREINFO_TEXT = 46170, // 0x0000B45A + IDS_PLAYLIST_AUTOREFRESH_DETAILS = 46171, // 0x0000B45B + IDS_PLAYLIST_AUTOREFRESH_DETAILS_SINGLE = 46172, // 0x0000B45C + IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TITLE = 46173, // 0x0000B45D + IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_ONE_PARAM_TEXT = 46174, // 0x0000B45E + IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TWO_PARAM_TEXT = 46175, // 0x0000B45F + IDS_QUICKMIXPLAYLIST_ZUNEPASS_OFFER = 46179, // 0x0000B463 + IDS_QUICKMIXPLAYLIST_REFRESH_WARNING = 46180, // 0x0000B464 + IDS_QUICKMIX_SUBTYPE_DESCRIPTION_LOCAL = 46181, // 0x0000B465 + IDS_QUICKMIX_SUBTYPE_DESCRIPTION_MIXED = 46182, // 0x0000B466 + IDS_QUICKMIX_SUBTYPE_DESCRIPTION_RADIO = 46183, // 0x0000B467 + IDS_QUICKMIXPLAYLIST_PLAY = 46184, // 0x0000B468 + IDS_QUICKMIX_ITEM_CREATION_UNAVAILABLE_TEXT = 46185, // 0x0000B469 + IDS_PLAYLIST_GROUPHEADER_QUICKMIX = 46186, // 0x0000B46A + IDS_PLAYLIST_CREATION_FAILED_TITLE = 46187, // 0x0000B46B + IDS_EXIT_NOW_PLAYING_TOOLTIP_4_0 = 46188, // 0x0000B46C + IDS_QUICKMIX_SIGNIN_REQUIRED_TITLE = 46189, // 0x0000B46D + IDS_QUICKMIX_SIGNIN_REQUIRED_TEXT = 46190, // 0x0000B46E + IDS_QUICKMIXPLAYLIST_ZUNEPASS_TRIAL_LINK = 46191, // 0x0000B46F + IDS_QUICKMIXPLAYLIST_ZUNEPASS_SUBSCRIPTION_LINK = 46192, // 0x0000B470 + IDS_QUICKMIXPLAYLIST_ZUNEPASS_SIGNIN = 46193, // 0x0000B471 + IDS_QUICKMIX_INTERNET_REQUIRED_TEXT = 46195, // 0x0000B473 + IDS_QUICKMIX_LINK = 46196, // 0x0000B474 + IDS_PLAYLIST_ERROR_TOOLTIP = 46197, // 0x0000B475 + IDS_PLAYLIST_ERROR_DIALOG_TITLE = 46198, // 0x0000B476 + IDS_PLAYLIST_EMPTY_NO_QUICKMIX_MATCHES = 46199, // 0x0000B477 + IDS_QUICKMIX_NOTIFICATION_REFRESH_PLAYLIST = 46200, // 0x0000B478 + IDS_QUICKMIXPLAYLIST_DURATION_SONGS_INFO = 46201, // 0x0000B479 + IDS_QUICKMIXPLAYLIST_DURATION_MINUTES_INFO = 46202, // 0x0000B47A + IDS_NOW_PLAYING_LINK_ONLINE = 46203, // 0x0000B47B + IDS_NOW_PLAYING_EMPTY_LINK_ONLINE = 46204, // 0x0000B47C + IDS_NOW_PLAYING_FIND_ONLINE = 46205, // 0x0000B47D + IDS_NOW_PLAYING_EMPTY_FIND_ONLINE = 46206, // 0x0000B47E + IDS_NOW_PLAYING_TRACK_LINK_ONLINE = 46207, // 0x0000B47F + IDS_NOW_PLAYING_TRACK_FIND_ONLINE = 46208, // 0x0000B480 + IDS_NOW_PLAYING_ZUNEDOTNET_ERROR_TITLE = 46209, // 0x0000B481 + IDS_NOW_PLAYING_ZUNEDOTNET_ERROR = 46210, // 0x0000B482 + IDS_FRAME_MINIMIZE_TOOLTIP = 48000, // 0x0000BB80 + IDS_FRAME_MAXIMIZE_TOOLTIP = 48001, // 0x0000BB81 + IDS_FRAME_RESTORE_TOOLTIP = 48002, // 0x0000BB82 + IDS_FRAME_CLOSE_TOOLTIP = 48003, // 0x0000BB83 + IDS_FRAME_HELP_TOOLTIP = 48004, // 0x0000BB84 + IDS_FRAME_SIZE_TOOLTIP = 48005, // 0x0000BB85 + IDS_FRAME_MOVE_TOOLTIP = 48006, // 0x0000BB86 + IDS_FRAME_COMPACT_MODE_TOOLTIP = 48007, // 0x0000BB87 + IDS_HubGenresHeader = 49001, // 0x0000BF69 + IDS_HubSubGenresHeader = 49002, // 0x0000BF6A + IDS_ShowAllAlbums = 49003, // 0x0000BF6B + IDS_ShowOnlyAvailableAlbums = 49004, // 0x0000BF6C + IDS_ArtistPivotHub = 49005, // 0x0000BF6D + IDS_ArtistPivotBio = 49006, // 0x0000BF6E + IDS_ArtistPivotRelated = 49007, // 0x0000BF6F + IDS_ArtistPivotVideos = 49008, // 0x0000BF70 + IDS_ArtistPivotListeners = 49009, // 0x0000BF71 + IDS_ArtistShowAlbums = 49010, // 0x0000BF72 + IDS_ArtistShowSongs = 49011, // 0x0000BF73 + IDS_ArtistAlbumsByDate = 49012, // 0x0000BF74 + IDS_ArtistAlbumsByPopularity = 49013, // 0x0000BF75 + IDS_ArtistAlbumsByTitle = 49014, // 0x0000BF76 + IDS_ArtistAlbumsByAppearsOn = 49015, // 0x0000BF77 + IDS_ArtistAlbumReviewHeader = 49016, // 0x0000BF78 + IDS_ArtistAlbumReviewLink = 49017, // 0x0000BF79 + IDS_ArtistTrackListLink = 49018, // 0x0000BF7A + IDS_TracksByTrackOrder = 49019, // 0x0000BF7B + IDS_TracksByPopularity = 49020, // 0x0000BF7C + IDS_ArtistAppearsOnTitle = 49021, // 0x0000BF7D + IDS_ArtistAppearsInTitle = 49022, // 0x0000BF7E + IDS_ArtistVideosByDate = 49023, // 0x0000BF7F + IDS_ArtistVideosByPopularity = 49024, // 0x0000BF80 + IDS_ArtistVideosByTitle = 49025, // 0x0000BF81 + IDS_ArtistRelatedSimilarAlbums = 49026, // 0x0000BF82 + IDS_ArtistRelatedInfluencedBy = 49027, // 0x0000BF83 + IDS_ArtistRelatedArtists = 49028, // 0x0000BF84 + IDS_ArtistRelatedGenres = 49029, // 0x0000BF85 + IDS_ArtistPlaylistsHeader = 49030, // 0x0000BF86 + IDS_ArtistListenersFriends = 49031, // 0x0000BF87 + IDS_ArtistListenersTopListeners = 49032, // 0x0000BF88 + IDS_ArtistListenersFriendListeners = 49033, // 0x0000BF89 + IDS_ShowListenersAll = 49034, // 0x0000BF8A + IDS_ShowListenersFavs = 49035, // 0x0000BF8B + IDS_ShowListenersMostPlayedSongs = 49036, // 0x0000BF8C + IDS_ShowListenersMostPlayedArtists = 49037, // 0x0000BF8D + IDS_GenrePivotFeatured = 49038, // 0x0000BF8E + IDS_GenrePivotArtists = 49039, // 0x0000BF8F + IDS_GenrePivotAlbums = 49040, // 0x0000BF90 + IDS_GenrePivotVideos = 49041, // 0x0000BF91 + IDS_GenrePivotPlaylists = 49042, // 0x0000BF92 + IDS_GenreArtistsByPopularity = 49043, // 0x0000BF93 + IDS_GenreAlbumsByPopularity = 49044, // 0x0000BF94 + IDS_GenreAlbumsByDate = 49045, // 0x0000BF95 + IDS_GenreVideosByPopularity = 49046, // 0x0000BF96 + IDS_GenreVideosByDate = 49047, // 0x0000BF97 + IDS_GenreVideosByTitle = 49048, // 0x0000BF98 + IDS_GenrePlaylistsByPopularity = 49049, // 0x0000BF99 + IDS_GenrePlaylistsByDate = 49050, // 0x0000BF9A + IDS_BrowseDateAll = 49051, // 0x0000BF9B + IDS_BrowseDateDecade00 = 49052, // 0x0000BF9C + IDS_BrowseDateDecade90 = 49053, // 0x0000BF9D + IDS_BrowseDateDecade80 = 49054, // 0x0000BF9E + IDS_BrowseDateDecade70 = 49055, // 0x0000BF9F + IDS_BrowseDateDecade60 = 49056, // 0x0000BFA0 + IDS_BrowseDateDecade50 = 49057, // 0x0000BFA1 + IDS_BrowseDateDecade40 = 49058, // 0x0000BFA2 + IDS_BrowseDateEarlier = 49059, // 0x0000BFA3 + IDS_BrowseTitleAll = 49060, // 0x0000BFA4 + IDS_BrowseTitleNumber = 49061, // 0x0000BFA5 + IDS_BrowseTitleAtoI = 49062, // 0x0000BFA6 + IDS_BrowseTitleJtoR = 49063, // 0x0000BFA7 + IDS_BrowseTitleStoZ = 49064, // 0x0000BFA8 + IDS_MusicHubTitle = 49065, // 0x0000BFA9 + IDS_MusicHubPlaylists = 49066, // 0x0000BFAA + IDS_MusicHubCharts = 49067, // 0x0000BFAB + IDS_MusicHubVideos = 49068, // 0x0000BFAC + IDS_MusicHubTopArtists = 49069, // 0x0000BFAD + IDS_MusicHubTopAlbums = 49070, // 0x0000BFAE + IDS_MusicHubTopTracks = 49071, // 0x0000BFAF + IDS_MusicHubTopPlaylists = 49072, // 0x0000BFB0 + IDS_MusicHubTopVideos = 49073, // 0x0000BFB1 + IDS_MusicHubGenres = 49074, // 0x0000BFB2 + IDS_MusicHubBrowse = 49075, // 0x0000BFB3 + IDS_MusicHubNewReleases1 = 49076, // 0x0000BFB4 + IDS_MusicHubNewReleases2 = 49077, // 0x0000BFB5 + IDS_MusicHubFeatures = 49078, // 0x0000BFB6 + IDS_ChartsHubTitle = 49079, // 0x0000BFB7 + IDS_ChartsHubGenres = 49080, // 0x0000BFB8 + IDS_ChartsHubTopArtists = 49081, // 0x0000BFB9 + IDS_ChartsHubTopAlbums = 49082, // 0x0000BFBA + IDS_ChartsHubTopTracks = 49083, // 0x0000BFBB + IDS_ChartsHubTopVideos = 49084, // 0x0000BFBC + IDS_ChartTitleAlbum = 49086, // 0x0000BFBE + IDS_ChartTitleSong = 49087, // 0x0000BFBF + IDS_ChartTitleArtist = 49088, // 0x0000BFC0 + IDS_ChartTitleMusicVideo = 49089, // 0x0000BFC1 + IDS_ChartFilterAlbum = 49091, // 0x0000BFC3 + IDS_ChartFilterSong = 49092, // 0x0000BFC4 + IDS_ChartFilterArtist = 49093, // 0x0000BFC5 + IDS_ChartFilterMusicVideo = 49094, // 0x0000BFC6 + IDS_PlaylistHubTitle = 49095, // 0x0000BFC7 + IDS_PlaylistHubTopList = 49096, // 0x0000BFC8 + IDS_PlaylistHubNewList = 49097, // 0x0000BFC9 + IDS_PlaylistHubGenres = 49098, // 0x0000BFCA + IDS_PlaylistHubCategories = 49099, // 0x0000BFCB + IDS_PlaylistHubExclusives = 49100, // 0x0000BFCC + IDS_MusicVideosHubTitle = 49101, // 0x0000BFCD + IDS_MusicVideosHubGenres = 49102, // 0x0000BFCE + IDS_MusicVideosHubNewReleases = 49103, // 0x0000BFCF + IDS_MusicVideosHubFeatures = 49104, // 0x0000BFD0 + IDS_MusicVideosHubTopList = 49105, // 0x0000BFD1 + IDS_FlexHubExclusives = 49106, // 0x0000BFD2 + IDS_FlexHubAlbums = 49107, // 0x0000BFD3 + IDS_FlexHubVideos = 49108, // 0x0000BFD4 + IDS_FlexHubPodcasts = 49110, // 0x0000BFD6 + IDS_PodcastHubTitle = 49111, // 0x0000BFD7 + IDS_PodcastHubTopList = 49112, // 0x0000BFD8 + IDS_PodcastHubNewList = 49113, // 0x0000BFD9 + IDS_PodcastHub101 = 49114, // 0x0000BFDA + IDS_PodcastHubBecomeAPodcaster = 49115, // 0x0000BFDB + IDS_PodcastHubSubmit = 49116, // 0x0000BFDC + IDS_PodcastHubCategories = 49117, // 0x0000BFDD + IDS_PodcastHubHotList = 49118, // 0x0000BFDE + IDS_PodcastHubAudioList = 49119, // 0x0000BFDF + IDS_PodcastHubVideoList = 49120, // 0x0000BFE0 + IDS_PodcastListSubcategory = 49121, // 0x0000BFE1 + IDS_PodcastListFilterAll = 49122, // 0x0000BFE2 + IDS_PodcastListFilterVideo = 49123, // 0x0000BFE3 + IDS_PodcastListFilterAudio = 49124, // 0x0000BFE4 + IDS_PodcastListTopTitle = 49125, // 0x0000BFE5 + IDS_PodcastListNewTitle = 49126, // 0x0000BFE6 + IDS_PodcastHeaderTitle = 49127, // 0x0000BFE7 + IDS_PodcastHeaderAuthor = 49128, // 0x0000BFE8 + IDS_PodcastHeaderDate = 49129, // 0x0000BFE9 + IDS_PodcastHeaderCategory = 49130, // 0x0000BFEA + IDS_PodcastsByPopularity = 49131, // 0x0000BFEB + IDS_PodcastsByDate = 49132, // 0x0000BFEC + IDS_PodcastsByTitle = 49133, // 0x0000BFED + IDS_PodcastValidationProblemHeader = 49134, // 0x0000BFEE + IDS_PodcastValidationBadUrl = 49135, // 0x0000BFEF + IDS_PodcastValidationCantDownload = 49136, // 0x0000BFF0 + IDS_PodcastValidationNoFeed = 49137, // 0x0000BFF1 + IDS_PodcastSubmissionSuccessHeader = 49138, // 0x0000BFF2 + IDS_PodcastSubmissionSuccess = 49139, // 0x0000BFF3 + IDS_VideoHubTitle = 49140, // 0x0000BFF4 + IDS_VideoHubBrowse = 49141, // 0x0000BFF5 + IDS_VideoHubNewReleases = 49142, // 0x0000BFF6 + IDS_VideoHubTopEpisodes = 49143, // 0x0000BFF7 + IDS_VideoHubTopSeries = 49144, // 0x0000BFF8 + IDS_VideoHubTopShorts = 49145, // 0x0000BFF9 + IDS_VideoHubShortsCategory = 49146, // 0x0000BFFA + IDS_VideoHubMusicVideos = 49147, // 0x0000BFFB + IDS_VideoHubCategories = 49148, // 0x0000BFFC + IDS_VideoHubNetworks = 49149, // 0x0000BFFD + IDS_VideoHubFeatures = 49150, // 0x0000BFFE + IDS_VideoListTitle = 49151, // 0x0000BFFF + IDS_VideoListTopShows = 49152, // 0x0000C000 + IDS_VideoListTopSeasons = 49153, // 0x0000C001 + IDS_VideoListTopShorts = 49154, // 0x0000C002 + IDS_VideosByPopularity = 49155, // 0x0000C003 + IDS_VideosByDate = 49156, // 0x0000C004 + IDS_VideosByTitle = 49157, // 0x0000C005 + IDS_VideoChartTitleSeries = 49158, // 0x0000C006 + IDS_VideoChartTitleEpisodes = 49159, // 0x0000C007 + IDS_VideoChartPivotSeries = 49160, // 0x0000C008 + IDS_VideoChartPivotEpisodes = 49161, // 0x0000C009 + IDS_VideoPreviewButton = 49162, // 0x0000C00A + IDS_VideoPlayButton = 49163, // 0x0000C00B + IDS_VideoStopPreview = 49164, // 0x0000C00C + IDS_VideoPreviewErrorHeading = 49165, // 0x0000C00D + IDS_VideoPreviewMustLogin = 49166, // 0x0000C00E + IDS_VideoPreviewNeedAdult = 49167, // 0x0000C00F + IDS_VideoShortBrowseTitle = 49168, // 0x0000C010 + IDS_SeriesSeason = 49169, // 0x0000C011 + IDS_SeriesSeasonDateFormat = 49170, // 0x0000C012 + IDS_SeriesNoSeason = 49171, // 0x0000C013 + IDS_SeriesOneSeason = 49172, // 0x0000C014 + IDS_SeriesManySeasons = 49173, // 0x0000C015 + IDS_SeasonTitle = 49174, // 0x0000C016 + IDS_SeasonDescriptionHeader = 49175, // 0x0000C017 + IDS_SeasonDescriptionLink = 49176, // 0x0000C018 + IDS_SeasonEpisodesLink = 49177, // 0x0000C019 + IDS_SeriesRating = 49178, // 0x0000C01A + IDS_VideoShortDateFormat = 49179, // 0x0000C01B + IDS_VideoShortDurationFormat = 49180, // 0x0000C01C + IDS_ChannelHubTitle = 49181, // 0x0000C01D + IDS_ChannelHubCategories = 49182, // 0x0000C01E + IDS_ChannelHubGenres = 49183, // 0x0000C01F + IDS_ChannelHubJustForYou = 49184, // 0x0000C020 + IDS_ChannelHubDescriptionTitle = 49185, // 0x0000C021 + IDS_ChannelHubShortDescription = 49186, // 0x0000C022 + IDS_ChannelHubDescriptionMore = 49187, // 0x0000C023 + IDS_ChannelDescriptionTitle = 49188, // 0x0000C024 + IDS_ChannelDescription = 49189, // 0x0000C025 + IDS_MusicHubChannels = 49190, // 0x0000C026 + IDS_ChannelsByTitle = 49191, // 0x0000C027 + IDS_ChannelsByLastUpdated = 49192, // 0x0000C028 + IDS_RecommendationsSigninHeader = 49193, // 0x0000C029 + IDS_RecommendationsTitle = 49194, // 0x0000C02A + IDS_RecommendationsTopTracks = 49195, // 0x0000C02B + IDS_RecommendationsChannels = 49196, // 0x0000C02C + IDS_RecommendationsListeners = 49197, // 0x0000C02D + IDS_PersonalChannelsTopLabel = 49198, // 0x0000C02E + IDS_SongsForYouDescription = 49199, // 0x0000C02F + IDS_RecommendationsEmpty = 49200, // 0x0000C030 + IDS_NoMoreRecommendations = 49202, // 0x0000C032 + IDS_RecommendationsArtist_Play = 49203, // 0x0000C033 + IDS_RecommendationsArtist_Plays = 49204, // 0x0000C034 + IDS_RecommendationsError = 49205, // 0x0000C035 + IDS_ChannelHubJustForYouCategory = 49206, // 0x0000C036 + IDS_BrowseMarketplace = 49207, // 0x0000C037 + IDS_ChannelHubJustForUser = 49208, // 0x0000C038 + IDS_PodcastSubmissionTitle = 49209, // 0x0000C039 + IDS_PodcastSubmissionIntro1 = 49210, // 0x0000C03A + IDS_PodcastSubmissionIntro2 = 49211, // 0x0000C03B + IDS_PodcastSubmissionUrl = 49212, // 0x0000C03C + IDS_PodcastConcernTitle = 49213, // 0x0000C03D + IDS_PodcastConcernEmailLabel = 49214, // 0x0000C03E + IDS_PodcastConcernEmailContent = 49215, // 0x0000C03F + IDS_PodcastConcernCopyright = 49216, // 0x0000C040 + IDS_PodcastConcernConcernLabel = 49217, // 0x0000C041 + IDS_PodcastConcernConcern1 = 49218, // 0x0000C042 + IDS_PodcastConcernConcern2 = 49219, // 0x0000C043 + IDS_PodcastConcernConcern3 = 49220, // 0x0000C044 + IDS_PodcastConcernConcern4 = 49221, // 0x0000C045 + IDS_PodcastConcernConcern5 = 49222, // 0x0000C046 + IDS_PodcastConcernConcern6 = 49223, // 0x0000C047 + IDS_PodcastConcernInvalidEmail = 49224, // 0x0000C048 + IDS_RecommendationsArtist_Plays_None = 49225, // 0x0000C049 + IDS_VideoFormatDescriptionHD = 49226, // 0x0000C04A + IDS_VideoFormatDescriptionSD = 49227, // 0x0000C04B + IDS_VideoFormatChoiceHDSD = 49228, // 0x0000C04C + IDS_PicksPlayTooltip = 49229, // 0x0000C04D + IDS_PicksNotInterestedTooltip = 49230, // 0x0000C04E + IDS_PicksLearnMoreTooltip = 49231, // 0x0000C04F + IDS_PicksArtistHeading = 49233, // 0x0000C051 + IDS_PicksRunDryHeading = 49237, // 0x0000C055 + IDS_PicksRunDry = 49238, // 0x0000C056 + IDS_GenreBrowseSubGenreHeading = 49240, // 0x0000C058 + IDS_ExplicitErrorHeading = 49241, // 0x0000C059 + IDS_ExplicitMustLogin = 49242, // 0x0000C05A + IDS_ExplicitNeedAdult = 49243, // 0x0000C05B + IDS_VideoFormatHD = 49250, // 0x0000C062 + IDS_VideoFormatSD = 49251, // 0x0000C063 + IDS_VideoHubTopRentals = 49253, // 0x0000C065 + IDS_ArtistChooserTitle = 49257, // 0x0000C069 + IDS_ArtistChooserDescription = 49258, // 0x0000C06A + IDS_ArtistChooserSkip = 49259, // 0x0000C06B + IDS_ArtistChooserDone = 49260, // 0x0000C06C + IDS_ArtistChooserPicksFailed = 49266, // 0x0000C072 + IDS_VideoHubNewMovies = 49267, // 0x0000C073 + IDS_VideoHubNewEpisodes = 49268, // 0x0000C074 + IDS_VideoHubExclusives = 49269, // 0x0000C075 + IDS_VideoHubBrowseAll = 49270, // 0x0000C076 + IDS_VideoHubBrowseMovies = 49271, // 0x0000C077 + IDS_MovieHubRating = 49272, // 0x0000C078 + IDS_MovieHubBrowseAll = 49273, // 0x0000C079 + IDS_MoviesByTitle = 49274, // 0x0000C07A + IDS_MoviesByRating = 49275, // 0x0000C07B + IDS_MoviesBySales = 49276, // 0x0000C07C + IDS_MoviesByRentals = 49277, // 0x0000C07D + IDS_VideoHubBrowseTV = 49278, // 0x0000C07E + IDS_MovieListFilterAll = 49279, // 0x0000C07F + IDS_MovieListFilterRental = 49280, // 0x0000C080 + IDS_MovieListFilterPurchase = 49281, // 0x0000C081 + IDS_MovieHubSeparator = 49283, // 0x0000C083 + IDS_MovieHubDetailsActors = 49284, // 0x0000C084 + IDS_MovieHubDetailsDirectors = 49285, // 0x0000C085 + IDS_MovieHubCategories = 49286, // 0x0000C086 + IDS_VideoHubTopMovies = 49287, // 0x0000C087 + IDS_ChartFilterRentals = 49288, // 0x0000C088 + IDS_ChartFilterPurchases = 49289, // 0x0000C089 + IDS_VideoHubBrowseMovieTrailers = 49291, // 0x0000C08B + IDS_ArtistChooserUploadFailedDialogTitle = 49292, // 0x0000C08C + IDS_ZuneRadioLink = 49293, // 0x0000C08D + IDS_ZuneRadioUpsell = 49294, // 0x0000C08E + IDS_ZuneRadioTrialLink = 49295, // 0x0000C08F + IDS_ArtistChooserPicksTitle = 49296, // 0x0000C090 + IDS_ArtistChooserPicksDescription = 49297, // 0x0000C091 + IDS_AppsHubTitle = 49298, // 0x0000C092 + IDS_AppsHubExclusives = 49300, // 0x0000C094 + IDS_AppsByDate = 49301, // 0x0000C095 + IDS_AppsByTitle = 49302, // 0x0000C096 + IDS_AppsVersionFormat = 49303, // 0x0000C097 + IDS_AppsScreenshots = 49305, // 0x0000C099 + IDS_AppsZuneHDOnlyTitle = 49306, // 0x0000C09A + IDS_AppsZuneHDOnlyDescription = 49307, // 0x0000C09B + IDS_AppsZuneHDLearnMore = 49308, // 0x0000C09C + IDS_AppsZuneHDLearnMoreUrl = 49309, // 0x0000C09D + IDS_AppsHubGameGenres = 49310, // 0x0000C09E + IDS_AppsHubAppGenres = 49311, // 0x0000C09F + IDS_PicksRateMoreTitle = 49313, // 0x0000C0A1 + IDS_PicksRateMore = 49314, // 0x0000C0A2 + IDS_ArtistChooserPicksPrepopulated = 49315, // 0x0000C0A3 + IDS_ArtistChooserQuickplayPrepopulated = 49316, // 0x0000C0A4 + IDS_PicksFindingRecommendations = 49317, // 0x0000C0A5 + IDS_ArtistChooserSearchBoxHint = 49318, // 0x0000C0A6 + IDS_VideoStreamingMustLogin = 49320, // 0x0000C0A8 + IDS_MovieHubNotRated = 49321, // 0x0000C0A9 + IDS_ArtistChooserBadArtist = 49322, // 0x0000C0AA + IDS_ArtistChooserNoService = 49323, // 0x0000C0AB + IDS_ArtistChooserSelectedHeading = 49324, // 0x0000C0AC + IDS_VideoHubBrowseAllMovieTrailers = 49325, // 0x0000C0AD + IDS_MoviesByReleaseDate = 49326, // 0x0000C0AE + IDS_AppsDetailsSeperator = 49327, // 0x0000C0AF + IDS_AppsDetailsGenreList = 49328, // 0x0000C0B0 + IDS_ArtistChooserBadArtistQP = 49329, // 0x0000C0B1 + IDS_ZuneRadioPurchaseLink = 49330, // 0x0000C0B2 + IDS_ArtistChooserRemoveTooltip = 49331, // 0x0000C0B3 + IDS_VideoPlayTrailerButton = 49332, // 0x0000C0B4 + IDS_VideoPurchaseEpisodeTitle = 49333, // 0x0000C0B5 + IDS_ArtistPivotTracks = 49334, // 0x0000C0B6 + IDS_ArtistVideoAlbumOnly = 49335, // 0x0000C0B7 + IDS_AppsForWindowsPhoneHubTitle = 49336, // 0x0000C0B8 + IDS_AppsWindowsPhoneOnlyTitle = 49337, // 0x0000C0B9 + IDS_AppsWindowsPhoneOnlyDescription = 49338, // 0x0000C0BA + IDS_AppsWindowsPhoneLearnMore = 49339, // 0x0000C0BB + IDS_AppsWindowsPhoneLearnMoreUrl = 49340, // 0x0000C0BC + IDS_AppsDeviceListLabel = 49341, // 0x0000C0BD + IDS_AppsZuneHDDeviceName = 49342, // 0x0000C0BE + IDS_AppsWindowsPhoneDeviceName = 49343, // 0x0000C0BF + IDS_AppsTopAppsListLabel = 49344, // 0x0000C0C0 + IDS_AppsTopFreeAppsListLabel = 49345, // 0x0000C0C1 + IDS_AppsHubNew = 49346, // 0x0000C0C2 + IDS_AppsDetailsPivot = 49347, // 0x0000C0C3 + IDS_AppsReviewsPivot = 49348, // 0x0000C0C4 + IDS_AppsWriteReview = 49350, // 0x0000C0C6 + IDS_AppsAverageRatingLabel = 49351, // 0x0000C0C7 + IDS_AppsByPopularity = 49352, // 0x0000C0C8 + IDS_AppsBrowsePivotAll = 49353, // 0x0000C0C9 + IDS_AppsBrowsePivotPaid = 49354, // 0x0000C0CA + IDS_AppsBrowsePivotFree = 49355, // 0x0000C0CB + IDS_AppsBrowsePivotXboxLive = 49356, // 0x0000C0CC + IDS_AppsGenreLabel = 49357, // 0x0000C0CD + IDS_AppsSubGenreLabel = 49358, // 0x0000C0CE + IDS_AppsNoContentLabel = 49359, // 0x0000C0CF + IDS_AppsDeveloperHeader = 49360, // 0x0000C0D0 + IDS_AppsVersionHeader = 49361, // 0x0000C0D1 + IDS_AppsTopForWindowsPhoneTitle = 49362, // 0x0000C0D2 + IDS_AppsSendingReview = 49363, // 0x0000C0D3 + IDS_AppsReviewRate = 49365, // 0x0000C0D5 + IDS_AppsReviewTitle = 49366, // 0x0000C0D6 + IDS_AppsReviewDialogTitle = 49367, // 0x0000C0D7 + IDS_AppsReviewDialogLoading = 49368, // 0x0000C0D8 + IDS_AppsNoRatingSelected = 49369, // 0x0000C0D9 + IDS_AppsCapabilityItem = 49370, // 0x0000C0DA + IDS_AppsCapabilitiesPassiveText = 49371, // 0x0000C0DB + IDS_AppsCapabilitiesDialogText = 49372, // 0x0000C0DC + IDS_AppsCapabilitiesDialogTitle = 49373, // 0x0000C0DD + IDS_BrowseDateDecade10 = 49374, // 0x0000C0DE + IDS_AppsConnectAppDeviceToBuy = 49375, // 0x0000C0DF + IDS_SeasonInProgress = 49377, // 0x0000C0E1 + IDS_AppsConfirmDisconnected = 49378, // 0x0000C0E2 + IDS_AppsPhonePurchaseNoIdTitle = 49379, // 0x0000C0E3 + IDS_AppsPhonePurchaseNoId = 49380, // 0x0000C0E4 + IDS_ChartTitleMovieRentals = 49381, // 0x0000C0E5 + IDS_MovieHubStudios = 49382, // 0x0000C0E6 + IDS_SeasonBestValueText = 49383, // 0x0000C0E7 + IDS_ChartTitleMoviePurchases = 49384, // 0x0000C0E8 + IDS_AppsCollectionBannerTitle = 49385, // 0x0000C0E9 + IDS_AppsCollectionBannerDescription = 49386, // 0x0000C0EA + IDS_AppsConfirmText2 = 49387, // 0x0000C0EB + IDS_AppsConfirmText3 = 49388, // 0x0000C0EC + IDS_AppsConfirmText4 = 49389, // 0x0000C0ED + IDS_AppsReviewFinishedTitle = 49390, // 0x0000C0EE + IDS_AppsReviewFinished = 49391, // 0x0000C0EF + IDS_AppsConfirmConnected = 49392, // 0x0000C0F0 + IDS_AppsRatingInfoUrl = 49393, // 0x0000C0F1 + IDS_MIX_REASONTOPLISTENER = 50000, // 0x0000C350 + IDS_MIX_REASONFRIENDOFTAG = 50001, // 0x0000C351 + IDS_MIX_REASONFAVORITEALBUMOFTAG = 50002, // 0x0000C352 + IDS_MIX_REASONRECENTALBUMOFTAG = 50003, // 0x0000C353 + IDS_MIX_REASONTOPARTISTOFTAG = 50004, // 0x0000C354 + IDS_MIX_REASONARTISTRELATEDALBUM = 50005, // 0x0000C355 + IDS_MIX_REASONNEWALBUMOFARTIST = 50006, // 0x0000C356 + IDS_MIX_REASONARTISTRELATEDARTIST = 50007, // 0x0000C357 + IDS_MIX_REASONINFLUENCEROFARTIST = 50008, // 0x0000C358 + IDS_MIX_REASONFOLLOWEROFARTIST = 50009, // 0x0000C359 + IDS_MIX_REASONSHAREDFRIENDOFARTIST = 50010, // 0x0000C35A + IDS_MIX_LINK = 50011, // 0x0000C35B + IDS_MIX_ACTION_PLAY = 50012, // 0x0000C35C + IDS_MIX_ACTION_ADDTONOWPLAYING = 50014, // 0x0000C35E + IDS_MIX_REASONALBUMRELATEDALBUM = 50015, // 0x0000C35F + IDS_MIX_ACTION_LEARNMORE = 50016, // 0x0000C360 + IDS_MIX_ACTION_VIEWPROFILE = 50017, // 0x0000C361 + IDS_MIX_ACTION_ADDTOCART = 50018, // 0x0000C362 + IDS_MIX_ACTION_DOWNLOAD = 50019, // 0x0000C363 + IDS_MIX_ACTION_INCOLLECTION = 50020, // 0x0000C364 + IDS_MIX_REASONRECENTARTISTOFTAG = 50021, // 0x0000C365 + IDS_MIX_REASONFAVORITEARTISTOFTAG = 50022, // 0x0000C366 + IDS_MIX_MENUITEM = 50024, // 0x0000C368 + IDS_QP_NEW_LABEL = 51000, // 0x0000C738 + IDS_QP_FAVORITES_LABEL = 51001, // 0x0000C739 + IDS_QP_THUMBADDED = 51002, // 0x0000C73A + IDS_QP_THUMBPRIMARYSECONDARYLABEL = 51003, // 0x0000C73B + IDS_QP_HISTORY_LABEL = 51005, // 0x0000C73D + IDS_QP_ACCESSIBILITYFORMATTING = 51006, // 0x0000C73E + IDS_QP_CHANGESTARTUPPAGE_TITLE = 51007, // 0x0000C73F + IDS_QP_WELCOME_LABEL = 51009, // 0x0000C741 + IDS_QP_NOPINS_LABEL = 51010, // 0x0000C742 + IDS_QP_NONEW_LABEL = 51011, // 0x0000C743 + IDS_QP_NOHISTORY_LABEL = 51012, // 0x0000C744 + IDS_QP_WELCOME_COLLECTION_LABEL = 51013, // 0x0000C745 + IDS_QP_WELCOME_MARKETPLACE_LABEL = 51014, // 0x0000C746 + IDS_QP_WELCOME_SOCIALPASS_LABEL = 51015, // 0x0000C747 + IDS_QP_WELCOME_SOCIALNOPASS_LABEL = 51016, // 0x0000C748 + IDS_QP_WELCOME_SOCIALNOTSIGNEDIN_LABEL = 51017, // 0x0000C749 + IDS_QP_WELCOME_HEADER_LABEL = 51018, // 0x0000C74A + IDS_QP_WELCOME_HEADER_NOMARKETPLACE_LABEL = 51019, // 0x0000C74B + IDS_QP_THUMBPRIMARYLABEL = 51022, // 0x0000C74E + IDS_QP_THUMBPRIMARYMESSAGELABEL = 51023, // 0x0000C74F + IDS_QP_THUMBPRIMARYSECONDARYMESSAGELABEL = 51024, // 0x0000C750 + IDS_QP_WELCOME_FREETRIAL_LABEL = 51025, // 0x0000C751 + IDS_QP_CHANGESTARTUPPAGE_COLLECTION = 51026, // 0x0000C752 + IDS_QP_CHANGESTARTUPPAGE_MARKETPLACE = 51027, // 0x0000C753 + IDS_QP_CHANGESTARTUPPAGE_SOCIAL = 51028, // 0x0000C754 + IDS_QP_QUICKMIX_CREATE_LABEL = 51029, // 0x0000C755 + IDS_QP_QUICKMIX_CREATE_SUBLABEL = 51030, // 0x0000C756 + IDS_QP_QUICKMIX_ARTIST_SUBLABEL = 51031, // 0x0000C757 + IDS_QP_QUICKMIX_YOU_CHOOSE_SUBLABEL = 51033, // 0x0000C759 + IDS_QP_QUICKMIX_CHANGEARTIST_TOOLTIP = 51036, // 0x0000C75C + IDS_QP_QUICKMIX_DONE_TOOLTIP = 51037, // 0x0000C75D + IDS_QP_QUICKMIX_YOU_CHOOSE_NO_PASS_SUBLABEL = 51038, // 0x0000C75E + IDS_QP_NOTHING_TO_PLAY = 51039, // 0x0000C75F + IDS_QP_NO_SONGS_FROM_ARTIST = 51040, // 0x0000C760 + IDS_QP_WELCOME_MARKETPLACE_VIDEO_LABEL = 51041, // 0x0000C761 + IDS_QP_WELCOME_MARKETPLACE_MUSIC_LABEL = 51042, // 0x0000C762 + IDS_QP_WELCOME_HEADER_MARKETPLACE_LABEL = 51043, // 0x0000C763 + IDS_QP_WELCOME_SUBSCRIPTION_LABEL = 51044, // 0x0000C764 + IDS_MINIMODE_TASKBAR_TOOLBAR = 51300, // 0x0000C864 + IDS_MINIMODE_TASKBAR_RESTORE = 51301, // 0x0000C865 + IDS_MINIMODE_TASKBAR_RESTORE_HT = 51302, // 0x0000C866 + IDS_MINIMODE_TASKBAR_RESTORE_TT = 51303, // 0x0000C867 + IDS_MINIMODE_TASKBAR_BACK_TT = 51304, // 0x0000C868 + IDS_MINIMODE_TASKBAR_PLAY_TT = 51305, // 0x0000C869 + IDS_MINIMODE_TASKBAR_PAUSE_TT = 51306, // 0x0000C86A + IDS_MINIMODE_TASKBAR_FORWARD_TT = 51307, // 0x0000C86B + IDS_MINIMODE_TASKBAR_MUTE_OFF_TT = 51308, // 0x0000C86C + IDS_MINIMODE_TASKBAR_MUTE_ON_TT = 51309, // 0x0000C86D + IDS_MINIMODE_VIDEO_SEEK_FORMAT = 51310, // 0x0000C86E + IDS_TASKBAR_SETTINGS_TITLE = 51311, // 0x0000C86F + IDS_TASKBAR_SETTINGS_DESC = 51312, // 0x0000C870 + IDS_TASKBAR_ENABLE_ON_VISTA = 51313, // 0x0000C871 + IDS_TASKBAR_DISABLE_ON_VISTA = 51314, // 0x0000C872 + IDS_TASKBAR_SETUP_ON_XP = 51315, // 0x0000C873 + IDS_TASKBAR_SETUP_ON_XP_TITLE = 51316, // 0x0000C874 + IDS_TASKBAR_SETUP_ON_XP_DESC = 51317, // 0x0000C875 + IDS_TASKBAR_SETUP_ON_XP_HOWTO_LABEL = 51318, // 0x0000C876 + IDS_TASKBAR_SETUP_ON_XP_HOWTO_DESC = 51319, // 0x0000C877 + IDS_TASKBAR_SETUP_ON_VISTA_TITLE = 51320, // 0x0000C878 + IDS_TASKBAR_SETUP_ON_VISTA_DESC = 51321, // 0x0000C879 + IDS_COMPACT_MODE_SETTINGS_TITLE = 51322, // 0x0000C87A + IDS_COMPACT_MODE_ALWAYS_ON_TOP = 51323, // 0x0000C87B + IDS_MINIMODE_JUMPLIST_PIVOT_PLAYLIKE = 51330, // 0x0000C882 + IDS_MINIMODE_JUMPLIST_PIVOT_PINS = 51331, // 0x0000C883 + IDS_MINIMODE_PLAYBACK_ERROR_TOOLTIP = 51333, // 0x0000C885 + IDS_MINIMODE_JUMPLIST_NO_PLAYLIKE = 51334, // 0x0000C886 + IDS_MINIMODE_JUMPLIST_NO_PINS = 51335, // 0x0000C887 + IDS_MINIMODE_JUMPLIST_PICKING_MUSIC = 51336, // 0x0000C888 + IDS_MINIMODE_JUMPLIST_RESUME = 51337, // 0x0000C889 + IDS_MINIMODE_JUMPLIST_PLAYLAST = 51338, // 0x0000C88A + IDS_MINIMODE_JUMPLIST_PLAYALL = 51339, // 0x0000C88B + IDS_DEVICE_RESTORE_HEADER = 52000, // 0x0000CB20 + IDS_DEVICE_RESTORE_DESCRIPTION = 52001, // 0x0000CB21 + IDS_DEVICE_RESTORE_BUTTON = 52002, // 0x0000CB22 + IDS_DEVICE_RESTORE_POINT_CREATION_DATE = 52003, // 0x0000CB23 + IDS_DEVICE_RESTORE_YOUR_PHONE = 52004, // 0x0000CB24 + IDS_DEVICE_RESTORE_WARNING = 52005, // 0x0000CB25 + IDS_DEVICE_RESTORE_I_HAVE_READ = 52006, // 0x0000CB26 + IDS_DEVICE_RESTORE_NO_CALLS = 52007, // 0x0000CB27 + IDS_DEVICE_RESTORE_DONT_DISCONNECT = 52008, // 0x0000CB28 + IDS_DEVICE_RESTORE_MAY_DISCONNECT = 52009, // 0x0000CB29 + IDS_DEVICE_RESTORE_IN_PROGRESS = 52010, // 0x0000CB2A + IDS_DEVICE_RESTORE_PROGRESS_DESCRIPTION = 52011, // 0x0000CB2B + IDS_DEVICE_RESTORE_STEPS_COMPLETE = 52012, // 0x0000CB2C + IDS_DEVICE_RESTORE_SUCCESS = 52013, // 0x0000CB2D + IDS_DEVICE_RESTORE_SUCCESS_DESCRIPTION = 52014, // 0x0000CB2E + IDS_DEVICE_RESTORE_ERROR_TITLE = 52015, // 0x0000CB2F + IDS_DEVICE_RESTORE_ERROR_FRIENDLY = 52016, // 0x0000CB30 + IDS_DEVICE_RESTORE_ERROR_NOTICE1 = 52017, // 0x0000CB31 + IDS_DEVICE_RESTORE_ERROR_NOTICE2 = 52018, // 0x0000CB32 + IDS_DEVICE_ROLLBACK_IN_PROGRESS = 52019, // 0x0000CB33 + IDS_DEVICE_ROLLBACK_PROGRESS_DESCRIPTION = 52020, // 0x0000CB34 + IDS_DEVICE_ROLLBACK_NOTICE = 52021, // 0x0000CB35 + IDS_DEVICE_ROLLBACK_ERROR_TITLE = 52022, // 0x0000CB36 + IDS_DEVICE_ROLLBACK_COMPLETE_TITLE = 52023, // 0x0000CB37 + IDS_DEVICE_ROLLBACK_COMPLETE_DESCRIPTION = 52024, // 0x0000CB38 + IDS_DEVICE_ROLLBACK_COMPLETE_NOTICE1 = 52025, // 0x0000CB39 + IDS_DEVICE_ROLLBACK_COMPLETE_NOTICE2 = 52026, // 0x0000CB3A + IDS_WIRELESS_MOBILE_WIZARD_CONFIRM_TITLE = 52027, // 0x0000CB3B + IDS_WIRELESS_MOBILE_WIZARD_REFRESH = 52028, // 0x0000CB3C + IDS_WIRELESS_MOBILE_WIZARD_TROUBLESHOOT = 52029, // 0x0000CB3D + IDS_WIRELESS_MOBILE_WIZARD_SSID_FORMAT = 52030, // 0x0000CB3E + IDS_WIRELESS_MOBILE_WIZARD_NO_SSID = 52031, // 0x0000CB3F + IDS_WIRELESS_MOBILE_WIZARD_CURRENT_NETWORK = 52032, // 0x0000CB40 + IDS_WIRELESS_MOBILE_WIZARD_INSTRUCTIONS = 52033, // 0x0000CB41 + IDS_WIRELESS_MOBILE_WIZARD_SSID_CHANGED = 52034, // 0x0000CB42 + IDS_WIRELESS_MOBILE_WIZARD_NO_NETWORK = 52035, // 0x0000CB43 + IDS_WIRELESS_MOBILE_WIZARD_SUCCESS = 52036, // 0x0000CB44 + IDS_WIRELESS_MOBILE_WIZARD_TRY_AGAIN = 52037, // 0x0000CB45 + IDS_WIRELESS_MOBILE_WIZARD_DONE = 52038, // 0x0000CB46 + IDS_BREADCRUMB_INTRODUCTION = 52039, // 0x0000CB47 + IDS_BREADCRUMB_SOFTWARE_SETTINGS = 52040, // 0x0000CB48 + IDS_BREADCRUMB_PHONE_NAME = 52041, // 0x0000CB49 + IDS_PHONELAND_FIRSTRUN_YOUR_COLLECTION = 52042, // 0x0000CB4A + IDS_PHONELAND_FIRSTRUN_MY_PHONE = 52046, // 0x0000CB4E + IDS_PHONELAND_FIRSTRUN_URL = 52047, // 0x0000CB4F + IDS_WIRELESS_MOBILE_SETUP_NO_DEVICE = 52049, // 0x0000CB51 + IDS_WIRELESS_MOBILE_SETUP_NO_PC_NETWORK = 52050, // 0x0000CB52 + IDS_WIRELESS_MOBILE_SETUP_NO_PHONE_WIFI = 52051, // 0x0000CB53 + IDS_WIRELESS_MOBILE_SETUP_REFRESH = 52052, // 0x0000CB54 + IDS_WIRELESS_MOBILE_SETUP_DISABLE_SYNC = 52053, // 0x0000CB55 + IDS_WIRELESS_MOBILE_SETUP_EXISTING_SYNC = 52054, // 0x0000CB56 + IDS_WIRELESS_MOBILE_SETUP_TITLE = 52055, // 0x0000CB57 + IDS_WIRELESS_MOBILE_SETUP_CURRENT_SSID = 52056, // 0x0000CB58 + IDS_WIRELESS_MOBILE_SETUP_NO_SSID = 52057, // 0x0000CB59 + IDS_WIRELESS_MOBILE_PITCH_INSTRUCTIONS = 52058, // 0x0000CB5A + IDS_WIRELESS_MOBILE_WARNING = 52059, // 0x0000CB5B + IDS_PHONE_WELCOME_TITLE = 52060, // 0x0000CB5C + IDS_PHONE_WELCOME_DESCRIPTION = 52061, // 0x0000CB5D + IDS_PHONE_WELCOME_DEFAULT_HEADER = 52062, // 0x0000CB5E + IDS_PHONE_WELCOME_DEFAULT_TEXT = 52063, // 0x0000CB5F + IDS_PHONE_WELCOME_CONFIG_HEADER = 52064, // 0x0000CB60 + IDS_PHONE_WELCOME_CONFIG_TEXT = 52065, // 0x0000CB61 + IDS_PHONE_WELCOME_NOTICE = 52066, // 0x0000CB62 + IDS_PHONE_SEARCHING = 52067, // 0x0000CB63 + IDS_PHONE_PIN_UNLOCK_TITLE = 52068, // 0x0000CB64 + IDS_PHONE_PIN_UNLOCK_TEXT = 52069, // 0x0000CB65 + IDS_PHONE_INTRO_TITLE = 52070, // 0x0000CB66 + IDS_PHONE_INTRO_DESCRIPTION = 52071, // 0x0000CB67 + IDS_PHONE_INTRO_TEXT_STEPS_HEADER = 52072, // 0x0000CB68 + IDS_PHONE_INTRO_TEXT_STEPS = 52073, // 0x0000CB69 + IDS_PHONE_INTRO_TEXT = 52074, // 0x0000CB6A + IDS_PHONE_UPDATE_CHECKING_TITLE = 52075, // 0x0000CB6B + IDS_PHONE_UPDATE_CHECKING_DESCRIPTION = 52076, // 0x0000CB6C + IDS_PHONE_UPDATE_CHECKING_STATUS = 52077, // 0x0000CB6D + IDS_PHONE_UPDATE_AVAILABLE_TITLE = 52078, // 0x0000CB6E + IDS_PHONE_UPDATE_AVAILABLE_DESCRIPTION = 52079, // 0x0000CB6F + IDS_PHONE_UPDATE_AVAILABLE_ATTENTION = 52080, // 0x0000CB70 + IDS_BREADCRUMB_PHONE_UPDATE = 52081, // 0x0000CB71 + IDS_DEVICE_ROLLBACK_SEARCHING_POINTS = 52082, // 0x0000CB72 + IDS_WIRELESS_DEVICELAND_SETUP_HEADER = 52083, // 0x0000CB73 + IDS_WIRELESS_DEVICELAND_SETUP_TEXT = 52084, // 0x0000CB74 + IDS_WIRELESS_DEVICELAND_SETUP_BUTTON = 52085, // 0x0000CB75 + IDS_PHONELAND_FIRSTRUN_HEADER = 52086, // 0x0000CB76 + IDS_PHONE_CURRENT_VERSION = 52087, // 0x0000CB77 + IDS_DEVICE_RESTORE_ERROR_NO_POINTS = 52088, // 0x0000CB78 + IDS_PHONE_FIRMWARE_UPDATE_WARNING = 52090, // 0x0000CB7A + IDS_PHONE_FIRMWARE_INSTALLING = 52091, // 0x0000CB7B + IDS_PHONE_FIRMWARE_UPDATE_UNAVAILABLE = 52092, // 0x0000CB7C + IDS_PHONE_ASSOCIATE_ZUNE_OFFER_LOGGEDOUT = 52093, // 0x0000CB7D + IDS_PHONE_ASSOCIATE_ZUNE_OFFER_LOGGEDIN = 52094, // 0x0000CB7E + IDS_PHONE_ASSOCIATE_ZUNE_OFFER_LOGGEDIN_YES = 52095, // 0x0000CB7F + IDS_PHONE_ASSOCIATED_ZUNE = 52096, // 0x0000CB80 + IDS_PHONE_DELETE_DEVICE_BUTTON = 52097, // 0x0000CB81 + IDS_PHONE_FORMAT_IN_PROGRESS = 52098, // 0x0000CB82 + IDS_PHONE_WIRELESS_SYNC_TEST_FAILED = 52099, // 0x0000CB83 + IDS_PHONE_FORMAT_DIALOG_TEXT = 52100, // 0x0000CB84 + IDS_PHONE_WIRELESS_SUGG_MAC_FILTERING = 52101, // 0x0000CB85 + IDS_PHONE_FIRMWARE_NEW_VERSION_OPTIONAL = 52102, // 0x0000CB86 + IDS_PHONE_WIRELESS_ALREADY_CONFIGURED = 52103, // 0x0000CB87 + IDS_PHONE_WIRELESS_DEVICE_BUSY = 52104, // 0x0000CB88 + IDS_PHONE_FORGET_DEVICE_DIALOG_CONTENT = 52105, // 0x0000CB89 + IDS_PHONE_LIBRARY_QUESTION_N_ITEMS = 52106, // 0x0000CB8A + IDS_PHONE_EULA_DIALOG_TITLE = 52107, // 0x0000CB8B + IDS_PHONE_EULA_DIALOG_TITLE_REQUIRED = 52108, // 0x0000CB8C + IDS_PHONE_FIRMWARE_NEW_VERSION = 52109, // 0x0000CB8D + IDS_PHONE_EULA_DIALOG_TEXTAREA_TITLE = 52110, // 0x0000CB8E + IDS_PHONE_FIRMWARE_ACCEPT_EULA = 52111, // 0x0000CB8F + IDS_PHONE_SPACE_RESERVATION_DESCRIPTION = 52112, // 0x0000CB90 + IDS_DEVICE_RECOVERY_ERROR_NO_POINTS = 52116, // 0x0000CB94 + IDS_PHONE_UPDATE_SUCCESS = 52117, // 0x0000CB95 + IDS_PHONE_OOBE_INCOMPLETE_TITLE = 52119, // 0x0000CB97 + IDS_PHONE_OOBE_INCOMPLETE_DESCRIPTION = 52120, // 0x0000CB98 + IDS_DEVICE_UPDATE_ESTIMATED_TIME = 52121, // 0x0000CB99 + IDS_ZUNE_UPDATE_AVAILABLE_PHONE_TITLE = 52122, // 0x0000CB9A + IDS_ZUNE_UPDATE_AVAILABLE_PHONE_DESCRIPTION = 52123, // 0x0000CB9B + IDS_ZUNE_UPDATE_AVAILABLE_PHONE_NOTICE = 52124, // 0x0000CB9C + IDS_PHONE_MUSIC_DEVICE_EMPTY = 52125, // 0x0000CB9D + IDS_PHONE_VIDEO_DEVICE_EMPTY = 52126, // 0x0000CB9E + IDS_PHONE_PHOTO_DEVICE_EMPTY = 52127, // 0x0000CB9F + IDS_PHONE_PLAYLIST_DEVICE_EMPTY_TITLE = 52128, // 0x0000CBA0 + IDS_PHONE_FIRMWARE_TRANSFERRING = 52129, // 0x0000CBA1 + IDS_PHONE_FIRMWARE_VERSION_PRE_TEXT = 52130, // 0x0000CBA2 + IDS_PHONE_ASSOCIATE_YOUR_ZUNE_DESCRIPTION2 = 52131, // 0x0000CBA3 + IDS_PHONE_NO_SYNC_OPTIONS_INFO = 52132, // 0x0000CBA4 + IDS_PHONE_TRANSCODE_VIDEO_PLAYBACK_OPTION = 52133, // 0x0000CBA5 + IDS_PHONE_REMOVE_SINGLE_SYNC_GROUP_DIALOG_TEXT = 52134, // 0x0000CBA6 + IDS_PHONE_REMOVE_MULTIPLE_SYNC_GROUP_DIALOG_TEXT = 52135, // 0x0000CBA7 + IDS_PHONE_REMOVE_SYNC_ALL_GROUP_DIALOG_TEXT = 52136, // 0x0000CBA8 + IDS_PHONE_FIRMWARE_UPDATE_SUCCESS = 52137, // 0x0000CBA9 + IDS_PHONE_ENABLE_ZUNE_MARKETPLACE_TEXT = 52138, // 0x0000CBAA + IDS_PHONE_ENABLE_ZUNE_MARKETPLACE_OPTION = 52139, // 0x0000CBAB + IDS_PHONE_PICK_A_NAME_HEADER = 52140, // 0x0000CBAC + IDS_PHONE_DISABLE_MARKETPLACE_BUTTON = 52141, // 0x0000CBAD + IDS_PHONE_FIRMWARE_UPDATE_ERROR_NOTICE2 = 52142, // 0x0000CBAE + IDS_PHONE_FIRMWARE_NEW_VERSION_REQUIRED = 52143, // 0x0000CBAF + IDS_PHONE_FIRMWARE_NOTICE = 52144, // 0x0000CBB0 + IDS_PHONE_FIRMWARE_UPDATE_SUCCESS_NOTICE = 52145, // 0x0000CBB1 + IDS_PHONE_SYNC_CHAN_FRIEND_DISABLED_EXPLANATION = 52146, // 0x0000CBB2 + IDS_PHONE_FIRMWARE_MANDATE = 52147, // 0x0000CBB3 + IDS_PHONE_ZUNE_MARKETPLACE_LINKEDTO = 52148, // 0x0000CBB4 + IDS_PHONE_ENABLE_ZUNE_SOCIAL_TEXT_NO_MP = 52149, // 0x0000CBB5 + IDS_PHONE_FRIENDS_EMPTY_DEVICE_HEADER = 52150, // 0x0000CBB6 + IDS_PHONE_RENT_TARGET_DEVICE = 52151, // 0x0000CBB7 + IDS_PHONE_PODCAST_EMPTY_DEVICE_TITLE = 52152, // 0x0000CBB8 + IDS_PHONE_CHANNELS_EMPTY_DEVICE_TITLE = 52153, // 0x0000CBB9 + IDS_PHONE_DEVICE_UP_TO_DATE = 52154, // 0x0000CBBA + IDS_PHONE_DEVICE_NAME_EMPTY = 52155, // 0x0000CBBB + IDS_PHONE_ITEMS_SYNCED_DESCRIPTION = 52156, // 0x0000CBBC + IDS_PHONE_ITEMS_REMAINING_DESCRIPTION = 52157, // 0x0000CBBD + IDS_PHONE_DEVICE_SETTINGS_NAME = 52158, // 0x0000CBBE + IDS_PHONE_ALL_SYNCED_ITEMS = 52159, // 0x0000CBBF + IDS_PHONE_COMPUTER_ICON_DROP_TARGET_TOOLTIP = 52160, // 0x0000CBC0 + IDS_PHONE_ALL_PICTURE_ITEMS = 52161, // 0x0000CBC1 + IDS_PHONE_ALL_PODCAST_ITEMS = 52162, // 0x0000CBC2 + IDS_PHONE_DEVICE_HUNG = 52163, // 0x0000CBC3 + IDS_PHONE_OUT_OF_SPACE_GAS_GAUGE_FORMAT = 52164, // 0x0000CBC4 + IDS_PHONE_GUEST_OUT_OF_SPACE_MESSAGE = 52165, // 0x0000CBC5 + IDS_PHONE_DEVICE_STATUS_SOCIAL_DESC_NO_ASSOC = 52166, // 0x0000CBC6 + IDS_PHONE_NOT_OUT_OF_SPACE_GAS_GAUGE_FORMAT = 52167, // 0x0000CBC7 + IDS_PHONE_DEVICE_STATUS_SOCIAL_DESC_ASSOC = 52168, // 0x0000CBC8 + IDS_PHONE_DEVICE_SUMMARY_DEVICE_UPDATE_TITLE = 52169, // 0x0000CBC9 + IDS_PHONE_DEVICE_RENTAL_GUEST_NOT_SUPPORTED = 52170, // 0x0000CBCA + IDS_PHONE_SPACE_RESERVATION_DESCRIPTION_NO_MARKETPLACE = 52171, // 0x0000CBCB + IDS_PHONE_NO_IP_TITLE = 52175, // 0x0000CBCF + IDS_PHONE_NO_IP_TEXT = 52176, // 0x0000CBD0 + IDS_PHONE_TLS_ERROR_TITLE = 52177, // 0x0000CBD1 + IDS_PHONE_TLS_ERROR_TEXT = 52178, // 0x0000CBD2 + IDS_PHONELAND_FIRSTRUN_TEXT_1 = 52179, // 0x0000CBD3 + IDS_PHONELAND_FIRSTRUN_TEXT_2 = 52180, // 0x0000CBD4 + IDS_PHONE_LOOKING_FOR_REGISTERED_DEVICES = 52182, // 0x0000CBD6 + IDS_PLEASE_SIGN_INTO_PHONE_LIVEID = 52183, // 0x0000CBD7 + IDS_PHONE_SIGNIN_REQUIRED_FOR_APP_PURCHASE = 52184, // 0x0000CBD8 + IDS_PHONE_ACCOUNTSWITCH_REQUIRED_FOR_APP_PURCHASE = 52185, // 0x0000CBD9 + IDS_UNLINKED_PHONE_DURING_APP_PURCHASE = 52186, // 0x0000CBDA + IDS_PHONE_SIGNIN_REQUIRED_FOR_MYPHONE_LINKS = 52187, // 0x0000CBDB + IDS_PHONE_ACCOUNTSWITCH_REQUIRED_FOR_MYPHONE_LINKS = 52188, // 0x0000CBDC + IDS_MYPHONE_LINKS_SIGNIN_BUTTON = 52189, // 0x0000CBDD + IDS_PHONE_ITEMS_SYNCED_TITLE = 52190, // 0x0000CBDE + IDS_PHONE_ITEMS_REMAINING_TITLE = 52191, // 0x0000CBDF + IDS_PHONE_ITEMS_REMOVED_TITLE = 52192, // 0x0000CBE0 + IDS_PHONE_ITEMS_FAILED_TITLE = 52193, // 0x0000CBE1 + IDS_WIRELESS_MOBILE_WARNING_TITLE = 52194, // 0x0000CBE2 + IDS_PHONELAND_FIRSTRUN_KIN_STUDIO_HEADER = 52195, // 0x0000CBE3 + IDS_PHONELAND_FIRSTRUN_KIN_STUDIO_TEXT = 52196, // 0x0000CBE4 + IDS_PHONELAND_FIRSTRUN_KIN_STUDIO_LINK = 52197, // 0x0000CBE5 + IDS_DEVICE_UPDATE_CALCULATION_IN_PROGRESS = 52198, // 0x0000CBE6 + IDS_DO_MORE_ON_WEB_HEADER = 52199, // 0x0000CBE7 + IDS_DO_MORE_ON_WEB_DESCRIPTION = 52200, // 0x0000CBE8 + IDS_DO_MORE_ON_WEB_LINK_TEXT = 52201, // 0x0000CBE9 + IDS_DO_MORE_ON_WEB_LINK_ADDRESS = 52202, // 0x0000CBEA + IDS_PHONE_UPDATE_SYNCING_DESCRIPTION = 52205, // 0x0000CBED + IDS_PHONE_UPDATE_GUEST_WARNING_TITLE = 52206, // 0x0000CBEE + IDS_PHONE_UPDATE_GUEST_WARNING_DESCRIPTION = 52207, // 0x0000CBEF + IDS_PHONE_UPDATE_ERROR_FRIENDLY = 52208, // 0x0000CBF0 + IDS_DEVICE_DISK_SPACE_BODY = 52239, // 0x0000CC0F + IDS_DEVICE_DISK_SPACE_REQUIRED_SPACE = 52240, // 0x0000CC10 + IDS_DEVICE_DISK_SPACE_BODY2 = 52241, // 0x0000CC11 + IDS_DEVICE_DISK_SPACE_CHECKBOX = 52242, // 0x0000CC12 + IDS_DEVICE_DISK_SPACE_WAIT_TEXT = 52243, // 0x0000CC13 + IDS_PHONE_UPDATE_SYNCING_DESCRIPTION_ERR = 52244, // 0x0000CC14 + IDS_DEVICE_SYNCING_DESCRIPTION_ERR = 52245, // 0x0000CC15 + IDS_DEVICE_RESTORE_SYNCING_DESCRIPTION_ERR = 52246, // 0x0000CC16 + IDS_PHONE_UPDATE_ADDITIONAL_CHECKING_TITLE = 52249, // 0x0000CC19 + IDS_PHONE_UPDATE_CHECKING_MORE_UPDATES = 52251, // 0x0000CC1B + IDS_PHONE_UPDATE_GUEST_WARNING_BODY = 52252, // 0x0000CC1C + IDS_PHONE_UPDATE_TIME_WARNING = 52253, // 0x0000CC1D + IDS_RADIO_EMPTY = 53000, // 0x0000CF08 + IDS_RADIO_ERROR = 53001, // 0x0000CF09 + IDS_RADIO_NOTIMPL_ERROR = 53002, // 0x0000CF0A + IDS_RADIO_INVALID_ERROR = 53003, // 0x0000CF0B + IDS_RADIO_PIVOT = 53004, // 0x0000CF0C + IDS_RADIO_HEADER = 53005, // 0x0000CF0D + IDS_APPLICATIONS_HEADER = 54000, // 0x0000D2F0 + IDS_APPLICATIONS_EMPTY = 54001, // 0x0000D2F1 + IDS_APPLICATIONS_DEVICE_EMPTY = 54002, // 0x0000D2F2 + IDS_APPLICATIONS_EMPTY_MARKETPLACE_LINK = 54003, // 0x0000D2F3 + IDS_APP_RELEASE_DATE_LABEL = 54004, // 0x0000D2F4 + IDS_APP_VERSION_LABEL = 54005, // 0x0000D2F5 + IDS_APP_SELECT_ONE = 54006, // 0x0000D2F6 + IDS_APPLICATION_HEADER = 54007, // 0x0000D2F7 + IDS_FEATURESCHANGED_TITLE = 56000, // 0x0000DAC0 + IDS_FEATURESCHANGED_CONTENT = 56001, // 0x0000DAC1 + IDS_UNKNOWN_REGION_OR_LANGUAGE_TITLE = 56002, // 0x0000DAC2 + IDS_PHOTOS_SETTINGS_TITLE = 57000, // 0x0000DEA8 + IDS_PHOTOS_SETTINGS_IMPORT_TITLE = 57001, // 0x0000DEA9 + IDS_PHOTOS_SETTINGS_DELETE_AFTER_REVERSE_SYNC = 57003, // 0x0000DEAB + IDS_PHOTOS_SETTINGS_CAMERA_ROLL_DEST = 57004, // 0x0000DEAC + IDS_PHOTOS_SETTINGS_CAMERA_ROLL_DEST_WIN7 = 57005, // 0x0000DEAD + IDS_PHOTOS_SETTINGS_QUALITY_TITLE = 57006, // 0x0000DEAE + IDS_PHOTOS_SETTINGS_QUALITY_DESC = 57007, // 0x0000DEAF + IDS_PHOTOS_SETTINGS_QUALITY_ORIGINAL = 57008, // 0x0000DEB0 + IDS_PHOTOS_SETTINGS_QUALITY_DEFAULT = 57009, // 0x0000DEB1 + IDS_PHOTOS_SETTINGS_QUALITY_VGA = 57010, // 0x0000DEB2 + IDS_PHOTOS_SETTINGS_AUTOUPLOADER_TITLE = 57011, // 0x0000DEB3 + IDS_PHOTOS_SETTINGS_AUTOUPLOADER_DESC = 57012, // 0x0000DEB4 + IDS_CHECKING_FOR_UPDATES_FAILED = 57013, // 0x0000DEB5 + IDS_OPTION_FOR_WINDOWS_PHONE_ONLY = 57014, // 0x0000DEB6 + IDS_BILLING_LIST_AND_ADD_CC_DESC = 57015, // 0x0000DEB7 + IDS_BILLING_ADD_CC_TO_ACCOUNT_DESC = 57016, // 0x0000DEB8 + IDS_ACCOUNT_ADD_CC_TO_ACCOUNT_ERROR_TITLE = 57017, // 0x0000DEB9 + IDS_ACCOUNT_ADD_CC_TO_ACCOUNT_ERROR_DESC = 57018, // 0x0000DEBA + IDS_ACCOUNT_ADD_CC_TO_ACCOUNT_SUCCESS_DESC = 57019, // 0x0000DEBB + IDS_PHOTO_EXPANDFOLDER_MENUITEM = 57020, // 0x0000DEBC + IDS_PHOTO_COLLAPSEFOLDER_MENUITEM = 57021, // 0x0000DEBD + IDS_PHOTO_CREATE_MENUITEM = 57022, // 0x0000DEBE + IDS_COLLECTION_VIDEO_PERSONAL_PIVOT = 57023, // 0x0000DEBF + IDS_COLLECTION_VIDEO_PERSONAL = 57024, // 0x0000DEC0 + IDS_NEW_ALBUM_NAME = 57025, // 0x0000DEC1 + IDS_NEW_ALBUM_NAME_MULTIPLE = 57026, // 0x0000DEC2 + IDS_VIDEO_PERSONAL_EMPTY = 57027, // 0x0000DEC3 + IDS_PHOTOS_SETTINGS_AUTOUPLOADER_VIEWMORE = 57028, // 0x0000DEC4 + IDS_AC_POWER_WARNING_TITLE = 57029, // 0x0000DEC5 + IDS_AC_POWER_WARNING_DESCRIPTION = 57030, // 0x0000DEC6 + IDS_PHOTOS_SETTINGS_LEAVE_AFTER_REVERSE_SYNC = 57031, // 0x0000DEC7 + IDS_VIDEO_PERSONAL_PHONE_EMPTY = 57032, // 0x0000DEC8 + IDS_SPACE_RESERVATION_DESCRIPTION_NO_SOCIAL = 67000, // 0x000105B8 + IDS_SPACE_RESERVATION_DESCRIPTION_NO_FEATURES = 67001, // 0x000105B9 + IDS_WIN7LIBRARIES_OPTOUT_EXPLANATION = 67002, // 0x000105BA + IDS_WIN7LIBRARIES_OPTOUT_ACTION = 67003, // 0x000105BB + IDS_WIN7LIBRARIES_OPTOUT_MESSAGEBOX = 67004, // 0x000105BC + IDS_WIN7LIBRARIES_OPTIN_EXPLANATION = 67005, // 0x000105BD + IDS_WIN7LIBRARIES_OPTIN_ACTION = 67006, // 0x000105BE + IDS_WIN7LIBRARIES_OPTIN_MESSAGEBOX = 67007, // 0x000105BF + IDS_CONFIRM_SUBSCRIPTION_HEADER = 67008, // 0x000105C0 + IDS_SUBSCRIPTION_DETAILS_TITLE = 67009, // 0x000105C1 + IDS_UPDATE_METADATA_QUICKMIX_CHECK = 67010, // 0x000105C2 + IDS_REGDEVICES_PAGE_LINK = 67011, // 0x000105C3 + IDS_SPACE_RESERVATION_SUB_HEADER = 67012, // 0x000105C4 + IDS_SPACE_RESERVATION_SUB_CONTENT = 67013, // 0x000105C5 + IDS_ACCOUNT_NEWSLTR_MKTG_EMAIL_DESC = 67014, // 0x000105C6 + IDS_ACCOUNT_NEWSLTR_MKTG_EMAIL_URL = 67015, // 0x000105C7 + IDS_CHECK_FOR_UPDATES_FAILED_DESCRIPTION = 67016, // 0x000105C8 + IDS_TERMS_OF_SERVICE_URL = 77000, // 0x00012CC8 + IDS_ACCOUNT_CREATION_ZUNE_ALL_SOCIAL_DESC = 77001, // 0x00012CC9 + IDS_ACCOUNT_CREATION_ZUNE_ALL_SOCIAL_HEAD = 77002, // 0x00012CCA + IDS_ACCOUNT_PHONE_NUMBER_FORMAT = 77003, // 0x00012CCB + IDS_ZUNEPASS_TERMS_OF_SERVICE_URL = 77004, // 0x00012CCC + IDS_ZUNEPASS_TERMS_OF_SERVICE_TITLE = 77005, // 0x00012CCD + IDS_ZUNEPASS_AGREEMENT_TEXT = 77006, // 0x00012CCE + IDS_ZUNEPASS_PRINT_DETAILS_URL = 77007, // 0x00012CCF + IDS_ZUNEPASS_PRINT_DETAILS_TITLE = 77008, // 0x00012CD0 + IDS_BILLING_CONTINUE = 77009, // 0x00012CD1 + IDS_ACCOUNT_CREATION_STATE = 77010, // 0x00012CD2 + IDS_ACCOUNT_CREATION_PROVINCE = 77011, // 0x00012CD3 + IDS_ACCOUNT_CREATION_PERSONALIZE_HEADER = 77012, // 0x00012CD4 + IDS_ACCOUNT_CREATION_PERSONALIZE_DESC = 77013, // 0x00012CD5 + IDS_CONTACT_PHONE_LABEL = 77014, // 0x00012CD6 + IDS_ACCOUNT_CHANGE_ZUNE_TAG = 77015, // 0x00012CD7 + IDS_ACCOUNT_CHANGE_ZUNE_TAG_MENU_ITEM = 77016, // 0x00012CD8 + IDS_ACCOUNT_CHANGE_ZUNE_TAG_URL = 77017, // 0x00012CD9 + IDS_ACCOUNT_CREATION_FROM_PURCHASE = 77018, // 0x00012CDA + IDS_ACCOUNT_CREATION_FROM_SIGN_IN = 77019, // 0x00012CDB + IDS_ACCOUNT_SIGNING_INTO_WINDOWS_LIVE = 77020, // 0x00012CDC + IDS_ACCOUNT_PURCHASE_ABOUT_ZUNE_PASS_URL = 77021, // 0x00012CDD + IDS_ACCOUNT_PURCHASE_ABOUT_ZUNE_PASS_LINK_TEXT = 77022, // 0x00012CDE + IDS_ACCOUNT_ABOUT_ZUNE_PASS_URL = 77023, // 0x00012CDF + IDS_ACCOUNT_ABOUT_ZUNE_PASS_LINK_TEXT = 77024, // 0x00012CE0 + IDS_BILLING_BUY_PASS_DESC2_NOTRIAL = 77025, // 0x00012CE1 + IDS_ACCOUNT_CREATION_SUBSCRIPTION_TITLE = 77026, // 0x00012CE2 + IDS_ACCOUNT_CREATION_SUBSCRIPTION_DESC = 77027, // 0x00012CE3 + IDS_ACCOUNT_CREATION_FREE_TRIAL_GENERIC_DESC = 77028, // 0x00012CE4 + IDS_ACCOUNT_CREATION_PRIVACY_INSTRUCTIONS = 77029, // 0x00012CE5 + IDS_ACCOUNT_PRIVACY_INSTRUCTIONS = 77030, // 0x00012CE6 + IDS_VALIDATE_CREDIT_CARD_HEADER = 77037, // 0x00012CED + IDS_VALIDATE_CREDIT_CARD_BODY = 77038, // 0x00012CEE + IDS_ACCOUNT_CREATION_SECRET_ANSWER_HELP_3CHARS = 77039, // 0x00012CEF + } +} diff --git a/ZuneUI/StringListPropertyDescriptor.cs b/ZuneUI/StringListPropertyDescriptor.cs new file mode 100644 index 0000000..fc860a4 --- /dev/null +++ b/ZuneUI/StringListPropertyDescriptor.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StringListPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class StringListPropertyDescriptor : PropertyDescriptor + { + public StringListPropertyDescriptor(string name, string multiValueString, string unknownString) + : base(name, multiValueString, unknownString) + { + } + + public override string ConvertToString(object value) => value != null ? TrackDetails.ContributingArtistListToString((IList)value) : (string)null; + + public override object ConvertFromString(string value) => value != null ? (object)TrackDetails.ContributingArtistStringToList(value) : (object)null; + } +} diff --git a/ZuneUI/StringParserHelper.cs b/ZuneUI/StringParserHelper.cs new file mode 100644 index 0000000..bd52cf5 --- /dev/null +++ b/ZuneUI/StringParserHelper.cs @@ -0,0 +1,228 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StringParserHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; +using System.Globalization; +using System.Text; +using System.Text.RegularExpressions; + +namespace ZuneUI +{ + public static class StringParserHelper + { + private static Regex s_notNumberRegex = new Regex("[^0-9]"); + private static string s_validNumberChars = "0123456789"; + + public static int ParseInt32(string input) + { + int result; + int.TryParse(input, out result); + return result; + } + + public static int NumberFilter(string input) => StringParserHelper.ParseInt32(StringParserHelper.s_notNumberRegex.Replace(input, string.Empty)); + + public static bool TryParseDate(string input, DateTimeKind dateTimeKind, out DateTime dateTime) + { + switch (dateTimeKind) + { + case DateTimeKind.Utc: + if (!DateTime.TryParse(input, out dateTime) && !DateTime.TryParse(input, (IFormatProvider)CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.RoundtripKind, out dateTime)) + { + int result; + if (!int.TryParse(input, out result) || result < 1 || result > 9999) + return false; + dateTime = new DateTime(result, 1, 1, 0, 0, 0, DateTimeKind.Utc); + } + else + dateTime = new DateTime(dateTime.Ticks, DateTimeKind.Utc); + return true; + case DateTimeKind.Local: + if (!DateTime.TryParse(input, out dateTime) && !DateTime.TryParse(input, (IFormatProvider)CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.RoundtripKind, out dateTime)) + { + int result; + if (!int.TryParse(input, out result) || result < 1 || result > 9999) + return false; + dateTime = new DateTime(result, 1, 1, 0, 0, 0, DateTimeKind.Local); + dateTime = dateTime.ToUniversalTime(); + } + else + dateTime = dateTime.ToUniversalTime(); + return true; + default: + return StringParserHelper.TryParseDate(input, out dateTime); + } + } + + public static bool TryParseDate(string input, out DateTime dateTime) + { + if (!DateTime.TryParse(input, out dateTime) && !DateTime.TryParse(input, (IFormatProvider)CultureInfo.CurrentCulture.DateTimeFormat, DateTimeStyles.RoundtripKind, out dateTime)) + { + int result; + if (!int.TryParse(input, out result) || result < 1 || result > 9999) + return false; + dateTime = new DateTime(result, 1, 1, 0, 0, 0, DateTimeKind.Utc); + } + else + dateTime = dateTime.ToUniversalTime(); + return true; + } + + public static string CoerceToNonNegativeInt(string input) + { + if (input != null) + { + StringBuilder stringBuilder = (StringBuilder)null; + int index = 0; + int startIndex = 0; + for (; index < input.Length; ++index) + { + if (StringParserHelper.s_validNumberChars.IndexOf(input[index]) < 0) + { + if (stringBuilder == null) + stringBuilder = new StringBuilder(input); + stringBuilder.Remove(startIndex, 1); + } + else + ++startIndex; + } + if (stringBuilder != null) + input = stringBuilder.ToString(); + } + return input; + } + + public static int ParseYear(string input) + { + int result = 0; + if (input != null && input.Length <= 4 && int.TryParse(input, out result)) + { + if (result >= 0) + { + if (result < 20) + result += 2000; + else if (result < 100) + result += 1900; + else if (result < 1000) + result += 2000; + } + else + result = 0; + } + return result; + } + + public static IList Split(string source, string splitCharacter) => (IList)source.Split(new string[1] + { + splitCharacter + }, StringSplitOptions.None); + + public static bool IsNullOrEmptyOrBlank(string value) => string.IsNullOrEmpty(value) || value.Trim().Length == 0; + + public static string HtmlTagsToLowerCase(string html) + { + if (!string.IsNullOrEmpty(html)) + { + StringBuilder stringBuilder = (StringBuilder)null; + bool flag = false; + for (int index = 0; index < html.Length; ++index) + { + char c = html[index]; + switch (c) + { + case '<': + flag = true; + break; + case '>': + flag = false; + break; + default: + if (!char.IsWhiteSpace(c)) + break; + goto case '>'; + } + if (flag && char.IsUpper(c)) + { + if (stringBuilder == null) + stringBuilder = new StringBuilder(html); + stringBuilder[index] = char.ToLower(c); + } + } + if (stringBuilder != null) + html = stringBuilder.ToString(); + } + return html; + } + + public static string StripHtmlTags(string html) + { + if (!string.IsNullOrEmpty(html)) + { + StringBuilder stringBuilder = (StringBuilder)null; + bool flag = false; + for (int index = 0; index < html.Length; ++index) + { + char ch = html[index]; + if (ch == '<') + flag = true; + if (!flag) + { + if (stringBuilder == null) + stringBuilder = new StringBuilder(html.Length); + stringBuilder.Append(ch); + } + if (ch == '>') + flag = false; + } + if (stringBuilder != null) + html = stringBuilder.ToString(); + } + return html; + } + + public static string FormatFirmwareVersion(string version) + { + if (string.IsNullOrEmpty(version)) + return string.Empty; + string[] strArray = version.Split('.'); + if (strArray.Length < 3) + return version; + int int32_1 = StringParserHelper.ParseInt32(strArray[0]); + int int32_2 = StringParserHelper.ParseInt32(strArray[1]); + int int32_3 = StringParserHelper.ParseInt32(strArray[2]); + version = int32_1 != 0 ? string.Format(Shell.LoadString(StringId.IDS_FIRMWARE_VERSION_FORMAT), (object)int32_1, (object)int32_2, (object)int32_3) : Shell.LoadString(StringId.IDS_DEVICE_RECOVERY_MODE); + return version; + } + + public static int CompareFirmwareVersions(string versionA, string versionB) + { + string[] strArray1 = new string[3] { "0", "0", "0" }; + string[] strArray2; + if (string.IsNullOrEmpty(versionA)) + strArray2 = strArray1; + else + strArray2 = versionA.Split('.'); + string[] strArray3; + if (string.IsNullOrEmpty(versionB)) + strArray3 = strArray1; + else + strArray3 = versionB.Split('.'); + int int32_1 = StringParserHelper.ParseInt32(strArray2[0]); + int int32_2 = StringParserHelper.ParseInt32(strArray2[1]); + int int32_3 = StringParserHelper.ParseInt32(strArray2[2]); + int int32_4 = StringParserHelper.ParseInt32(strArray3[0]); + int int32_5 = StringParserHelper.ParseInt32(strArray3[1]); + int int32_6 = StringParserHelper.ParseInt32(strArray3[2]); + int num1 = int32_1.CompareTo(int32_4); + int num2 = int32_2.CompareTo(int32_5); + int num3 = int32_3.CompareTo(int32_6); + if (num1 != 0) + return num1; + return num2 != 0 ? num2 : num3; + } + } +} diff --git a/ZuneUI/StringSet.cs b/ZuneUI/StringSet.cs new file mode 100644 index 0000000..32504eb --- /dev/null +++ b/ZuneUI/StringSet.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.StringSet +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class StringSet + { + private SortedDictionary _set = new SortedDictionary(); + + public void Add(string s) => this._set[s] = (object)null; + + public void Clear() => this._set.Clear(); + + public IList ToList() + { + List stringList = new List(this._set.Count); + foreach (KeyValuePair keyValuePair in this._set) + stringList.Add(keyValuePair.Key); + return (IList)stringList; + } + } +} diff --git a/ZuneUI/SubList.cs b/ZuneUI/SubList.cs new file mode 100644 index 0000000..bb107a9 --- /dev/null +++ b/ZuneUI/SubList.cs @@ -0,0 +1,95 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SubList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public abstract class SubList : ModelItem + { + private IList _source; + private List _subLists; + + public IList Source + { + get => this._source; + set + { + if (this._source == value) + return; + this._source = value; + this.FirePropertyChanged(nameof(Source)); + this.ProduceSubLists(); + } + } + + public List SubLists + { + get => this._subLists; + private set + { + if (this._subLists == value) + return; + this._subLists = value; + this.FirePropertyChanged(nameof(SubLists)); + } + } + + protected void ProduceSubLists() + { + int num1 = 0; + if (this._source != null) + num1 = this._source.Count; + List listList = new List(); + List splits = this.GetSplits(); + int num2 = 0; + if (splits != null) + { + for (int index = 0; index < splits.Count; ++index) + { + int val1 = splits[index]; + int begin = Math.Min(num2, num1); + int end = Math.Min(val1, num1); + listList.Add((IList)new SubList.SubListSection((IModelItemOwner)this, begin, end, this._source)); + num2 = end; + } + } + if (num2 < num1 || num1 == 0) + listList.Add((IList)new SubList.SubListSection((IModelItemOwner)this, num2, num1, this._source)); + this.SubLists = listList; + } + + protected abstract List GetSplits(); + + protected void ValidateSplits(List splits) + { + int num = 0; + foreach (int split in splits) + num = split >= num ? split : throw new ArgumentException("Split values must be sequential"); + } + + private class SubListSection : VirtualList + { + private int _begin; + private int _end; + private IList _source; + + public SubListSection(IModelItemOwner owner, int begin, int end, IList source) + : base(owner, false, (ItemCountHandler)null) + { + this._begin = begin; + this._end = end; + this._source = source; + this.Count = this._end - this._begin; + } + + protected override object OnRequestItem(int index) => this._source[index + this._begin]; + } + } +} diff --git a/ZuneUI/SubscribeConfirmDialogHelper.cs b/ZuneUI/SubscribeConfirmDialogHelper.cs new file mode 100644 index 0000000..75a19f4 --- /dev/null +++ b/ZuneUI/SubscribeConfirmDialogHelper.cs @@ -0,0 +1,57 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SubscribeConfirmDialogHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Subscription; +using System; +using UIXControls; +using ZuneXml; + +namespace ZuneUI +{ + internal class SubscribeConfirmDialogHelper + { + private string m_feedTitle; + private string m_feedUrl; + + private SubscribeConfirmDialogHelper(string feedTitle, string feedUrl) + { + this.m_feedUrl = feedUrl; + if (!string.IsNullOrEmpty(feedTitle)) + this.m_feedTitle = feedTitle; + else + this.m_feedTitle = feedUrl; + } + + private void ShowDialog() => MessageBox.Show(Shell.LoadString(StringId.IDS_PODCAST_CONFIRM_DIALOG_TITLE), string.Format(Shell.LoadString(StringId.IDS_PODCAST_CONFIRM_DIALOG_MESSAGE), (object)this.m_feedTitle), new EventHandler(this.OnConfirm)); + + private void OnConfirm(object sender, EventArgs args) + { + SubscriptionManager instance = SubscriptionManager.Instance; + int subscriptionMediaId = -1; + if (!instance.FindByUrl(this.m_feedUrl, EMediaTypes.eMediaTypePodcastSeries, out subscriptionMediaId, out bool _)) + { + HRESULT hresult = (HRESULT)instance.Subscribe(this.m_feedUrl, this.m_feedTitle, Guid.Empty, false, EMediaTypes.eMediaTypePodcastSeries, ESubscriptionSource.eSubscriptionSourceProtocolHandler, out subscriptionMediaId); + if (hresult.IsSuccess) + { + string endPointUri = Microsoft.Zune.Service.Service.GetEndPointUri(Microsoft.Zune.Service.EServiceEndpointId.SEID_RootCatalog); + if (!string.IsNullOrEmpty(endPointUri) && !string.IsNullOrEmpty(this.m_feedUrl) && this.m_feedUrl.Length < 1024) + WebRequestHelper.ConstructWebPostRequest(endPointUri + "/podcast", "URL=" + this.m_feedUrl, EPassportPolicyId.None, HttpRequestCachePolicy.Default, true, false).GetResponseAsync(new AsyncRequestComplete(this.OnRequestComplete), (object)null); + } + else + ErrorDialogInfo.Show(hresult.Int, Shell.LoadString(StringId.IDS_PODCAST_SUBSCRIPTION_ERROR)); + } + PodcastLibraryPage.FindInCollection(subscriptionMediaId); + } + + private void OnRequestComplete(HttpWebResponse response, object requestArgs) + { + int statusCode = (int)response.StatusCode; + } + + public static void Show(string feedTitle, string feedUrl) => new SubscribeConfirmDialogHelper(feedTitle, feedUrl).ShowDialog(); + } +} diff --git a/ZuneUI/SubscriptionDetailsPanel.cs b/ZuneUI/SubscriptionDetailsPanel.cs new file mode 100644 index 0000000..22462f7 --- /dev/null +++ b/ZuneUI/SubscriptionDetailsPanel.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SubscriptionDetailsPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class SubscriptionDetailsPanel : LibraryPanel + { + public SubscriptionDetailsPanel(SubscriptionLibraryPage page) + : base((IModelItemOwner)page) + { + } + } +} diff --git a/ZuneUI/SubscriptionEndingDialog.cs b/ZuneUI/SubscriptionEndingDialog.cs new file mode 100644 index 0000000..6fe2895 --- /dev/null +++ b/ZuneUI/SubscriptionEndingDialog.cs @@ -0,0 +1,73 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SubscriptionEndingDialog +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using UIXControls; + +namespace ZuneUI +{ + public class SubscriptionEndingDialog : DialogHelper + { + private BooleanChoice m_neverShowAgain; + private Command m_subscribe; + private Command m_delete; + private string m_title; + + public static void Show(DateTime endDate) + { + if (ZuneShell.DefaultInstance.Management.InhibitSubscriptionEndingWarning || ZuneShell.DefaultInstance.Management.CurrentCategoryPage != null && ZuneShell.DefaultInstance.Management.CurrentCategoryPage.IsWizard) + return; + new SubscriptionEndingDialog(endDate).Show(); + } + + public Command Delete => this.m_delete; + + public Command Subscribe => this.m_subscribe; + + public BooleanChoice NeverShowAgain => this.m_neverShowAgain; + + public string Title => this.m_title; + + protected SubscriptionEndingDialog(DateTime endDate) + : base("res://ZuneShellResources!BillingOffer.uix#SubscriptionEndingDialogContentUI") + { + if (endDate >= DateTime.Today) + { + this.m_title = Shell.LoadString(StringId.IDS_BILLING_SUBSCRIPTION_ENDING_TITLE); + this.Description = string.Format(Shell.LoadString(StringId.IDS_BILLING_SUBSCRIPTION_ENDING_WARNING), (object)endDate); + } + else + { + this.m_title = Shell.LoadString(StringId.IDS_BILLING_SUBSCRIPTION_ENDED_TITLE); + this.Description = Shell.LoadString(StringId.IDS_BILLING_SUBSCRIPTION_ENDED_WARNING); + } + this.m_subscribe = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_BILLING_RENEW_SUBSCRIPTION), new EventHandler(this.OnSubscribe)); + this.m_delete = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_ACCOUNT_CLEAR_SUBSCRIPTION_BUTTON), new EventHandler(this.OnDeleteInvoked)); + this.Cancel.Invoked += new EventHandler(this.OnCancel); + this.m_neverShowAgain = new BooleanChoice((IModelItemOwner)this, Shell.LoadString(StringId.IDS_DONT_SHOW_THIS_MESSAGE_AGAIN)); + this.m_neverShowAgain.Value = false; + this.m_neverShowAgain.ChosenChanged += new EventHandler(this.OnNeverShowAgain); + } + + private void OnCancel(object sender, EventArgs args) => this.Hide(); + + private void OnNeverShowAgain(object sender, EventArgs args) => ZuneShell.DefaultInstance.Management.InhibitSubscriptionEndingWarning = this.m_neverShowAgain.Value; + + private void OnSubscribe(object sender, EventArgs args) + { + ZuneShell.DefaultInstance.Execute("Settings\\Account\\PurchaseSubscription", (IDictionary)null); + this.Hide(); + } + + private void OnDeleteInvoked(object sender, EventArgs args) + { + DeleteSubscriptionDownloadsDialog.ShowDialog(); + this.Hide(); + } + } +} diff --git a/ZuneUI/SubscriptionEpisodePanel.cs b/ZuneUI/SubscriptionEpisodePanel.cs new file mode 100644 index 0000000..afbd91f --- /dev/null +++ b/ZuneUI/SubscriptionEpisodePanel.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SubscriptionEpisodePanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class SubscriptionEpisodePanel : ListPanel + { + private ArrayList _selectedLibraryIds = new ArrayList(); + + public override IList SelectedLibraryIds => (IList)this._selectedLibraryIds; + + public SubscriptionEpisodePanel(SubscriptionLibraryPage page) + : base((IModelItemOwner)page) + { + } + } +} diff --git a/ZuneUI/SubscriptionEventsListener.cs b/ZuneUI/SubscriptionEventsListener.cs new file mode 100644 index 0000000..fb0a830 --- /dev/null +++ b/ZuneUI/SubscriptionEventsListener.cs @@ -0,0 +1,98 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SubscriptionEventsListener +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Subscription; +using System; +using System.ComponentModel; + +namespace ZuneUI +{ + public class SubscriptionEventsListener : INotifyPropertyChanged + { + private static volatile SubscriptionEventsListener m_instance; + private static MessageNotification _notification; + private static object myLock = new object(); + + private SubscriptionEventsListener() + { + } + + public static SubscriptionEventsListener Instance + { + get + { + if (SubscriptionEventsListener.m_instance == null) + { + lock (SubscriptionEventsListener.myLock) + { + if (SubscriptionEventsListener.m_instance == null) + SubscriptionEventsListener.m_instance = new SubscriptionEventsListener(); + } + } + return SubscriptionEventsListener.m_instance; + } + } + + public event PropertyChangedEventHandler PropertyChanged; + + public void StartListening() => SubscriptionManager.Instance.OnForegroundSubscriptionChanged += new SubscriptionEventHandler(this.OnForegroundSubscriptionChanged); + + public void StopListening() => SubscriptionManager.Instance.OnForegroundSubscriptionChanged -= new SubscriptionEventHandler(this.OnForegroundSubscriptionChanged); + + public event EventHandler SubscriptionChanged; + + private void OnForegroundSubscriptionChanged(SubscriptonEventArguments args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredOnForegroundSubscriptionChanged), (object)args, DeferredInvokePriority.Normal); + + private void DeferredOnForegroundSubscriptionChanged(object args) + { + SubscriptonEventArguments subscriptonEventArguments = (SubscriptonEventArguments)args; + if (subscriptonEventArguments.Action != SubscriptionAction.Unsubscribed && subscriptonEventArguments.UserInitiated && (subscriptonEventArguments.MediaType == EMediaTypes.eMediaTypePodcastSeries || subscriptonEventArguments.MediaType == EMediaTypes.eMediaTypePlaylist)) + { + if (SubscriptionEventsListener._notification == null) + { + SubscriptionEventsListener._notification = new MessageNotification(NotificationTask.Podcast, NotificationState.Normal); + NotificationArea.Instance.RemoveAll(NotificationTask.Podcast, NotificationState.Completed); + NotificationArea.Instance.Add((Notification)SubscriptionEventsListener._notification); + } + SubscriptionEventsListener._notification.SubMessage = subscriptonEventArguments.SubscriptionTitle; + switch (subscriptonEventArguments.Action) + { + case SubscriptionAction.Subscribed: + if (EMediaTypes.eMediaTypePodcastSeries == subscriptonEventArguments.MediaType) + SubscriptionEventsListener._notification.Message = Shell.LoadString(StringId.IDS_PODCAST_SUBSCRIBED_NOTIFICATION); + else if (EMediaTypes.eMediaTypePlaylist == subscriptonEventArguments.MediaType) + SubscriptionEventsListener._notification.Message = Shell.LoadString(StringId.IDS_CHANNEL_SUBSCRIBED_NOTIFICATION); + SubscriptionEventsListener._notification.Type = NotificationState.OneShot; + SubscriptionEventsListener._notification = (MessageNotification)null; + break; + case SubscriptionAction.RefreshStarted: + if (EMediaTypes.eMediaTypePodcastSeries == subscriptonEventArguments.MediaType) + SubscriptionEventsListener._notification.Message = Shell.LoadString(StringId.IDS_PODCAST_REFRESH_START_NOTIFICATION); + else if (EMediaTypes.eMediaTypePlaylist == subscriptonEventArguments.MediaType) + SubscriptionEventsListener._notification.Message = Shell.LoadString(StringId.IDS_CHANNEL_REFRESH_START_NOTIFICATION); + SubscriptionEventsListener._notification.Type = NotificationState.Normal; + break; + case SubscriptionAction.RefreshFinished: + if (EMediaTypes.eMediaTypePodcastSeries == subscriptonEventArguments.MediaType) + SubscriptionEventsListener._notification.Message = Shell.LoadString(StringId.IDS_PODCAST_REFRESH_END_NOTIFICATION); + else if (EMediaTypes.eMediaTypePlaylist == subscriptonEventArguments.MediaType) + SubscriptionEventsListener._notification.Message = Shell.LoadString(StringId.IDS_CHANNEL_REFRESH_END_NOTIFICATION); + SubscriptionEventsListener._notification.Type = NotificationState.Completed; + SubscriptionEventsListener._notification = (MessageNotification)null; + break; + default: + return; + } + } + if (this.PropertyChanged != null) + this.PropertyChanged((object)this, new PropertyChangedEventArgs("SubscriptionChanged")); + if (this.SubscriptionChanged == null) + return; + this.SubscriptionChanged((object)this, new EventArgs()); + } + } +} diff --git a/ZuneUI/SubscriptionLibraryPage.cs b/ZuneUI/SubscriptionLibraryPage.cs new file mode 100644 index 0000000..50752e8 --- /dev/null +++ b/ZuneUI/SubscriptionLibraryPage.cs @@ -0,0 +1,226 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SubscriptionLibraryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Subscription; +using System; +using System.Collections; +using System.ComponentModel; +using System.Diagnostics; + +namespace ZuneUI +{ + public abstract class SubscriptionLibraryPage : LibraryPage + { + private SubscriptionSeriesPanel m_seriesPanel; + private SubscriptionEpisodePanel m_episodePanel; + private LibraryPanel m_detailsPanel; + private SubscriptionManager m_subscriptionManager; + private int m_selectedSeriesId; + private int m_selectedEpisodeId; + private Command m_seriesClicked = new Command(); + private Command m_episodeClicked = new Command(); + protected MenuItemCommand m_markAllAsPlayed; + protected MenuItemCommand m_markAllAsUnplayed; + + public SubscriptionSeriesPanel SeriesPanel + { + get => this.m_seriesPanel; + set + { + if (value == this.m_seriesPanel) + return; + this.m_seriesPanel = value; + this.FirePropertyChanged(nameof(SeriesPanel)); + } + } + + public SubscriptionEpisodePanel EpisodePanel + { + get => this.m_episodePanel; + set + { + if (value == this.m_episodePanel) + return; + this.m_episodePanel = value; + this.FirePropertyChanged(nameof(EpisodePanel)); + } + } + + public LibraryPanel DetailsPanel + { + get => this.m_detailsPanel; + set + { + if (value == this.m_detailsPanel) + return; + this.m_detailsPanel = value; + this.FirePropertyChanged(nameof(DetailsPanel)); + } + } + + public int SeriesState + { + get + { + int num = 1; + if (this.m_seriesPanel.SelectedItem is DataProviderObject selectedItem) + num = (int)selectedItem.GetProperty(nameof(SeriesState)); + return num; + } + set => this.FirePropertyChanged(nameof(SeriesState)); + } + + public SubscriptionLibraryPage(bool showDevice, MediaType mediaType) + : base(showDevice, mediaType) + { + this.UI = this.LandUI; + this.m_selectedSeriesId = -1; + this.m_selectedEpisodeId = -1; + this.m_subscriptionManager = SubscriptionManager.Instance; + } + + public MenuItemCommand MarkAllAsPlayed => this.m_markAllAsPlayed; + + public MenuItemCommand MarkAllAsUnplayed => this.m_markAllAsUnplayed; + + protected override void OnNavigatedToWorker() + { + if (this.NavigationArguments != null) + { + int num = -1; + int mediaId = -1; + if (this.NavigationArguments.Contains((object)"SeriesLibraryId")) + num = (int)this.NavigationArguments[(object)"SeriesLibraryId"]; + if (this.NavigationArguments.Contains((object)"EpisodeLibraryId")) + mediaId = (int)this.NavigationArguments[(object)"EpisodeLibraryId"]; + if (num <= 0 && mediaId > 0) + num = PlaylistManager.GetFieldValue(mediaId, this.SeriesListType, 311, -1); + this.SelectedSeriesId = num; + this.SelectedEpisodeId = mediaId; + this.NavigationArguments = (IDictionary)null; + } + base.OnNavigatedToWorker(); + } + + public override IPageState SaveAndRelease() + { + this.m_seriesPanel.Release(); + this.m_episodePanel.Release(); + this.m_seriesPanel.SelectedItem = (object)null; + this.m_episodePanel.SelectedItem = (object)null; + return base.SaveAndRelease(); + } + + public int LastSelectedSeriesIndex + { + get => ClientConfiguration.Series.PodcastLastSelectedSeriesIndex; + set => ClientConfiguration.Series.PodcastLastSelectedSeriesIndex = value; + } + + protected abstract string LandUI { get; } + + protected abstract EMediaTypes SeriesMediaType { get; } + + protected abstract EListType SeriesListType { get; } + + protected abstract StringId SubscriptionErrorStringId { get; } + + public void OpenOfficialWebSite(string link) + { + if (string.IsNullOrEmpty(link)) + return; + try + { + Uri result; + Uri.TryCreate(link, UriKind.Absolute, out result); + if (!(result != (Uri)null) || !(result.Scheme == Uri.UriSchemeHttp) && !(result.Scheme == Uri.UriSchemeHttps)) + return; + Process.Start(link); + } + catch (Win32Exception ex) + { + } + } + + public void Unsubscribe(int seriesId, bool deleteContent) + { + HRESULT hresult = (HRESULT)this.m_subscriptionManager.Unsubscribe(seriesId, this.SeriesMediaType, deleteContent); + if (hresult.IsSuccess) + this.SeriesState = 1; + else + ErrorDialogInfo.Show(hresult.Int, Shell.LoadString(this.SubscriptionErrorStringId)); + } + + public void Resubscribe(int seriesId) + { + HRESULT hresult = (HRESULT)this.m_subscriptionManager.Subscribe(seriesId, this.SeriesMediaType); + if (hresult.IsSuccess) + this.SeriesState = 0; + else + ErrorDialogInfo.Show(hresult.Int, Shell.LoadString(this.SubscriptionErrorStringId)); + } + + public SeriesSettings GetSeriesSettings(int seriesId) => new SeriesSettings(this.m_subscriptionManager, seriesId); + + public bool IsSubscribed(DataProviderObject series) + { + bool isSubscribed = false; + if (series != null) + { + string property = (string)series.GetProperty("FeedUrl"); + if (property != null) + this.m_subscriptionManager.FindByUrl(property, this.SeriesMediaType, out int _, out isSubscribed); + } + return isSubscribed; + } + + public bool IsSubscribed() => this.IsSubscribed(this.m_seriesPanel.SelectedItem as DataProviderObject); + + public static Guid GetZuneMediaId(int seriesId, EListType listType) + { + Guid guid = Guid.Empty; + if (seriesId > 0) + guid = PlaylistManager.GetFieldValue(seriesId, listType, 451, Guid.Empty); + return guid; + } + + public int SelectedSeriesId + { + get => this.m_selectedSeriesId; + set + { + if (this.m_selectedSeriesId == value) + return; + this.SelectedEpisodeId = -1; + if (this.EpisodePanel != null) + { + this.EpisodePanel.SelectedItem = (object)null; + this.EpisodePanel.SelectedLibraryIds.Clear(); + } + this.m_selectedSeriesId = value; + this.FirePropertyChanged(nameof(SelectedSeriesId)); + } + } + + public Command SeriesClicked => this.m_seriesClicked; + + public int SelectedEpisodeId + { + get => this.m_selectedEpisodeId; + set + { + if (this.m_selectedEpisodeId == value) + return; + this.m_selectedEpisodeId = value; + this.FirePropertyChanged(nameof(SelectedEpisodeId)); + } + } + + public Command EpisodeClicked => this.m_episodeClicked; + } +} diff --git a/ZuneUI/SubscriptionSeriesPanel.cs b/ZuneUI/SubscriptionSeriesPanel.cs new file mode 100644 index 0000000..eb7fe18 --- /dev/null +++ b/ZuneUI/SubscriptionSeriesPanel.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SubscriptionSeriesPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class SubscriptionSeriesPanel : ListPanel + { + public SubscriptionSeriesPanel(SubscriptionLibraryPage page) + : base((IModelItemOwner)page) + { + } + } +} diff --git a/ZuneUI/SubscriptionState.cs b/ZuneUI/SubscriptionState.cs new file mode 100644 index 0000000..9da2a24 --- /dev/null +++ b/ZuneUI/SubscriptionState.cs @@ -0,0 +1,67 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SubscriptionState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class SubscriptionState : ModelItem + { + private bool _isSubscribed; + private bool _seriesFound; + private int _seriesId; + + public SubscriptionState(bool isSubscribed, bool seriesFound, int seriesId) + { + this._seriesFound = seriesFound; + this._isSubscribed = isSubscribed; + this._seriesId = seriesId; + } + + public SubscriptionState() + { + this._seriesFound = false; + this._isSubscribed = false; + this._seriesId = -1; + } + + public bool IsSubscribed + { + get => this._isSubscribed; + set + { + if (this._isSubscribed == value) + return; + this._isSubscribed = value; + this.FirePropertyChanged(nameof(IsSubscribed)); + } + } + + public bool SeriesFound + { + get => this._seriesFound; + set + { + if (this._seriesFound == value) + return; + this._seriesFound = value; + this.FirePropertyChanged(nameof(SeriesFound)); + } + } + + public int SeriesId + { + get => this._seriesId; + set + { + if (this._seriesId == value) + return; + this._seriesId = value; + this.FirePropertyChanged(nameof(SeriesId)); + } + } + } +} diff --git a/ZuneUI/SyncCategory.cs b/ZuneUI/SyncCategory.cs new file mode 100644 index 0000000..c881a40 --- /dev/null +++ b/ZuneUI/SyncCategory.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncCategory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum SyncCategory + { + Undefined = -1, // 0xFFFFFFFF + Music = 0, + Video = 1, + Photo = 2, + Podcast = 3, + Friend = 4, + Audiobook = 5, + Channel = 6, + Application = 7, + Guest = 8, + } +} diff --git a/ZuneUI/SyncCommandBase.cs b/ZuneUI/SyncCommandBase.cs new file mode 100644 index 0000000..c3eb9e0 --- /dev/null +++ b/ZuneUI/SyncCommandBase.cs @@ -0,0 +1,49 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncCommandBase +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.ComponentModel; + +namespace ZuneUI +{ + public class SyncCommandBase : Command + { + private UIDevice _device; + protected bool _availableWhenSyncing; + + public UIDevice Device + { + get => this._device; + set + { + if (this._device == value) + return; + if (this._device != null) + this._device.PropertyChanged -= new PropertyChangedEventHandler(this.OnDevicePropertyChanged); + this._device = value; + if (this._device != null) + this._device.PropertyChanged += new PropertyChangedEventHandler(this.OnDevicePropertyChanged); + this.UpdateAvailability(); + this.FirePropertyChanged(nameof(Device)); + } + } + + private void OnDevicePropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "IsReadyForSync") && !(args.PropertyName == "IsSyncing")) + return; + this.UpdateAvailability(); + } + + protected override void OnInvoked() + { + this.Available = false; + base.OnInvoked(); + } + + private void UpdateAvailability() => this.Available = this.Device != null && this.Device.IsReadyForSync && this.Device.IsSyncing == this._availableWhenSyncing; + } +} diff --git a/ZuneUI/SyncCompletedNotification.cs b/ZuneUI/SyncCompletedNotification.cs new file mode 100644 index 0000000..a363bf1 --- /dev/null +++ b/ZuneUI/SyncCompletedNotification.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncCompletedNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class SyncCompletedNotification : MessageNotification + { + private int _count; + private string _pluralMessage; + private string _deviceName; + + public SyncCompletedNotification( + string message, + string pluralMessage, + int count, + string deviceName) + : base(message, NotificationTask.Sync, NotificationState.OneShot) + { + this._pluralMessage = pluralMessage; + this._count = count; + this._deviceName = deviceName; + } + + public string PluralMessage => this._pluralMessage; + + public int Count => this._count; + + public string DeviceName => this._deviceName; + } +} diff --git a/ZuneUI/SyncControls.cs b/ZuneUI/SyncControls.cs new file mode 100644 index 0000000..e34f841 --- /dev/null +++ b/ZuneUI/SyncControls.cs @@ -0,0 +1,568 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncControls +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using UIXControls; + +namespace ZuneUI +{ + public class SyncControls : ModelItem + { + private UIDeviceList _deviceList; + private UIDevice _currentDevice; + private UIDevice _deferredArrivalDevice; + private string _canonicalNameToMakeActive; + private bool _changeIntoSetupDevice; + private Command _deviceSignInFailureEvent; + private Queue _failedSignInQueue; + private DownloadTaskList _downloadTasks; + private bool _haveSeenDownloadsOngoing; + private MessageBox _currentUnlinkedDeviceDialog; + private bool _showSyncInstructionsToast; + private bool _displayWirelessSyncBanner; + private static string _sizeInKB = ZuneUI.Shell.LoadString(StringId.IDS_GAS_GAUGE_SIZE_IN_KB); + private static string _sizeInMB = ZuneUI.Shell.LoadString(StringId.IDS_GAS_GAUGE_SIZE_IN_MB); + private static string _sizeInGB = ZuneUI.Shell.LoadString(StringId.IDS_GAS_GAUGE_SIZE_IN_GB); + private static long _devicelandKilobyte = 1024; + private static long _devicelandMegabyte = SyncControls.DevicelandKilobyte * SyncControls.DevicelandKilobyte; + private static long _devicelandGigabyte = SyncControls.DevicelandMegabyte * SyncControls.DevicelandKilobyte; + private static SyncControls s_singletonInstance; + private static string _unlinkedDeviceNagDialogTitle = ZuneUI.Shell.LoadString(StringId.IDS_DIALOG_TITLE_LINK_TO_SYNC_FRIENDS); + private static string _unlinkedDeviceNagDialogMessageBase = ZuneUI.Shell.LoadString(StringId.IDS_DIALOG_TEXT_LINK_TO_SYNC_FRIENDS); + + private SyncControls(IModelItemOwner owner) + : base(owner) + { + this._deviceList = SingletonModelItem.Instance; + this._deviceList.DeviceAddedEvent += new DeviceListEventHandler(this.OnDeviceAdded); + this._deviceList.DeviceRemovedEvent += new DeviceListEventHandler(this.OnDeviceRemoved); + this._deviceList.DeviceConnectedEvent += new DeviceListEventHandler(this.OnDeviceConnected); + this._deviceList.DeviceDisconnectedEvent += new DeviceListEventHandler(this.OnDeviceDisconnected); + this._currentDevice = UIDeviceList.NullDevice; + SignIn.Instance.PropertyChanged += new PropertyChangedEventHandler(this.SignInPropertyChanged); + AccountCreationWizard.CreationCompleted += new EventHandler(this.AccountCreationFinished); + DeviceManagement.DeviceConnectionHandled += new DeviceConnectionHandledEventHandler(this.OnDeviceConnectionHandled); + this.UpdateWirelessSyncBannerDisplay(); + } + + protected override void OnDispose(bool fDisposing) + { + if (fDisposing) + { + if (this._deviceList != null) + { + this._deviceList.DeviceAddedEvent -= new DeviceListEventHandler(this.OnDeviceAdded); + this._deviceList.DeviceRemovedEvent -= new DeviceListEventHandler(this.OnDeviceRemoved); + this._deviceList.DeviceConnectedEvent -= new DeviceListEventHandler(this.OnDeviceConnected); + this._deviceList.DeviceDisconnectedEvent -= new DeviceListEventHandler(this.OnDeviceDisconnected); + this._deviceList = (UIDeviceList)null; + } + if (this._downloadTasks != null) + { + this._downloadTasks.ActiveDownloads.PropertyChanged -= new PropertyChangedEventHandler(this.OnDownloadPropertyChanged); + this._downloadTasks = (DownloadTaskList)null; + } + SignIn.Instance.PropertyChanged -= new PropertyChangedEventHandler(this.SignInPropertyChanged); + AccountCreationWizard.CreationCompleted -= new EventHandler(this.AccountCreationFinished); + DeviceManagement.DeviceConnectionHandled -= new DeviceConnectionHandledEventHandler(this.OnDeviceConnectionHandled); + } + base.OnDispose(fDisposing); + } + + public bool ShowPhoneWelcomeMessage + { + get => ClientConfiguration.FUE.ShowPhoneFUEDeviceLandOptions; + set + { + if (ClientConfiguration.FUE.ShowPhoneFUEDeviceLandOptions == value) + return; + ClientConfiguration.FUE.ShowPhoneFUEDeviceLandOptions = value; + this.FirePropertyChanged(nameof(ShowPhoneWelcomeMessage)); + } + } + + public bool ShowSyncInstructionsToast + { + get => this._showSyncInstructionsToast; + set + { + if (this._showSyncInstructionsToast == value) + return; + if (this.CurrentDevice.Class == DeviceClass.Classic || this.CurrentDevice.Class == DeviceClass.ZuneHD) + { + bool flag = value && ClientConfiguration.Devices.ShowSyncInstructionsToast; + value = flag; + ClientConfiguration.Devices.ShowSyncInstructionsToast = flag; + } + this._showSyncInstructionsToast = value; + this.FirePropertyChanged(nameof(ShowSyncInstructionsToast)); + } + } + + public bool DisplayWirelessSyncBanner + { + get => this._displayWirelessSyncBanner && !this.CurrentDevice.IsWirelessSyncEnabled; + set + { + if (this._displayWirelessSyncBanner == value) + return; + this._displayWirelessSyncBanner = value; + this.FirePropertyChanged(nameof(DisplayWirelessSyncBanner)); + } + } + + public UIDevice CurrentDevice + { + get => this._currentDevice ?? UIDeviceList.NullDevice; + private set + { + if (this._currentDevice == value) + return; + this._currentDevice = value ?? UIDeviceList.NullDevice; + PhoneBrandingStringMap.Instance.BrandingEnabled = this._currentDevice != null && this._currentDevice.SupportsBrandingType(DeviceBranding.WindowsPhone); + KinBrandingStringMap.Instance.BrandingEnabled = this._currentDevice != null && this._currentDevice.SupportsBrandingType(DeviceBranding.Kin); + this.FirePropertyChanged(nameof(CurrentDevice)); + } + } + + public UIDevice CurrentDeviceOverride => DeviceManagement.SetupDevice ?? this.CurrentDevice; + + public bool ChangeIntoSetupDevice + { + get => this._changeIntoSetupDevice; + set + { + if (this._changeIntoSetupDevice == value) + return; + this._changeIntoSetupDevice = value; + this.FirePropertyChanged(nameof(ChangeIntoSetupDevice)); + } + } + + public Command DeviceSignInFailureEvent + { + get + { + if (this._deviceSignInFailureEvent == null) + this._deviceSignInFailureEvent = new Command((IModelItemOwner)this); + return this._deviceSignInFailureEvent; + } + } + + public Queue FailedSignInDevices + { + get + { + if (this._failedSignInQueue == null) + this._failedSignInQueue = new Queue(); + return this._failedSignInQueue; + } + } + + public UIDevice CurrentFailedSignInDevice + { + get + { + try + { + return this.FailedSignInDevices.Peek(); + } + catch (InvalidOperationException ex) + { + return UIDeviceList.NullDevice; + } + } + } + + public void SetCurrentDevice(UIDevice device) + { + if (device == null) + device = UIDeviceList.NullDevice; + if (this._canonicalNameToMakeActive != null && device.CanonicalName != null && device.CanonicalName.StartsWith(this._canonicalNameToMakeActive)) + { + this._canonicalNameToMakeActive = (string)null; + if ((!(ZuneShell.DefaultInstance.CurrentPage is QuickplayPage) || !ClientConfiguration.FUE.ShowArtistChooser) && (ZuneShell.DefaultInstance.Management.CurrentCategoryPage == null || !ZuneShell.DefaultInstance.Management.CurrentCategoryPage.IsWizard)) + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)new Deviceland()); + } + if (device == this.CurrentDevice) + return; + Management management = (Management)null; + CategoryPage categoryPage = (CategoryPage)null; + if (ZuneShell.DefaultInstance != null) + management = ZuneShell.DefaultInstance.Management; + if (management != null) + categoryPage = management.CurrentCategoryPage; + categoryPage?.RestartSyncIfNecessary(); + this.CurrentDevice = device; + ClientConfiguration.Devices.CurrentDeviceID = this.CurrentDevice.ID; + categoryPage?.PauseSyncIfNecessary(); + management?.DisposeDeviceManagement(false); + } + + public void Phase3Init() + { + this._downloadTasks = DownloadTaskList.Instance; + this._downloadTasks.ActiveDownloads.PropertyChanged += new PropertyChangedEventHandler(this.OnDownloadPropertyChanged); + this._haveSeenDownloadsOngoing = this._downloadTasks.ActiveDownloads.Count > 0; + } + + public void SetCurrentDeviceByCanonicalName(string canonicalName) + { + this._canonicalNameToMakeActive = canonicalName.ToLower(); + if (this._deviceList == null) + return; + foreach (UIDevice device in this._deviceList) + { + if (device.IsConnectedToClient && device.CanonicalName.StartsWith(this._canonicalNameToMakeActive)) + { + this.SetCurrentDevice(device); + break; + } + } + } + + public void SetCurrentDeviceIfNecessary(UIDevice device, bool comingOutOfFirstConnect) + { + if (!device.IsConnectedToClientPhysically) + return; + this.SetCurrentDevice(device); + if (comingOutOfFirstConnect) + return; + this.ShowUnlinkedDeviceNagDialogIfNecessary(); + } + + public UIDevice FindNewActiveDevice() => this.FindNewActiveDevice((UIDevice)null); + + public UIDevice FindNewActiveDevice(UIDevice excludedDevice) + { + foreach (UIDevice device in this._deviceList) + { + if (device != excludedDevice) + return device; + } + return (UIDevice)null; + } + + public void DeleteCurrentDevice() + { + if (!this.CurrentDevice.IsValid) + return; + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_DELETE_DIALOG_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_DELETE_DIALOG_TEXT), new EventHandler(this.ConfirmedDeleteDevice)); + } + + private void ConfirmedDeleteDevice(object sender, EventArgs e) + { + if (this.CurrentDevice.IsGuest || !this.CurrentDevice.SupportsWirelessSetupMethod1 && !this.CurrentDevice.SupportsWirelessSetupMethod2) + this.DeleteCurrentDeviceWorker(); + else + WirelessSync.Instance.ClearWirelessOnDeviceForForget(); + } + + public void DeleteCurrentDeviceWorker() + { + if (this.CurrentDevice == null) + return; + string message = this.CurrentDevice.SupportsBrandingType(DeviceBranding.WindowsPhone) ? ZuneUI.Shell.LoadString(StringId.IDS_PHONE_FORGET_DEVICE_DIALOG_CONTENT) : ZuneUI.Shell.LoadString(StringId.IDS_FORGET_DEVICE_DIALOG_CONTENT); + ZuneShell.DefaultInstance.Management.CommitList.RemoveByIntValue(this.CurrentDevice.ID); + HRESULT hresult = this._deviceList.DeleteDevice(this.CurrentDevice); + if (hresult.IsError) + ZuneUI.Shell.ShowErrorDialog(hresult.Int, StringId.IDS_DELETE_DEVICE_FAILED); + else + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_FORGET_DEVICE_DIALOG_TITLE), message, (EventHandler)null); + } + + public void PromptForAccountLinkage() => this.ShowUnlinkedDeviceNagDialog(false); + + public void HideWirelessSyncBanner() + { + ClientConfiguration.Devices.ConnectionsUntilWirelessSyncBannerDisplay = -1; + this.UpdateWirelessSyncBannerDisplay(); + } + + public void AddDeviceToFailedSignInQueue(UIDevice device) + { + device.IsLockedAgainstSyncing = true; + this.FailedSignInDevices.Enqueue(device); + if (this.FailedSignInDevices.Count != 1) + return; + this.ShowFailedSignInMessageBox(); + } + + public void HandleFailedSignInDevice(string username, string password) + { + this.CurrentFailedSignInDevice.SendMarketplaceCredentials(username, password); + this.IgnoreFailedSignInDevice(); + } + + public void IgnoreFailedSignInDevice() + { + try + { + UIDevice uiDevice = this.FailedSignInDevices.Dequeue(); + uiDevice.IsLockedAgainstSyncing = false; + uiDevice.BeginSync(); + } + catch (InvalidOperationException ex) + { + } + if (this.FailedSignInDevices.Count <= 0) + return; + this.ShowFailedSignInMessageBox(); + } + + public void HandleFailedSignInDeviceGuidMismatch() + { + string message = string.IsNullOrEmpty(this.CurrentFailedSignInDevice.ZuneTag) ? string.Format(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_CREDS_GUID_MISMATCH_TEXT_UNKNONW_ZUNETAG), (object)this.CurrentFailedSignInDevice.Name, (object)SignIn.Instance.ZuneTag) : string.Format(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_CREDS_GUID_MISMATCH_TEXT), (object)this.CurrentFailedSignInDevice.Name, (object)this.CurrentFailedSignInDevice.ZuneTag, (object)SignIn.Instance.ZuneTag); + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_CREDS_GUID_MISMATCH_TITLE), message, new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_ENTER_CREDENTIALS), (EventHandler)delegate + { + this.DeviceSignInFailureEvent.Invoke(); + }), (string)null, (EventHandler)delegate + { + this.IgnoreFailedSignInDevice(); + }, true); + } + + private void ShowFailedSignInMessageBox() + { + string message = string.IsNullOrEmpty(this.CurrentFailedSignInDevice.ZuneTag) ? string.Format(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_SIGN_IN_FAILURE_TEXT_UNKNONW_ZUNETAG), (object)this.CurrentFailedSignInDevice.Name) : string.Format(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_SIGN_IN_FAILURE_TEXT), (object)this.CurrentFailedSignInDevice.Name, (object)this.CurrentFailedSignInDevice.ZuneTag); + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_SIGN_IN_FAILURE_TITLE), message, new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_ENTER_CREDENTIALS), (EventHandler)delegate + { + this.DeviceSignInFailureEvent.Invoke(); + }), (string)null, (EventHandler)delegate + { + this.IgnoreFailedSignInDevice(); + }, true); + } + + private void OnFUECompleted(object sender, EventArgs args) + { + Fue.FUECompleted -= new EventHandler(this.OnFUECompleted); + if (this._deferredArrivalDevice != null) + this.OnDeviceConnected((object)null, new DeviceListEventArgs(this._deferredArrivalDevice)); + this._deferredArrivalDevice = (UIDevice)null; + } + + private void OnDeviceConnected(object sender, DeviceListEventArgs args) + { + if (args.Device.SupportsBrandingType(DeviceBranding.WindowsPhone) && ZuneApplication.IsDesktopLocked && !args.Device.IsConnectedToClientWirelessly) + SingletonModelItem.Instance.HideDevice(args.Device); + else if (Fue.Instance.IsFirstLaunch) + { + if (ZuneApplication.InstallContext != SetupInstallContext.Zune && args.Device.SupportsBrandingType(DeviceBranding.WindowsPhone) && !args.Device.RequiresAutoRestore) + return; + this._deferredArrivalDevice = args.Device; + Fue.FUECompleted += new EventHandler(this.OnFUECompleted); + } + else + { + DeviceManagement.SetupQueue[(object)args.Device.ID] = (object)args.Device; + if (ClientConfiguration.Devices.ConnectionsUntilWirelessSyncBannerDisplay > 0) + --ClientConfiguration.Devices.ConnectionsUntilWirelessSyncBannerDisplay; + this.UpdateWirelessSyncBannerDisplay(); + } + } + + private void OnDeviceDisconnected(object sender, DeviceListEventArgs args) + { + if (this._deferredArrivalDevice == args.Device) + { + this._deferredArrivalDevice = (UIDevice)null; + Fue.FUECompleted -= new EventHandler(this.OnFUECompleted); + } + else + { + if (args.Device == this.CurrentDevice) + { + ZuneShell.DefaultInstance.Management.DisposeDeviceManagement(false); + this.HideUnlinkedDeviceNagDialog(); + foreach (UIDevice device in this._deviceList) + { + if (device != args.Device && device.IsConnectedToClientPhysically) + { + this.SetCurrentDevice(device); + break; + } + } + } + if (DeviceManagement.SetupDevice != args.Device) + return; + ZuneShell.DefaultInstance.Management.AlertedDeviceCategory = (Category)null; + } + } + + private void OnDeviceAdded(object sender, DeviceListEventArgs args) + { + if (args.Device.ID != ClientConfiguration.Devices.CurrentDeviceID && ClientConfiguration.Devices.CurrentDeviceID != 0 && (this.CurrentDevice.IsConnectedToClient || !args.Device.IsConnectedToClient)) + return; + this.SetCurrentDevice(args.Device); + } + + private void OnDeviceRemoved(object sender, DeviceListEventArgs args) + { + if (args.Device != this.CurrentDevice) + return; + this.SetCurrentDevice(this.FindNewActiveDevice(this.CurrentDevice)); + } + + private void OnDeviceConnectionHandled(object sender, DeviceConnectionHandledEventArgs args) + { + if (!args.IsFirstConnect) + return; + ClientConfiguration.Devices.ConnectionsUntilWirelessSyncBannerDisplay = 1; + this.UpdateWirelessSyncBannerDisplay(); + } + + private void UpdateWirelessSyncBannerDisplay() => this.DisplayWirelessSyncBanner = ClientConfiguration.Devices.ConnectionsUntilWirelessSyncBannerDisplay == 0; + + private void OnDownloadPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "Count")) + return; + if (this._downloadTasks.ActiveDownloads.Count > 0) + { + this._haveSeenDownloadsOngoing = true; + } + else + { + if (!this._haveSeenDownloadsOngoing) + return; + foreach (UIDevice device in this._deviceList) + { + if (device.IsConnectedToClient) + device.BeginSync(true, true); + } + this._haveSeenDownloadsOngoing = false; + } + } + + private void SignInPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "SignedIn") || !SignIn.Instance.SignedIn) + return; + this.ShowUnlinkedDeviceNagDialogIfNecessary(); + } + + private void AccountCreationFinished(object sender, EventArgs args) => this.ShowUnlinkedDeviceNagDialogIfNecessary(); + + private void ShowUnlinkedDeviceNagDialogIfNecessary() + { + if (!this.CurrentDevice.PromptForAccountLinkage || this.CurrentDevice.IsGuest || (this.CurrentDevice.UserId != 0 || !this.CurrentDevice.IsConnectedToClientPhysically) || (!this.CurrentDevice.SupportsZuneTagLinking || !SignIn.Instance.SignedIn || (AccountCreationWizard.AccountCreationInProgress || ZuneShell.DefaultInstance.CurrentPage is DialogPage))) + return; + this.ShowUnlinkedDeviceNagDialog(true); + } + + private void ShowUnlinkedDeviceNagDialog(bool allowUserToOptOut) + { + if (!SettingsExperience.ShouldShowDeviceMarketplaceCategory) + return; + this.HideUnlinkedDeviceNagDialog(); + SQMLog.Log(SQMDataId.UnlinkedDeviceNagDialogShow, 1); + UIDevice device = this.CurrentDevice; + BooleanChoice optOutChoice = (BooleanChoice)null; + Command okCommand = new Command((IModelItemOwner)this, DialogHelper.DialogYes, (EventHandler)delegate + { + SQMLog.Log(SQMDataId.UnlinkedDeviceNagDialogYes, 1); + ZuneUI.Shell.SettingsFrame.Settings.Device.Invoke(SettingCategories.DeviceMarketplace); + }); + EventHandler cancelCommand = (EventHandler)delegate + { + SQMLog.Log(SQMDataId.UnlinkedDeviceNagDialogNo, 1); + if (optOutChoice == null || optOutChoice.Value) + return; + SQMLog.Log(SQMDataId.UnlinkedDeviceNagDialogNoShow, 1); + }; + if (allowUserToOptOut) + { + optOutChoice = new BooleanChoice(); + optOutChoice.Value = !device.PromptForAccountLinkage; + optOutChoice.ChosenChanged += (EventHandler)delegate + { + device.PromptForAccountLinkage = !optOutChoice.Value; + }; + optOutChoice.Description = ZuneUI.Shell.LoadString(StringId.IDS_DONT_SHOW_THIS_MESSAGE_AGAIN); + } + this._currentUnlinkedDeviceDialog = MessageBox.Show(SyncControls._unlinkedDeviceNagDialogTitle, string.Format(SyncControls._unlinkedDeviceNagDialogMessageBase, (object)device.Name), DialogHelper.DialogNo, true, okCommand, (Command)null, (Command)null, cancelCommand, optOutChoice); + } + + private void HideUnlinkedDeviceNagDialog() + { + if (this._currentUnlinkedDeviceDialog == null || this._currentUnlinkedDeviceDialog.WouldLikeToBeHidden) + return; + this._currentUnlinkedDeviceDialog.Hide(); + } + + public static int ConvertSyncOperationToInt(ESyncOperation operation) => (int)operation; + + public static int ConvertSyncStateToInt(ESyncState state) => (int)state; + + public static int ConvertSyncStatusToInt(TrackSyncStatus status) => (int)status; + + public static int GetGasGaugeSegmentWidth( + int maxWidth, + long size, + long totalSize, + int margins) + { + totalSize = Math.Max(totalSize, 1L); + size = Math.Max(size, 0L); + return Math.Max((int)Math.Min((long)maxWidth * size / totalSize, (long)(maxWidth - margins)), 0); + } + + public static long DevicelandKilobyte => SyncControls._devicelandKilobyte; + + public static long DevicelandMegabyte => SyncControls._devicelandMegabyte; + + public static long DevicelandGigabyte => SyncControls._devicelandGigabyte; + + public static string FormatLongAsSize(long sizeInBytes) + { + if (sizeInBytes < SyncControls.DevicelandMegabyte && sizeInBytes != 0L) + return string.Format(SyncControls._sizeInKB, (object)(float)((double)sizeInBytes / (double)SyncControls.DevicelandKilobyte)); + return sizeInBytes < SyncControls.DevicelandGigabyte ? string.Format(SyncControls._sizeInMB, (object)(float)((double)sizeInBytes / (double)SyncControls.DevicelandMegabyte)) : string.Format(SyncControls._sizeInGB, (object)(float)((double)sizeInBytes / (double)SyncControls.DevicelandGigabyte)); + } + + public void BrowseAndReplaceMedia(IList items, int mediaType) => FileOpenDialog.Show(ZuneUI.Shell.LoadString(StringId.IDS_OPEN_FILE_DIALOG_TITLE), ZuneShell.DefaultInstance.Management.MediaFolder, (DeferredInvokeHandler)(args => + { + string path = (string)args; + if (string.IsNullOrEmpty(path)) + return; + ZuneUI.Shell.DeleteMedia(items, false); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + try + { + if (!ZuneApplication.ZuneLibrary.CanAddMedia(path, (EMediaTypes)mediaType)) + return; + ZuneApplication.ZuneLibrary.AddMedia(path); + } + catch (UnauthorizedAccessException ex) + { + } + catch (IOException ex) + { + } + }, (object)null); + })); + + public static SyncControls Instance + { + get + { + if (SyncControls.s_singletonInstance == null) + SyncControls.s_singletonInstance = new SyncControls((IModelItemOwner)ZuneShell.DefaultInstance); + return SyncControls.s_singletonInstance; + } + } + } +} diff --git a/ZuneUI/SyncErrorHelper.cs b/ZuneUI/SyncErrorHelper.cs new file mode 100644 index 0000000..a8d8ce4 --- /dev/null +++ b/ZuneUI/SyncErrorHelper.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncErrorHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public static class SyncErrorHelper + { + public static Guid GetMediaGuidForLibraryId(int id, MediaType type) + { + if (type == MediaType.PodcastEpisode) + id = PlaylistManager.GetFieldValue(id, PlaylistManager.MediaTypeToListType(type), 311, 0); + return PlaylistManager.GetFieldValue(id, PlaylistManager.MediaTypeToListType(type), 451, Guid.Empty); + } + + public static string GetEpisodeUrlForLibraryId(int id) => PlaylistManager.GetFieldValue(id, PlaylistManager.MediaTypeToListType(MediaType.PodcastEpisode), 317, string.Empty); + } +} diff --git a/ZuneUI/SyncGroup.cs b/ZuneUI/SyncGroup.cs new file mode 100644 index 0000000..6ebe850 --- /dev/null +++ b/ZuneUI/SyncGroup.cs @@ -0,0 +1,78 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncGroup +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public abstract class SyncGroup : ModelItem, IComparable, IComparable + { + private SyncGroupList _parentList; + + public SyncGroup(SyncGroupList parentList) + : base((IModelItemOwner)parentList) + => this._parentList = parentList; + + public abstract string Title { get; } + + public abstract int ID { get; } + + public abstract SyncCategory Type { get; } + + public abstract long Size { get; } + + public abstract int Count { get; } + + public abstract SyncGroupState State { get; } + + public abstract bool IsActive { get; set; } + + public abstract bool IsVisible { get; } + + public abstract bool IsComplex { get; } + + public abstract void CommitChanges(); + + public abstract void CancelChanges(); + + public abstract void DataUpdated(); + + public abstract void DataEdited(); + + public string TypeAsGroupDescription + { + get + { + switch (this.Type) + { + case SyncCategory.Music: + return Shell.LoadString(StringId.IDS_SONGS); + case SyncCategory.Video: + return Shell.LoadString(StringId.IDS_VIDEOS); + case SyncCategory.Photo: + return Shell.LoadString(StringId.IDS_PICTURES); + case SyncCategory.Podcast: + return Shell.LoadString(StringId.IDS_PODCAST_EPISODES); + case SyncCategory.Friend: + return Shell.LoadString(StringId.IDS_FRIENDS); + case SyncCategory.Channel: + return Shell.LoadString(StringId.IDS_CHANNELS); + case SyncCategory.Application: + return Shell.LoadString(StringId.IDS_APPLICATIONS); + default: + return Shell.LoadString(StringId.IDS_GENERIC_ERROR); + } + } + } + + public int CompareTo(object obj) => !(obj is SyncGroup other) ? 0 : this.CompareTo(other); + + public int CompareTo(SyncGroup other) => this.Size.CompareTo(other.Size) * -1; + + protected SyncGroupList ParentList => this._parentList; + } +} diff --git a/ZuneUI/SyncGroupList.cs b/ZuneUI/SyncGroupList.cs new file mode 100644 index 0000000..64f5ed9 --- /dev/null +++ b/ZuneUI/SyncGroupList.cs @@ -0,0 +1,313 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncGroupList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using UIXControls; + +namespace ZuneUI +{ + public class SyncGroupList : ModelItem + { + private UIDevice _device; + private SyncRulesView _snapshot; + private bool _inOverfill; + private bool _inManagement; + private UIGasGauge _gauge; + private Dictionary _existingRulesList; + private Dictionary _complexRulesList; + private ProxySettingDelegate _commitDelegate; + private bool _committed; + private SchemaSyncGroup _music; + private SchemaSyncGroup _video; + private SchemaSyncGroup _photo; + private SchemaSyncGroup _podcast; + private SchemaSyncGroup _friend; + private SchemaSyncGroup _channel; + private SchemaSyncGroup _application; + private SchemaSyncGroup _audiobook; + private SchemaSyncGroup _guest; + private System.Collections.Generic.List _schemas; + + public SyncGroupList( + IModelItemOwner parent, + UIDevice device, + SyncRulesView snapshot, + bool inOverfill) + : base(parent) + { + this._device = device; + this._snapshot = snapshot; + this._inOverfill = inOverfill; + this._inManagement = parent is DeviceManagement; + this._commitDelegate = new ProxySettingDelegate(this.CommitChanges); + this._gauge = this._snapshot == null ? new UIGasGauge((IModelItemOwner)this, (MicrosoftZuneLibrary.GasGauge)null) : new UIGasGauge((IModelItemOwner)this, this._snapshot.PredictedGasGauge); + this._existingRulesList = new Dictionary((IEqualityComparer)new SyncGroupList.SyncRuleDetailsHasher()); + this._complexRulesList = new Dictionary(); + this._schemas = new System.Collections.Generic.List(8); + this._music = (SchemaSyncGroup)new DetailsBackedSchemaSyncGroup(this, this._snapshot, SyncCategory.Music, this._inOverfill); + this._schemas.Add(this._music); + this._video = (SchemaSyncGroup)new DetailsBackedSchemaSyncGroup(this, this._snapshot, SyncCategory.Video, this._inOverfill); + this._schemas.Add(this._video); + this._photo = (SchemaSyncGroup)new DetailsBackedSchemaSyncGroup(this, this._snapshot, SyncCategory.Photo, this._inOverfill); + this._schemas.Add(this._photo); + this._podcast = (SchemaSyncGroup)new DetailsBackedSchemaSyncGroup(this, this._snapshot, SyncCategory.Podcast, this._inOverfill); + this._schemas.Add(this._podcast); + if (this.Device.UserId != 0) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eSocial) && device.SupportsUserCards) + { + this._friend = (SchemaSyncGroup)new DetailsBackedSchemaSyncGroup(this, this._snapshot, SyncCategory.Friend, this._inOverfill); + this._schemas.Add(this._friend); + } + if (FeatureEnablement.IsFeatureEnabled(Features.eChannels) && device.SupportsChannels) + { + this._channel = (SchemaSyncGroup)new DetailsBackedSchemaSyncGroup(this, this._snapshot, SyncCategory.Channel, this._inOverfill); + this._schemas.Add(this._channel); + } + } + if (FeatureEnablement.IsFeatureEnabled(Features.eGames) && this.Device.SupportsSyncApplications) + { + this._application = (SchemaSyncGroup)new DetailsBackedSchemaSyncGroup(this, this._snapshot, SyncCategory.Application, this._inOverfill); + this._schemas.Add(this._application); + } + if (this.InOverfill) + { + this._guest = (SchemaSyncGroup)new GuestSchemaSyncGroup(this, this.GasGauge.GuestSpace); + this._audiobook = (SchemaSyncGroup)new DetailsBackedSchemaSyncGroup(this, this._snapshot, SyncCategory.Audiobook, this._inOverfill); + this._schemas.Add(this._audiobook); + } + if (this._snapshot == null) + return; + this._snapshot.ItemAddedEvent += new SyncRulesViewItemAddedHandler(this.ItemAdded); + this._snapshot.ItemUpdatedEvent += new SyncRulesViewItemUpdatedHandler(this.ItemUpdated); + if (this._snapshot.Count <= 0) + return; + for (int indexInRulesSnapshot = 0; indexInRulesSnapshot < this._snapshot.Count; ++indexInRulesSnapshot) + this.AddExistingSyncGroup(indexInRulesSnapshot); + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + if (this._snapshot != null) + { + this._snapshot.ItemAddedEvent -= new SyncRulesViewItemAddedHandler(this.ItemAdded); + this._snapshot.ItemUpdatedEvent -= new SyncRulesViewItemUpdatedHandler(this.ItemUpdated); + this._snapshot.Dispose(); + } + if (!this._committed) + { + if (this._inManagement) + ZuneShell.DefaultInstance.Management.CommitList.Remove((object)this._commitDelegate); + this.CancelChanges(); + } + } + base.OnDispose(disposing); + } + + public UIDevice Device => this._device; + + public bool InOverfill => this._inOverfill; + + public System.Collections.Generic.List List + { + get => this._schemas; + private set + { + if (this._schemas == value) + return; + this._schemas = value; + this.FirePropertyChanged(nameof(List)); + } + } + + public UIGasGauge GasGauge => this._gauge; + + public SchemaSyncGroup GetGroupForSchema(SyncCategory schema) + { + switch (schema) + { + case SyncCategory.Music: + return this._music; + case SyncCategory.Video: + return this._video; + case SyncCategory.Photo: + return this._photo; + case SyncCategory.Podcast: + return this._podcast; + case SyncCategory.Friend: + return this._friend; + case SyncCategory.Audiobook: + return this._audiobook; + case SyncCategory.Channel: + return this._channel; + case SyncCategory.Application: + return this._application; + case SyncCategory.Guest: + return this._guest; + default: + return (SchemaSyncGroup)null; + } + } + + public void AddNewComplexSyncGroup(int playlistID) + { + NewComplexSyncGroup complexSyncGroup = new NewComplexSyncGroup(this, playlistID); + this.AddSyncGroup((SyncGroup)complexSyncGroup); + if (this.GetGroupForSchema(complexSyncGroup.Type) is DetailsBackedSchemaSyncGroup groupForSchema) + groupForSchema.IsExpanded = true; + if (!this._inManagement) + return; + ZuneShell.DefaultInstance.Management.CommitList[(object)this._commitDelegate] = (object)this._device.ID; + } + + public void DeleteGroup(SyncGroup group) => this.DeleteGroups((IList)new SyncGroup[1] + { + group + }); + + public void DeleteGroups(IList groupList) + { + if (groupList == null || groupList.Count < 1) + return; + if (groupList.Count == 1) + { + MessageBox.Show(Shell.LoadString(StringId.IDS_REMOVE_SYNC_GROUP_DIALOG_TITLE), string.Format(Shell.LoadString(StringId.IDS_REMOVE_SINGLE_SYNC_GROUP_DIALOG_TEXT), (object)((SyncGroup)groupList[0]).Title), (EventHandler)delegate + { + this.DeleteGroupsConfirmed(groupList); + }); + } + else + { + if (groupList.Count <= 1) + return; + MessageBox.Show(Shell.LoadString(StringId.IDS_REMOVE_SYNC_GROUP_DIALOG_TITLE), Shell.LoadString(StringId.IDS_REMOVE_MULTIPLE_SYNC_GROUP_DIALOG_TEXT), (EventHandler)delegate + { + this.DeleteGroupsConfirmed(groupList); + }); + } + } + + private void DeleteGroupsConfirmed(IList groupList) + { + if (groupList == null) + return; + System.Collections.Generic.List syncCategoryList = new System.Collections.Generic.List(); + foreach (object group in (IEnumerable)groupList) + { + if (group is SyncGroup syncGroup) + { + syncGroup.IsActive = false; + if (!syncCategoryList.Contains(syncGroup.Type)) + syncCategoryList.Add(syncGroup.Type); + } + } + if (this._inManagement) + ZuneShell.DefaultInstance.Management.CommitList[(object)this._commitDelegate] = (object)this._device.ID; + foreach (SyncCategory schema in syncCategoryList) + { + if (this.GetGroupForSchema(schema) is DetailsBackedSchemaSyncGroup groupForSchema) + groupForSchema.Sort(true); + } + } + + public void ComplexGroupEdited(int playlistID) + { + if (this._complexRulesList.ContainsKey(playlistID)) + { + SyncGroup complexRules = this._complexRulesList[playlistID]; + complexRules.DataEdited(); + if (this.GetGroupForSchema(complexRules.Type) is DetailsBackedSchemaSyncGroup groupForSchema) + groupForSchema.Sort(true); + } + if (!this._inManagement) + return; + ZuneShell.DefaultInstance.Management.CommitList[(object)this._commitDelegate] = (object)this._device.ID; + } + + public void CommitChanges(object throwaway) + { + if (this.IsDisposed) + return; + foreach (SyncGroup schema in this._schemas) + schema.CommitChanges(); + this._committed = true; + } + + public void CancelChanges() + { + foreach (SyncGroup schema in this._schemas) + schema.CancelChanges(); + } + + private void ItemUpdated(SyncRulesView syncRulesView, int iItem) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + SyncRuleDetails key = syncRulesView.GetItem(iItem); + if (!this._existingRulesList.ContainsKey(key)) + return; + SyncGroup existingRules = this._existingRulesList[key]; + existingRules.DataUpdated(); + if (key.allMedia || !(this.GetGroupForSchema(existingRules.Type) is DetailsBackedSchemaSyncGroup groupForSchema)) + return; + groupForSchema.Sort(false); + }, (object)null); + + private void ItemAdded(SyncRulesView syncRulesView, int iItem) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed || this._existingRulesList.ContainsKey(syncRulesView.GetItem(iItem))) + return; + this.AddExistingSyncGroup(iItem); + }, (object)null); + + private void AddExistingSyncGroup(int indexInRulesSnapshot) + { + SyncRuleDetails key = this._snapshot.GetItem(indexInRulesSnapshot); + if (this._existingRulesList.ContainsKey(key)) + return; + if (key.allMedia) + { + if (!(this.GetGroupForSchema((SyncCategory)key.syncCategory) is DetailsBackedSchemaSyncGroup groupForSchema)) + return; + this._existingRulesList.Add(key, (SyncGroup)groupForSchema); + groupForSchema.AssignDetails(indexInRulesSnapshot); + } + else + { + SyncCategory syncCategory = !key.complex ? (SyncCategory)key.syncCategory : UIDeviceList.MapMediaTypeToSyncCategory(PlaylistManager.GetAutoPlaylistSchema(key.mediaId)); + bool isExpandedEntry = this.Device.IsSyncAllFor(syncCategory) || this.Device.IsManualFor(syncCategory); + if (!this.InOverfill && isExpandedEntry) + return; + ExistingSyncGroup existingSyncGroup = new ExistingSyncGroup(this, this._snapshot, indexInRulesSnapshot, isExpandedEntry); + this._existingRulesList.Add(key, (SyncGroup)existingSyncGroup); + this.AddSyncGroup((SyncGroup)existingSyncGroup); + } + } + + private void AddSyncGroup(SyncGroup group) + { + if (group.IsComplex) + this._complexRulesList.Add(group.ID, group); + if (!(this.GetGroupForSchema(group.Type) is DetailsBackedSchemaSyncGroup groupForSchema)) + return; + groupForSchema.Add(group); + } + + private class SyncRuleDetailsHasher : IEqualityComparer + { + public bool Equals(SyncRuleDetails x, SyncRuleDetails y) => x.mediaId == y.mediaId && x.mediaType == y.mediaType && x.syncCategory == y.syncCategory; + + public int GetHashCode(SyncRuleDetails obj) => obj.mediaId ^ (int)obj.mediaType << 24 ^ (int)obj.syncCategory << 16; + } + } +} diff --git a/ZuneUI/SyncGroupState.cs b/ZuneUI/SyncGroupState.cs new file mode 100644 index 0000000..69b91bb --- /dev/null +++ b/ZuneUI/SyncGroupState.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncGroupState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum SyncGroupState + { + Pending, + Uncalculated, + Calculated, + } +} diff --git a/ZuneUI/SyncMode.cs b/ZuneUI/SyncMode.cs new file mode 100644 index 0000000..22f969d --- /dev/null +++ b/ZuneUI/SyncMode.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncMode +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum SyncMode + { + Invalid = -1, // 0xFFFFFFFF + SyncAll = 0, + LetMeChoose = 1, + Manual = 2, + } +} diff --git a/ZuneUI/SyncModeOptionPair.cs b/ZuneUI/SyncModeOptionPair.cs new file mode 100644 index 0000000..8d0b97f --- /dev/null +++ b/ZuneUI/SyncModeOptionPair.cs @@ -0,0 +1,36 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncModeOptionPair +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class SyncModeOptionPair + { + private string _name; + private SyncMode _mode; + + public SyncModeOptionPair(string name, SyncMode mode) + { + this._name = name; + this._mode = mode; + } + + public string Name + { + get => this._name; + set => this._name = value; + } + + public SyncMode Mode + { + get => this._mode; + set => this._mode = value; + } + + public override string ToString() => this.Name; + + public static implicit operator string(SyncModeOptionPair pair) => pair.ToString(); + } +} diff --git a/ZuneUI/SyncNewRuleAddedNotification.cs b/ZuneUI/SyncNewRuleAddedNotification.cs new file mode 100644 index 0000000..e1db71c --- /dev/null +++ b/ZuneUI/SyncNewRuleAddedNotification.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncNewRuleAddedNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class SyncNewRuleAddedNotification : MessageNotification + { + private long _oldSize; + private UIGasGauge _gauge; + + public SyncNewRuleAddedNotification(string message, long startingSize, UIGasGauge gasGauge) + : base(message, NotificationTask.Sync, NotificationState.OneShot) + { + this._gauge = gasGauge; + this._oldSize = startingSize; + } + + public long OldSize => Math.Min(Math.Max(this._oldSize, 0L), this.PredictedGauge.TotalSpace); + + public UIGasGauge PredictedGauge => this._gauge; + } +} diff --git a/ZuneUI/SyncNotification.cs b/ZuneUI/SyncNotification.cs new file mode 100644 index 0000000..8121fae --- /dev/null +++ b/ZuneUI/SyncNotification.cs @@ -0,0 +1,115 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class SyncNotification : ProgressNotification + { + private bool _syncCanceled; + private UIDevice _device; + private static string _syncing = Shell.LoadString(StringId.IDS_SYNC_STATUS); + private static string _transcoding = Shell.LoadString(StringId.IDS_TRANSCODE_STATUS); + private static string _deleting = Shell.LoadString(StringId.IDS_DELETING_STATUS); + private static string _updating = Shell.LoadString(StringId.IDS_UPDATING_STATUS); + private static string _tunnelling = Shell.LoadString(StringId.IDS_TUNNELLING_STATUS); + private static string _group = Shell.LoadString(StringId.IDS_SYNC_STATUS_GROUP); + private static string _ellipsis = Shell.LoadString(StringId.IDS_GENERIC_ELLIPSIS); + + public SyncNotification(UIDevice device) + : base(Shell.LoadString(StringId.IDS_SYNC_HEADER), NotificationTask.Sync, NotificationState.Normal) + { + this._device = device; + this.UpdateProgress(0, 0, 0, "", "", ESyncEngineState.sesInitial); + } + + public void UpdateProgress( + int percent, + int percentItem, + int percentTranscode, + string group, + string title, + ESyncEngineState engineState) + { + this.Percentage = percent; + string format; + switch (engineState) + { + case ESyncEngineState.sesUpdatingContent: + format = SyncNotification._updating; + break; + case ESyncEngineState.sesDeletingFilesNotInSyncSet: + case ESyncEngineState.sesDeletingFilesByUserRequest: + format = SyncNotification._deleting; + break; + case ESyncEngineState.sesWaitingForTranscode: + format = SyncNotification._transcoding; + break; + case ESyncEngineState.sesDirectSyncNotStarted: + case ESyncEngineState.sesDirectSyncCalculating: + case ESyncEngineState.sesDirectSyncDownloading: + format = !string.IsNullOrEmpty(title) || !string.IsNullOrEmpty(group) ? SyncNotification._syncing : SyncNotification._tunnelling; + break; + default: + format = SyncNotification._syncing; + break; + } + string str1; + if (string.IsNullOrEmpty(group)) + str1 = title ?? string.Empty; + else if (string.IsNullOrEmpty(title)) + { + str1 = group; + } + else + { + string str2 = group; + if (str2.Length > 15) + str2 = string.Format(SyncNotification._ellipsis, (object)str2.Substring(0, 15).Trim()); + str1 = string.Format(SyncNotification._group, (object)str2, (object)title); + } + this.SubMessage = string.Format(format, (object)str1); + } + + public void Complete(ESyncEventReason reason) + { + this.Percentage = 100; + if (reason == ESyncEventReason.eSyncEventFailed || reason == ESyncEventReason.eSyncEventInvalid) + { + this.Message = Shell.LoadString(StringId.IDS_SYNC_ERROR_NOTIFICATION); + this.SubMessage = (string)null; + } + else + { + if (this.SyncCanceled) + this.Message = Shell.LoadString(StringId.IDS_SYNC_CANCELLED); + else + this.Message = Shell.LoadString(StringId.IDS_SYNC_COMPLETED); + long freeSpace = this._device.ActualGasGauge.FreeSpace; + if (freeSpace <= 0L) + return; + if (freeSpace < SyncControls.DevicelandGigabyte) + this.SubMessage = string.Format(Shell.LoadString(StringId.IDS_FREE_SPACE_REMAINING_IN_MB), (object)(float)((double)freeSpace / (double)SyncControls.DevicelandMegabyte)); + else + this.SubMessage = string.Format(Shell.LoadString(StringId.IDS_FREE_SPACE_REMAINING_IN_GB), (object)(float)((double)freeSpace / (double)SyncControls.DevicelandGigabyte)); + } + } + + public bool SyncCanceled + { + get => this._syncCanceled; + set + { + if (this._syncCanceled == value) + return; + this._syncCanceled = value; + } + } + + public UIDevice Device => this._device; + } +} diff --git a/ZuneUI/SyncOverrideNotification.cs b/ZuneUI/SyncOverrideNotification.cs new file mode 100644 index 0000000..afafed8 --- /dev/null +++ b/ZuneUI/SyncOverrideNotification.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncOverrideNotification +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class SyncOverrideNotification : MessageNotification + { + public SyncOverrideNotification() + : this((string)null) + { + } + + public SyncOverrideNotification(string message) + : base(message, NotificationTask.Sync, NotificationState.Normal) + { + } + } +} diff --git a/ZuneUI/SyncabilityHelper.cs b/ZuneUI/SyncabilityHelper.cs new file mode 100644 index 0000000..01bbb92 --- /dev/null +++ b/ZuneUI/SyncabilityHelper.cs @@ -0,0 +1,80 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.SyncabilityHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class SyncabilityHelper + { + private UIDevice _device; + private DelegateFuture _isGuest; + private DelegateFuture _userId; + private DelegateFuture _supportsUserCards; + private DelegateFuture _supportsChannels; + private DelegateFuture _supportsApplications; + private DelegateFuture _supportsRental; + private DelegateFuture _supportsHD; + private DelegateFuture _isUnlinked; + private DelegateFuture _canSyncUserCards; + private DelegateFuture _canSyncChannels; + private DelegateFuture _canSyncApplications; + private DelegateFuture _canSyncRentalVideo; + private DelegateFuture _canSyncHDRentalVideo; + + public SyncabilityHelper(UIDevice device) + { + this._device = device ?? UIDeviceList.NullDevice; + this._isGuest = new DelegateFuture((CalculateValue)(() => this._device.IsGuest)); + this._userId = new DelegateFuture((CalculateValue)(() => this._device.UserId)); + this._supportsUserCards = new DelegateFuture((CalculateValue)(() => this._device.SupportsUserCards)); + this._supportsChannels = new DelegateFuture((CalculateValue)(() => this._device.SupportsChannels)); + this._supportsApplications = new DelegateFuture((CalculateValue)(() => this._device.SupportsSyncApplications)); + this._supportsRental = new DelegateFuture((CalculateValue)(() => this._device.SupportsRental)); + this._supportsHD = new DelegateFuture((CalculateValue)(() => this._device.SupportsHD)); + this._isUnlinked = new DelegateFuture((CalculateValue)(() => this.UserID == 0)); + this._canSyncUserCards = new DelegateFuture(new CalculateValue(this.GetCanSyncUserCards)); + this._canSyncChannels = new DelegateFuture(new CalculateValue(this.GetCanSyncChannels)); + this._canSyncApplications = new DelegateFuture(new CalculateValue(this.GetCanSyncApplications)); + this._canSyncRentalVideo = new DelegateFuture(new CalculateValue(this.GetCanSyncRentalVideo)); + this._canSyncHDRentalVideo = new DelegateFuture(new CalculateValue(this.GetCanSyncHDRentalVideo)); + } + + public bool IsGuest => this._isGuest.Value; + + public int UserID => this._userId.Value; + + public bool SupportsUserCards => this._supportsUserCards.Value; + + public bool SupportsChannels => this._supportsChannels.Value; + + public bool SupportsSyncApplications => this._supportsApplications.Value; + + public bool SupportsRental => this._supportsRental.Value; + + public bool SupportsHD => this._supportsHD.Value; + + public bool IsUnlinked => this._isUnlinked.Value; + + public bool CanSyncUserCards => this._canSyncUserCards.Value; + + public bool CanSyncChannels => this._canSyncChannels.Value; + + public bool CanSyncApplications => this._canSyncApplications.Value; + + public bool CanSyncRentalVideo => this._canSyncRentalVideo.Value; + + public bool CanSyncHDRentalVideo => this._canSyncHDRentalVideo.Value; + + private bool GetCanSyncUserCards() => !this.IsGuest && this.UserID == SignIn.Instance.LastSignedInUserId && this.SupportsUserCards; + + private bool GetCanSyncChannels() => !this.IsGuest && this.UserID == SignIn.Instance.LastSignedInUserId && SignIn.Instance.LastSignedInUserHadActiveSubscription && this.SupportsChannels; + + private bool GetCanSyncApplications() => this.SupportsSyncApplications; + + private bool GetCanSyncRentalVideo() => this.SupportsRental; + + private bool GetCanSyncHDRentalVideo() => this.CanSyncRentalVideo && this.SupportsHD; + } +} diff --git a/ZuneUI/TeasePage.cs b/ZuneUI/TeasePage.cs new file mode 100644 index 0000000..74776a6 --- /dev/null +++ b/ZuneUI/TeasePage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TeasePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class TeasePage : TestPage + { + protected override void OnNavigatedToWorker() + { + base.OnNavigatedToWorker(); + ZuneShell.DefaultInstance.NavigateBack(); + } + } +} diff --git a/ZuneUI/Telemetry.cs b/ZuneUI/Telemetry.cs new file mode 100644 index 0000000..957d8ea --- /dev/null +++ b/ZuneUI/Telemetry.cs @@ -0,0 +1,208 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Telemetry +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class Telemetry + { + private const string sc_EpochTime = "@epochTime"; + private const string sc_SessionEventType = "@EventType"; + private const string sc_SessionData = "@Data"; + private static Telemetry m_instance; + private Queue m_queue; + private bool m_uploadAllowed; + private static string[] _supportedTags = new string[25] + { + "AlbumId", + "ArtistId", + "CategoryId", + "ChannelId", + "ChannelUrl", + "EpisodeId", + "AppId", + "GenreId", + "MovieId", + "MovieTrailerId", + "NetworkId", + "PlaylistId", + "PodcastId", + "SelectedPivot", + "SeasonId", + "SeriesId", + "ShortId", + "SubGenreId", + "VideoId", + "TrackId", + "HubId", + "PlaylistCategoryId", + "Context", + "SelectionId", + "SelectionTitle" + }; + private Hashtable m_sqmToEventMap; + + public static Telemetry Instance + { + get + { + if (Telemetry.m_instance == null) + Telemetry.m_instance = new Telemetry(); + return Telemetry.m_instance; + } + } + + private Telemetry() + { + this.m_queue = new Queue(); + this.m_sqmToEventMap = new Hashtable(); + this.m_sqmToEventMap[(object)SQMDataId.AutoPlaylistCreations] = (object)new DatapointInfo(ETelemetryEvent.eTelemetryEventBuildPlaylist); + this.m_sqmToEventMap[(object)SQMDataId.NowPlayingClicks] = (object)new DatapointInfo(ETelemetryEvent.eTelemetryEventNowPlaying); + this.m_sqmToEventMap[(object)SQMDataId.QuickMixPlaylistCreates] = (object)new DatapointInfo(ETelemetryEvent.eTelemetryEventQuickMix); + this.m_sqmToEventMap[(object)SQMDataId.MixViewTime] = (object)new DatapointInfo(ETelemetryEvent.eTelemetryEventMixView, "MixViewTime", true); + this.m_sqmToEventMap[(object)SQMDataId.NowPlayingMusicViewTime] = (object)new DatapointInfo(ETelemetryEvent.eTelemetryEventPlayback, "PlaybackAudio", true); + this.m_sqmToEventMap[(object)SQMDataId.NowPlayingVideoViewTime] = (object)new DatapointInfo(ETelemetryEvent.eTelemetryEventPlayback, "PlaybackVideo", true); + this.m_sqmToEventMap[(object)SQMDataId.NowPlayingPhotoViewTime] = (object)new DatapointInfo(ETelemetryEvent.eTelemetryEventPlayback, "PlaybackPhoto", true); + } + + internal void StartUpload() + { + lock (this.m_queue) + { + this.m_uploadAllowed = true; + if (this.m_queue.Count <= 0) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.ProcessQueue), (object)null, DeferredInvokePriority.Low); + } + } + + private Hashtable FilterPageArgs(IDictionary args) + { + Hashtable hashtable = new Hashtable(); + if (args != null) + { + foreach (DictionaryEntry dictionaryEntry in args) + { + if (dictionaryEntry.Key is string && Array.IndexOf(Telemetry._supportedTags, (string)dictionaryEntry.Key) != -1 && (dictionaryEntry.Value is string || dictionaryEntry.Value is Guid || dictionaryEntry.Value is int)) + hashtable.Add(dictionaryEntry.Key, dictionaryEntry.Value); + } + } + return hashtable; + } + + public void ReportNavigation(string command, IDictionary args) + { + if (command == null) + return; + Hashtable hashtable = this.FilterPageArgs(args); + this.QueueTelemetry(new TelemetryInfo(ETelemetryEvent.eTelemetryEventUndefined, command, (IDictionary)hashtable, false)); + } + + public void ReportPlaybackTime(int timeData) + { + if (timeData <= 0) + return; + this.QueueTelemetry(new TelemetryInfo(ETelemetryEvent.eTelemetryEventPlayback, "", (IDictionary)new Hashtable() + { + { + (object) "@Data", + (object) timeData + }, + { + (object) "@EventType", + (object) "CumulativePlaybackTime" + } + }, true)); + } + + public void ReportEvent(SQMDataPoint datapoint, int nData) + { + SQMDataId id = datapoint.id; + bool flag = datapoint.action == SQMAction.Add || datapoint.action == SQMAction.Inc; + if (id == SQMDataId.Invalid || !flag || !this.m_sqmToEventMap.ContainsKey((object)id)) + return; + Hashtable hashtable = new Hashtable(); + DatapointInfo sqmToEvent = (DatapointInfo)this.m_sqmToEventMap[(object)id]; + if (sqmToEvent.IsSession) + { + hashtable.Add((object)"@Data", (object)nData); + hashtable.Add((object)"@EventType", (object)sqmToEvent.TypeName); + } + this.QueueTelemetry(new TelemetryInfo(sqmToEvent.Event, "", (IDictionary)hashtable, sqmToEvent.IsSession)); + } + + public void ReportSearch(string search) => this.QueueTelemetry(new TelemetryInfo(ETelemetryEvent.eTelemetryEventUndefined, "Search", (IDictionary)new Hashtable() + { + { + (object) "zune_query", + (object) search + } + }, false)); + + public void ReportPageLoad(string pageUri, int pageLoadTime, IDictionary args) + { + if (string.IsNullOrEmpty(pageUri)) + return; + string uri = "PageLoadTime"; + Hashtable hashtable = this.FilterPageArgs(args); + hashtable.Add((object)pageUri, (object)pageLoadTime); + this.QueueTelemetry(new TelemetryInfo(ETelemetryEvent.eTelemetryEventUndefined, uri, (IDictionary)hashtable, false)); + } + + private void QueueTelemetry(TelemetryInfo info) + { + lock (this.m_queue) + { + this.m_queue.Enqueue(info); + if (!this.m_uploadAllowed || this.m_queue.Count != 1) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.ProcessQueue), (object)null, DeferredInvokePriority.Low); + } + } + + private void ProcessQueue(object state) + { + TelemetryInfo telemetryInfo = (TelemetryInfo)null; + bool flag; + lock (this.m_queue) + { + if (this.m_queue.Count > 0) + telemetryInfo = this.m_queue.Dequeue(); + flag = this.m_queue.Count > 0; + } + if (telemetryInfo != null) + this.SendTelemetry((object)telemetryInfo); + if (!flag) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.ProcessQueue), (object)null, DeferredInvokePriority.Low); + } + + private void SendTelemetryInfo(TelemetryInfo info) => Application.DeferredInvoke(new DeferredInvokeHandler(this.SendTelemetry), (object)info, DeferredInvokePriority.Low); + + private void SendTelemetry(object state) + { + TelemetryInfo telemetryInfo = (TelemetryInfo)state; + telemetryInfo.Args.Add((object)"@epochTime", (object)telemetryInfo.elapsedTime); + if (telemetryInfo.fSessionDatapoint) + { + int int32 = Convert.ToInt32(telemetryInfo.Args[(object)"@Data"]); + string key = telemetryInfo.Args[(object)"@EventType"].ToString(); + TelemetryAPI.AddToSessionEvent(telemetryInfo.eEvent, key, int32); + } + else if (telemetryInfo.eEvent == ETelemetryEvent.eTelemetryEventUndefined) + TelemetryAPI.SendDatapoint(telemetryInfo.dcsUri, telemetryInfo.Args); + else if (telemetryInfo.Args.Contains((object)"@EventType")) + TelemetryAPI.SendEvent(telemetryInfo.eEvent, telemetryInfo.Args[(object)"@EventType"].ToString()); + else + TelemetryAPI.SendEvent(telemetryInfo.eEvent, (string)null); + } + } +} diff --git a/ZuneUI/TelemetryInfo.cs b/ZuneUI/TelemetryInfo.cs new file mode 100644 index 0000000..db6cd12 --- /dev/null +++ b/ZuneUI/TelemetryInfo.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TelemetryInfo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + public class TelemetryInfo + { + public ETelemetryEvent eEvent = ETelemetryEvent.eTelemetryEventUndefined; + public string dcsUri = ""; + public IDictionary Args; + public DateTime utcTime; + public long elapsedTime; + public bool fSessionDatapoint; + + public TelemetryInfo(ETelemetryEvent evt, string uri, IDictionary args, bool fSession) + { + this.eEvent = evt; + this.dcsUri = uri; + this.Args = args; + this.utcTime = DateTime.UtcNow; + this.fSessionDatapoint = fSession; + this.elapsedTime = (long)this.utcTime.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds; + } + } +} diff --git a/ZuneUI/TermsOfServiceFinishStep.cs b/ZuneUI/TermsOfServiceFinishStep.cs new file mode 100644 index 0000000..9462ac1 --- /dev/null +++ b/ZuneUI/TermsOfServiceFinishStep.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TermsOfServiceFinishStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class TermsOfServiceFinishStep : AccountManagementFinishStep + { + public TermsOfServiceFinishStep(Wizard owner, AccountManagementWizardState state) + : base(owner, state, Shell.LoadString(StringId.IDS_ACCOUNT_FINISHED_DESCRIPTION)) + { + } + + protected override bool OnCommitChanges() => this.State.AcceptTermsOfService(); + } +} diff --git a/ZuneUI/TermsOfServiceStep.cs b/ZuneUI/TermsOfServiceStep.cs new file mode 100644 index 0000000..3601427 --- /dev/null +++ b/ZuneUI/TermsOfServiceStep.cs @@ -0,0 +1,181 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TermsOfServiceStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Collections; + +namespace ZuneUI +{ + public class TermsOfServiceStep : AccountManagementStep + { + private string _termsOfService; + private string _termsOfServiceUrl; + private string _privacyUrl; + private string _username; + private string _password; + private PassportIdentity _passportIdentity; + + public TermsOfServiceStep(Wizard owner, AccountManagementWizardState state, bool parentAccount) + : base(owner, state, parentAccount) + { + this.NextTextOverride = Shell.LoadString(StringId.IDS_I_ACCEPT_BUTTON); + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_TOS_STEP_TITLE); + this.Initialize((WizardPropertyEditor)null); + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#TermsOfServiceStep"; + + public string TermsOfService + { + get => this._termsOfService; + private set + { + if (!(this._termsOfService != value)) + return; + this._termsOfService = value; + this.FirePropertyChanged(nameof(TermsOfService)); + } + } + + public string TermsOfServiceUrl + { + get => this._termsOfServiceUrl; + private set + { + if (!(this._termsOfServiceUrl != value)) + return; + this._termsOfServiceUrl = value; + this.FirePropertyChanged(nameof(TermsOfServiceUrl)); + } + } + + public string PrivacyUrl + { + get => this._privacyUrl; + private set + { + if (!(this._privacyUrl != value)) + return; + this._privacyUrl = value; + this.FirePropertyChanged(nameof(PrivacyUrl)); + } + } + + public string Username + { + get => this._username; + set + { + if (!(this._username != value)) + return; + this._username = value; + this.FirePropertyChanged(nameof(Username)); + } + } + + public string Password + { + get => this._password; + set + { + if (value == null || value == SignIn.Instance.PseudoPassword) + value = string.Empty; + if (!(this._password != value)) + return; + this._password = value; + this.FirePropertyChanged(nameof(Password)); + } + } + + public PassportIdentity PassportIdentity + { + get => this._passportIdentity; + private set + { + if (this._passportIdentity == value) + return; + this._passportIdentity = value; + this.FirePropertyChanged(nameof(PassportIdentity)); + } + } + + internal static string GetTermsOfServiceUrl(string locale) => CultureHelper.AppendFwlinkCulture(Shell.LoadString(StringId.IDS_TERMS_OF_SERVICE_URL), locale); + + internal static string GetPrivacyUrl(string locale) => CultureHelper.AppendFwlinkCulture(Shell.LoadString(StringId.IDS_PRIVACY_STATEMENT_URL), locale); + + protected override void OnActivate() + { + this.ServiceActivationRequestsDone = this.TermsOfService != null && this.PassportIdentity != null; + if (this.ServiceActivationRequestsDone) + return; + this.StartActivationRequests((object)new TermsOfServiceStep.TermsOfServiceData() + { + Username = this.Username, + Password = this.Password + }); + } + + protected override void OnStartActivationRequests(object state) + { + HRESULT hr = HRESULT._S_OK; + TermsOfServiceStep.TermsOfServiceData termsOfServiceData = (TermsOfServiceStep.TermsOfServiceData)state; + if (hr.IsSuccess) + hr = AccountManagementHelper.GetPassportIdentity(termsOfServiceData.Username, termsOfServiceData.Password, out termsOfServiceData.PassportIdentity); + ServiceError serviceError = (ServiceError)null; + if (hr.IsSuccess) + hr = this.State.AccountManagement.GetAccount(termsOfServiceData.PassportIdentity, out termsOfServiceData.AccountUser, out serviceError); + string language = (string)null; + string country = (string)null; + if (hr.IsSuccess) + { + RegionInfoStep.GetLanguageAndCountry(termsOfServiceData.AccountUser.Locale, out language, out country); + if (string.IsNullOrEmpty(country)) + hr = HRESULT._E_FAIL; + } + if (hr.IsSuccess) + hr = this.State.AccountManagement.GetTermsOfService(language, country, out termsOfServiceData.TermsOfService); + if (hr.IsError) + this.SetError(hr, serviceError); + this.EndActivationRequests((object)termsOfServiceData); + } + + protected override void OnEndActivationRequests(object args) + { + TermsOfServiceStep.TermsOfServiceData termsOfServiceData = (TermsOfServiceStep.TermsOfServiceData)args; + this.TermsOfService = termsOfServiceData.TermsOfService; + this.PassportIdentity = termsOfServiceData.PassportIdentity; + if (termsOfServiceData.AccountUser == null) + return; + this.TermsOfServiceUrl = TermsOfServiceStep.GetTermsOfServiceUrl(termsOfServiceData.AccountUser.Locale); + this.PrivacyUrl = TermsOfServiceStep.GetPrivacyUrl(termsOfServiceData.AccountUser.Locale); + this.State.PrivacyInfoParentStep.CommittedSettings = termsOfServiceData.AccountUser.AccountSettings; + this.State.PrivacyInfoStep.CommittedSettings = termsOfServiceData.AccountUser.AccountSettings; + this.State.SetPrivacySettings(termsOfServiceData.AccountUser.AccountUserType); + if (termsOfServiceData.AccountUser.AccountUserType != AccountUserType.ChildWithoutSocial && termsOfServiceData.AccountUser.AccountUserType != AccountUserType.ChildWithSocial || this.State.PassportPasswordParentStep.IsEnabled || this._owner.Pages == null) + return; + this.State.PassportPasswordParentStep.ForceEnable = true; + int num = -1; + foreach (object page in (IEnumerable)this._owner.Pages) + { + ++num; + if (page == this.State.PassportPasswordParentStep) + break; + } + if (num >= this._owner.CurrentPageIndex || num >= this._owner.Pages.Count) + return; + this._owner.CurrentPageIndex = num; + } + + private class TermsOfServiceData + { + public string Username; + public string Password; + public string TermsOfService; + public PassportIdentity PassportIdentity; + public AccountUser AccountUser; + } + } +} diff --git a/ZuneUI/TermsOfServiceWizard.cs b/ZuneUI/TermsOfServiceWizard.cs new file mode 100644 index 0000000..19f0718 --- /dev/null +++ b/ZuneUI/TermsOfServiceWizard.cs @@ -0,0 +1,85 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TermsOfServiceWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class TermsOfServiceWizard : AccountManagementWizard + { + private TermsOfServiceFinishStep _finishStep; + private AccountManagementErrorPage _errorStep; + + public TermsOfServiceWizard() + { + this.RequiresSignIn = false; + this.State.PassportPasswordParentStep.DetailDescription = Shell.LoadString(StringId.IDS_ACCOUNT_TOS_STEP_PARENT_NEEDED); + this._finishStep = new TermsOfServiceFinishStep((Wizard)this, this.State); + this._errorStep = new AccountManagementErrorPage((Wizard)this, Shell.LoadString(StringId.IDS_ACCOUNT_TOS_ERROR_TITLE), Shell.LoadString(StringId.IDS_ACCOUNT_TOS_ERROR_DESC)); + SignIn.Instance.SignInStatusUpdatedEvent += new EventHandler(this.OnSignInStatusUpdatedEvent); + } + + protected override void OnDispose(bool disposing) + { + base.OnDispose(disposing); + if (!disposing) + return; + SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignInStatusUpdatedEvent); + } + + public bool ChildAccount + { + get => this.State.PassportPasswordParentStep.ForceEnable; + private set => this.State.PassportPasswordParentStep.ForceEnable = value; + } + + public string Username + { + get => this.State.TermsOfServiceStep.Username; + private set => this.State.TermsOfServiceStep.Username = value; + } + + public string Password + { + get => this.State.TermsOfServiceStep.Password; + private set => this.State.TermsOfServiceStep.Password = value; + } + + public void Initialize(string username, string password, bool childAccount) + { + this.Username = username; + this.Password = password; + this.ChildAccount = childAccount; + this.AddPage((WizardPage)this.State.PassportPasswordParentStep); + this.AddPage((WizardPage)this.State.TermsOfServiceStep); + this.AddPage((WizardPage)this.State.PrivacyInfoParentStep); + this.AddPage((WizardPage)this.State.PrivacyInfoStep); + this.AddPage((WizardPage)this._finishStep); + this.AddPage((WizardPage)this._errorStep); + } + + protected override void OnAsyncCommitCompleted(bool success) + { + if (success && !SignIn.Instance.SignedIn) + { + SignIn.Instance.SignInUser(this.Username, this.Password); + this._finishStep.LoadStatus = Shell.LoadString(StringId.IDS_LOGON_STATUS_BUTTON); + } + else + base.OnAsyncCommitCompleted(success); + } + + private void OnSignInStatusUpdatedEvent(object sender, EventArgs e) + { + if (!SignIn.Instance.SignInError.IsError && !SignIn.Instance.SignedIn) + return; + this._finishStep.ClosingMessage = Shell.LoadString(StringId.IDS_ACCOUNT_TOS_ERROR_SUCCESS_DESC); + if (!SignIn.Instance.SignInError.IsError) + this.State.SaveFamilySettings(); + base.OnAsyncCommitCompleted(true); + } + } +} diff --git a/ZuneUI/TestExperience.cs b/ZuneUI/TestExperience.cs new file mode 100644 index 0000000..2f19957 --- /dev/null +++ b/ZuneUI/TestExperience.cs @@ -0,0 +1,69 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TestExperience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System.Collections; + +namespace ZuneUI +{ + public class TestExperience : Experience + { + private ArrayListDataSet _nodes; + private Node _stringTester; + private Node _webHostTester; + private bool _pivotHasBeenShownBefore; + + public TestExperience(Frame frameOwner) + : base(frameOwner, StringId.IDS_TEST_PIVOT, SQMDataId.Invalid) + => this._pivotHasBeenShownBefore = false; + + public override IList NodesList + { + get + { + if (this._nodes == null) + { + this._nodes = new ArrayListDataSet((IModelItemOwner)this); + this._nodes.Add((object)this.StringTester); + this._nodes.Add((object)this.WebHost); + } + return (IList)this._nodes; + } + } + + public Node StringTester + { + get + { + if (this._stringTester == null) + this._stringTester = new Node((Experience)this, "string tester", "Test\\StringTester\\Home"); + return this._stringTester; + } + } + + public Node WebHost + { + get + { + if (this._webHostTester == null) + this._webHostTester = new Node((Experience)this, nameof(WebHost), "Test\\WebHost\\Home"); + return this._webHostTester; + } + } + + protected override void OnIsCurrentChanged() => this.UpdateShowTest(); + + public void UpdateShowTest() + { + bool show = this.IsCurrent || this._pivotHasBeenShownBefore; + ((MainFrame)this.Frame).ShowTest(show); + if (!show) + return; + this._pivotHasBeenShownBefore = true; + } + } +} diff --git a/ZuneUI/TestPage.cs b/ZuneUI/TestPage.cs new file mode 100644 index 0000000..056c4df --- /dev/null +++ b/ZuneUI/TestPage.cs @@ -0,0 +1,94 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TestPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class TestPage : ZunePage + { + private int _refCount; + private bool _saveToBackStack; + private bool _canBeTrimmed; + private bool _sharedInstance; + + public TestPage() + { + this._saveToBackStack = true; + this._canBeTrimmed = true; + } + + public bool SaveToBackStack + { + get => this._saveToBackStack; + set + { + if (this._saveToBackStack == value) + return; + this._saveToBackStack = value; + this.FirePropertyChanged(nameof(SaveToBackStack)); + } + } + + public bool SharedInstance + { + get => this._sharedInstance; + set + { + if (this._sharedInstance == value) + return; + this._sharedInstance = value; + this.FirePropertyChanged(nameof(SharedInstance)); + } + } + + public bool CanBeTrimmed + { + get => this._canBeTrimmed; + set + { + if (this._canBeTrimmed == value) + return; + this._canBeTrimmed = value; + this.FirePropertyChanged(nameof(CanBeTrimmed)); + } + } + + public override IPageState SaveAndRelease() + { + IPageState pageState = (IPageState)null; + if (this._saveToBackStack) + { + if (this._sharedInstance) + { + pageState = (IPageState)new InstancePageState((IPage)this); + } + else + { + pageState = (IPageState)new TestPageState(this.Description, this.UI, this.BackgroundUI, this.CanBeTrimmed); + this.Release(); + } + } + else + this.Release(); + return pageState; + } + + public override void Release() => --this._refCount; + + protected override void OnNavigatedToWorker() + { + if (this.IsValid) + { + int num = this._sharedInstance ? 1 : 0; + } + ++this._refCount; + base.OnNavigatedToWorker(); + } + + protected override void OnNavigatedAwayWorker(IPage destination) => base.OnNavigatedAwayWorker(destination); + + protected bool IsValid => this._refCount > 0; + } +} diff --git a/ZuneUI/TestPageState.cs b/ZuneUI/TestPageState.cs new file mode 100644 index 0000000..770c9f2 --- /dev/null +++ b/ZuneUI/TestPageState.cs @@ -0,0 +1,48 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TestPageState +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public class TestPageState : ModelItem, IPageState + { + private bool _isInvalid; + private bool _canBeTrimmed; + private string _mainUI; + private string _backgroundUI; + + public TestPageState( + string description, + string mainUI, + string backgroundUI, + bool canBeTrimmed) + { + this.Description = description; + this._mainUI = mainUI; + this._backgroundUI = backgroundUI; + this._canBeTrimmed = canBeTrimmed; + } + + public IPage RestoreAndRelease() + { + TestPage testPage = new TestPage(); + testPage.Description = this.Description; + testPage.UI = this._mainUI; + testPage.BackgroundUI = this._backgroundUI; + this.Release(); + return (IPage)testPage; + } + + public void Release() => this._isInvalid = true; + + public bool CanBeTrimmed + { + get => this._canBeTrimmed; + set => this._canBeTrimmed = value; + } + } +} diff --git a/ZuneUI/TextChopper.cs b/ZuneUI/TextChopper.cs new file mode 100644 index 0000000..aba08e8 --- /dev/null +++ b/ZuneUI/TextChopper.cs @@ -0,0 +1,110 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TextChopper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections.Generic; +using System.Text; + +namespace ZuneUI +{ + public class TextChopper + { + private static Random _random = new Random(); + + public static string Chop(string text, int minChunkSize, int maxChunkSize) + { + try + { + if (string.IsNullOrEmpty(text)) + return text; + if (minChunkSize < 1) + minChunkSize = 1; + List stringList = new List(); + stringList.Add(""); + StringBuilder stringBuilder = new StringBuilder(text.Length * 8); + int num1 = 0; + int num2 = 0; + bool flag = false; + while (num1 < text.Length) + { + if (text[num1] == '<') + { + num2 = 0; + if (flag) + { + flag = false; + for (int count = stringList.Count; count > 0; --count) + { + string str = stringList[count - 1].Insert(1, "/"); + stringBuilder.Append(str); + } + } + int num3 = text.IndexOf('>', num1); + if (num3 == -1) + throw new TextChopper.TextChopperException("Missing closing > in tag for string : " + text); + string str1 = text.Substring(num1, num3 - num1 + 1); + if (str1[1] == '/') + stringList.RemoveAt(stringList.Count - 1); + else + stringList.Add(str1); + num1 += str1.Length; + } + else + { + if (num2 == 0) + { + num2 = Math.Min(maxChunkSize <= minChunkSize ? minChunkSize : TextChopper._random.Next(minChunkSize, maxChunkSize), text.Length - num1); + foreach (string str in stringList) + stringBuilder.Append(str); + flag = true; + } + string str1; + int num3; + if (text[num1] == '&') + { + int num4 = text.IndexOf(';', num1); + if (num4 == -1) + throw new TextChopper.TextChopperException("Missing closing ; in escaped text for string : " + text); + int length = num4 - num1 + 1; + str1 = text.Substring(num1, length); + num3 = length; + } + else + { + str1 = text[num1].ToString(); + num3 = 1; + } + stringBuilder.Append(str1); + num1 += num3; + --num2; + if (num2 == 0 || num1 == text.Length) + { + for (int count = stringList.Count; count > 0; --count) + { + string str2 = stringList[count - 1].Insert(1, "/"); + stringBuilder.Append(str2); + } + flag = false; + } + } + } + return stringBuilder.ToString(); + } + catch (Exception ex) + { + return text; + } + } + + public class TextChopperException : Exception + { + public TextChopperException(string message) + : base(message) + { + } + } + } +} diff --git a/ZuneUI/ThumbBarButtons.cs b/ZuneUI/ThumbBarButtons.cs new file mode 100644 index 0000000..0018b1f --- /dev/null +++ b/ZuneUI/ThumbBarButtons.cs @@ -0,0 +1,210 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ThumbBarButtons +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using System.ComponentModel; +using System.Threading; + +namespace ZuneUI +{ + public class ThumbBarButtons : SingletonModelItem + { + private ThumbBar _thumbBar; + private ThumbBarButton _playPause; + private ThumbBarButton _previous; + private ThumbBarButton _next; + private ThumbBarButton _rating; + private int _lastUpdateJobCookie; + private object _updateJobLock = new object(); + private bool _thumbBarInitializationComplete; + private static string s_playTooltip = Shell.LoadString(StringId.IDS_PLAY); + private static string s_pauseTooltip = Shell.LoadString(StringId.IDS_PAUSE); + private static string s_unratedTooltip = Shell.LoadString(StringId.IDS_NOWPLAYING_UNRATED_TOOLTIP); + private static string s_loveItTooltip = Shell.LoadString(StringId.IDS_NOWPLAYING_LIKEIT_TOOLTIP); + private static string s_hateItTooltip = Shell.LoadString(StringId.IDS_NOWPLAYING_DONTLIKEIT_TOOLTIP); + + public void Phase3Init() + { + TransportControls instance = SingletonModelItem.Instance; + instance.PropertyChanged += new PropertyChangedEventHandler(this.OnTransportControlsPropertyChanged); + instance.Play.PropertyChanged += new PropertyChangedEventHandler(this.OnTransportControlsCommandPropertyChanged); + instance.Pause.PropertyChanged += new PropertyChangedEventHandler(this.OnTransportControlsCommandPropertyChanged); + instance.Back.PropertyChanged += new PropertyChangedEventHandler(this.OnTransportControlsCommandPropertyChanged); + instance.Forward.PropertyChanged += new PropertyChangedEventHandler(this.OnTransportControlsCommandPropertyChanged); + string previousText = Shell.LoadString(StringId.IDS_PREVIOUS); + string nextText = Shell.LoadString(StringId.IDS_NEXT); + IntPtr windowHandle = Application.Window.Handle; + ThreadPool.QueueUserWorkItem((WaitCallback)delegate + { + Win7ShellManager.Instance.BeginThumbBarSession(windowHandle, out this._thumbBar); + Win7ShellManager.Instance.OnThumbBarButtonPress += new ThumbBarButtonPressHandler(this.OnThumbButtonPressed); + ThumbBarButton button; + this._thumbBar.CreateButton(out button); + button.UniqueID = 4U; + button.IsHidden = true; + this._thumbBar.CreateButton(out this._previous); + this._previous.UniqueID = 1U; + this._previous.Tooltip = previousText; + this._thumbBar.CreateButton(out this._playPause); + this._playPause.UniqueID = 0U; + this._thumbBar.CreateButton(out this._next); + this._next.UniqueID = 2U; + this._next.Tooltip = nextText; + this._thumbBar.CreateButton(out this._rating); + this._rating.UniqueID = 3U; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this._thumbBarInitializationComplete = true; + this.UpdateButtonStatus(); + }, (object)null); + }, (object)null); + } + + private bool IsCurrentTrackRatable() + { + PlaybackTrack currentTrack = SingletonModelItem.Instance.CurrentTrack; + return currentTrack != null && currentTrack.CanRate; + } + + private void OnTransportControlsPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "CurrentTrackRating") && !(args.PropertyName == "Playing")) + return; + this.UpdateButtonStatus(); + } + + private void OnTransportControlsCommandPropertyChanged( + object sender, + PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "Available")) + return; + this.UpdateButtonStatus(); + } + + private void OnThumbButtonPressed(uint uniqueID) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + TransportControls instance = SingletonModelItem.Instance; + switch (uniqueID) + { + case 0: + if (instance.Playing) + { + instance.Pause.Invoke(); + break; + } + instance.Play.Invoke(); + break; + case 1: + instance.Back.Invoke(); + break; + case 2: + instance.Forward.Invoke(); + break; + case 3: + if (this.IsCurrentTrackRatable()) + { + PlaybackTrack currentTrack = instance.CurrentTrack; + currentTrack.UserRating = currentTrack.UserRating != 0 ? (currentTrack.UserRating > 5 ? 2 : 0) : 8; + } + this.UpdateButtonStatus(); + break; + } + }, (object)null); + + private void UpdateButtonStatus() + { + if (!this._thumbBarInitializationComplete) + return; + TransportControls instance = SingletonModelItem.Instance; + ThumbBarButtons.UpdateThumbBarJob updateThumbBarJob = new ThumbBarButtons.UpdateThumbBarJob(); + updateThumbBarJob.Cookie = Interlocked.Increment(ref this._lastUpdateJobCookie); + updateThumbBarJob.IsPlaying = instance.Playing; + updateThumbBarJob.CanPlay = instance.Play.Available; + updateThumbBarJob.CanPause = instance.Pause.Available; + updateThumbBarJob.CanGoBack = instance.Back.Available; + updateThumbBarJob.CanGoForward = instance.Forward.Available; + updateThumbBarJob.IsCurrentTrackRatable = this.IsCurrentTrackRatable(); + if (instance.CurrentTrack != null) + updateThumbBarJob.CurrentTrackRating = instance.CurrentTrack.UserRating; + ThreadPool.QueueUserWorkItem(new WaitCallback(this.UpdateButtonStatusWorker), (object)updateThumbBarJob); + } + + private void UpdateButtonStatusWorker(object data) + { + if (!(data is ThumbBarButtons.UpdateThumbBarJob updateThumbBarJob)) + return; + lock (this._updateJobLock) + { + if (this._lastUpdateJobCookie != updateThumbBarJob.Cookie) + return; + if (updateThumbBarJob.IsPlaying) + { + this._playPause.IsEnabled = updateThumbBarJob.CanPause; + this._playPause.Tooltip = ThumbBarButtons.s_pauseTooltip; + this._playPause.Icon = ThumbBarButtonIcons.eThumbBarButtonIconPause; + } + else + { + this._playPause.IsEnabled = updateThumbBarJob.CanPlay; + this._playPause.Tooltip = ThumbBarButtons.s_playTooltip; + this._playPause.Icon = updateThumbBarJob.CanPlay ? ThumbBarButtonIcons.eThumbBarButtonIconPlay : ThumbBarButtonIcons.eThumbBarButtonIconPlayDisabled; + } + this._previous.IsEnabled = updateThumbBarJob.CanGoBack; + this._previous.Icon = updateThumbBarJob.CanGoBack ? ThumbBarButtonIcons.eThumbBarButtonIconPrevious : ThumbBarButtonIcons.eThumbBarButtonIconPreviousDisabled; + this._next.IsEnabled = updateThumbBarJob.CanGoForward; + this._next.Icon = updateThumbBarJob.CanGoForward ? ThumbBarButtonIcons.eThumbBarButtonIconNext : ThumbBarButtonIcons.eThumbBarButtonIconNextDisabled; + if (!updateThumbBarJob.IsCurrentTrackRatable) + { + this._rating.IsHidden = true; + } + else + { + this._rating.IsHidden = false; + if (updateThumbBarJob.CurrentTrackRating == 0) + { + this._rating.Tooltip = ThumbBarButtons.s_unratedTooltip; + this._rating.Icon = ThumbBarButtonIcons.eThumbBarButtonIconUnrated; + } + else if (updateThumbBarJob.CurrentTrackRating <= 5) + { + this._rating.Tooltip = ThumbBarButtons.s_hateItTooltip; + this._rating.Icon = ThumbBarButtonIcons.eThumbBarButtonIconHateIt; + } + else + { + this._rating.Tooltip = ThumbBarButtons.s_loveItTooltip; + this._rating.Icon = ThumbBarButtonIcons.eThumbBarButtonIconLoveIt; + } + } + this._thumbBar.UpdateThumbBar(); + } + } + + private enum ThumbButtonID : uint + { + PlayPause, + Previous, + Next, + Rating, + Spacer, + } + + private class UpdateThumbBarJob + { + public int Cookie; + public bool IsPlaying; + public bool CanPlay; + public bool CanPause; + public bool CanGoForward; + public bool CanGoBack; + public bool IsCurrentTrackRatable; + public int CurrentTrackRating; + } + } +} diff --git a/ZuneUI/ThumbnailCommand.cs b/ZuneUI/ThumbnailCommand.cs new file mode 100644 index 0000000..2ab01a3 --- /dev/null +++ b/ZuneUI/ThumbnailCommand.cs @@ -0,0 +1,46 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ThumbnailCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public class ThumbnailCommand : Command, IThumbnailCommand, ICommand, INotifyPropertyChanged + { + private Image _image; + + public ThumbnailCommand() + : this((IModelItemOwner)null) + { + } + + public ThumbnailCommand(IModelItemOwner owner) + : base(owner) + { + } + + public virtual Image Image + { + get => this._image; + set + { + if (this._image == value) + return; + this._image = value; + this.FirePropertyChanged(nameof(Image)); + } + } + + public string ImagePath + { + set => this.Image = new Image(value); + } + + IDictionary IThumbnailCommand.Data => this.Data; + } +} diff --git a/ZuneUI/TimeFormattingHelper.cs b/ZuneUI/TimeFormattingHelper.cs new file mode 100644 index 0000000..62906f2 --- /dev/null +++ b/ZuneUI/TimeFormattingHelper.cs @@ -0,0 +1,46 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TimeFormattingHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class TimeFormattingHelper + { + public static string FormatSeconds(int seconds) + { + if (seconds <= 0) + return (string)null; + int num1 = seconds / 3600; + int num2 = seconds / 60 % 60; + seconds %= 60; + if (num1 >= 1 || num2 > 20) + { + num2 = num2 / 5 * 5; + seconds = 0; + } + if (num2 >= 1 || seconds > 20) + seconds = seconds / 5 * 5; + if (seconds == 1 && num2 == 0 && num1 == 0) + return Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_ONE_SECOND); + if (seconds > 1 && num2 == 0 && num1 == 0) + return string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_N_SECONDS), (object)seconds); + if (seconds == 0 && num2 == 1 && num1 == 0) + return Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_ONE_MINUTE); + if (seconds == 0 && num2 > 1 && num1 == 0) + return string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_N_MINUTES), (object)num2); + if (num2 == 0 && num1 == 1) + return Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_ONE_HOUR); + if (num2 == 0 && num1 > 1) + return string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_N_HOURS), (object)num1); + if (seconds > 1 && num2 == 1 && num1 == 0) + return string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_ONE_MINUTE_N_SECONDS), (object)seconds); + if (seconds > 1 && num2 > 1 && num1 == 0) + return string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_N_MINUTES_N_SECONDS), (object)num2, (object)seconds); + if (num2 > 1 && num1 == 1) + return string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_ONE_HOUR_N_MINUTES), (object)num2); + return num2 > 1 && num1 > 1 ? string.Format(Shell.LoadString(StringId.IDS_DOWNLOAD_TIME_FORMAT_N_HOURS_N_MINUTES), (object)num1, (object)num2) : (string)null; + } + } +} diff --git a/ZuneUI/TimeSpanHelper.cs b/ZuneUI/TimeSpanHelper.cs new file mode 100644 index 0000000..93714f4 --- /dev/null +++ b/ZuneUI/TimeSpanHelper.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TimeSpanHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public static class TimeSpanHelper + { + public static bool IsEmpty(TimeSpan span) => span == TimeSpan.Zero; + + public static TimeSpan Empty => TimeSpan.Zero; + } +} diff --git a/ZuneUI/ToStringCaseInsensitiveComparer.cs b/ZuneUI/ToStringCaseInsensitiveComparer.cs new file mode 100644 index 0000000..83a4c5a --- /dev/null +++ b/ZuneUI/ToStringCaseInsensitiveComparer.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ToStringCaseInsensitiveComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + internal class ToStringCaseInsensitiveComparer : IComparer + { + private static ToStringCaseInsensitiveComparer s_instance; + + public static IComparer Instance + { + get + { + if (ToStringCaseInsensitiveComparer.s_instance == null) + ToStringCaseInsensitiveComparer.s_instance = new ToStringCaseInsensitiveComparer(); + return (IComparer)ToStringCaseInsensitiveComparer.s_instance; + } + } + + private ToStringCaseInsensitiveComparer() + { + } + + int IComparer.Compare(object x, object y) => string.Compare(x.ToString(), y.ToString(), StringComparison.CurrentCultureIgnoreCase); + } +} diff --git a/ZuneUI/TraceCommandHandler.cs b/ZuneUI/TraceCommandHandler.cs new file mode 100644 index 0000000..beb64df --- /dev/null +++ b/ZuneUI/TraceCommandHandler.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TraceCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class TraceCommandHandler : ICommandHandler + { + public void Execute(string command, IDictionary commandArgs) => TraceCommandHandler.Trace(command, commandArgs); + + public static void Trace(string command, IDictionary commandArgs) + { + if (commandArgs == null) + return; + foreach (object key in (IEnumerable)commandArgs.Keys) + { + object commandArg = commandArgs[key]; + } + } + } +} diff --git a/ZuneUI/TrackAttachment.cs b/ZuneUI/TrackAttachment.cs new file mode 100644 index 0000000..09205f9 --- /dev/null +++ b/ZuneUI/TrackAttachment.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrackAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public class TrackAttachment : Attachment + { + public const string RequestTypeString = "song"; + + public TrackAttachment(Guid id, string title, string artist, string imageUri) + : base(id, title, artist, imageUri) + { + this.AttachmentUI = "res://ZuneShellResources!SocialComposer.uix#TrackAttachmentUI"; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_TRACK_ATTACHMENT); + } + + public override MediaType MediaType => MediaType.Track; + + public override string RequestType => "song"; + + public override void LogSend() => SQMLog.Log(SQMDataId.InboxMessageSendTrack, 1); + } +} diff --git a/ZuneUI/TrackCollectionFilterType.cs b/ZuneUI/TrackCollectionFilterType.cs new file mode 100644 index 0000000..b0f62b2 --- /dev/null +++ b/ZuneUI/TrackCollectionFilterType.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrackCollectionFilterType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum TrackCollectionFilterType + { + IncludeIfAnyTrackNotInCollection, + ExcludeIfAnyTrackInCollection, + } +} diff --git a/ZuneUI/TrackComparer.cs b/ZuneUI/TrackComparer.cs new file mode 100644 index 0000000..209c830 --- /dev/null +++ b/ZuneUI/TrackComparer.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrackComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections.Generic; + +namespace ZuneUI +{ + internal class TrackComparer : IComparer + { + public int Compare(MetadataEditTrack x, MetadataEditTrack y) + { + int result1 = 0; + int result2 = 0; + if (x != null && y != null) + { + int.TryParse(x.GetProperty(MetadataEditMedia.TrackNumberDescriptor).Value, out result1); + int.TryParse(y.GetProperty(MetadataEditMedia.TrackNumberDescriptor).Value, out result2); + } + return result1 - result2; + } + } +} diff --git a/ZuneUI/TrackDetails.cs b/ZuneUI/TrackDetails.cs new file mode 100644 index 0000000..c25e7c3 --- /dev/null +++ b/ZuneUI/TrackDetails.cs @@ -0,0 +1,137 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrackDetails +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class TrackDetails + { + private static int[] ColumnIndexes = new int[19] + { + 344, + 151, + 32, + 177, + 181, + 317, + 138, + 65, + 382, + 380, + 292, + 135, + 437, + 389, + 390, + 398, + 175, + 176, + 68 + }; + private static string[] DataProperties = new string[19] + { + "Title", + "Duration", + "Bitrate", + "MediaType", + "FolderName", + "FilePath", + "ArtistName", + "ContributingArtistNames", + "AlbumName", + "AlbumArtistName", + "ReleaseDate", + "DiscNumber", + "TrackNumber", + "ComposerName", + "ConductorName", + "Genre", + "FileName", + "FileSize", + "Copyright" + }; + private static string _contributingArtistFormat = Shell.LoadString(StringId.IDS_CONTRIBUTING_ARTISTS_SEPARATION_FORMAT); + private static string _contributingArtistSeperator = Shell.LoadString(StringId.IDS_CONTRIBUTING_ARTISTS_SEPARATOR); + + public static void Populate(object dataContainer, int libraryId) + { + DataProviderObject dataProviderObject = (DataProviderObject)dataContainer; + object[] fieldValues = new object[19] + { + (object) string.Empty, + (object) TimeSpan.Zero, + (object) 0, + (object) 0, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) new ArrayList(), + (object) string.Empty, + (object) string.Empty, + (object) DateTime.MinValue, + (object) 0, + (object) 0, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) 0L, + (object) string.Empty + }; + bool[] isEmptyValues = new bool[fieldValues.Length]; + ZuneLibrary.GetFieldValues(libraryId, EListType.eTrackList, TrackDetails.ColumnIndexes.Length, TrackDetails.ColumnIndexes, fieldValues, isEmptyValues, PlaylistManager.Instance.QueryContext); + for (int index = 0; index < TrackDetails.ColumnIndexes.Length; ++index) + { + if (TrackDetails.ColumnIndexes[index] == 177) + fieldValues[index] = (object)MediaDescriptions.Map((MediaType)fieldValues[index]); + dataProviderObject.SetProperty(TrackDetails.DataProperties[index], fieldValues[index]); + } + } + + public static string GetGenreHelper(DataProviderObject item) => PlaylistManager.GetFieldValue((int)item.GetProperty("LibraryId"), EListType.eTrackList, 398, ""); + + public static void SetGenreHelper(DataProviderObject item, string genre) => PlaylistManager.SetFieldValue((int)item.GetProperty("LibraryId"), EListType.eTrackList, 398, genre); + + public static Guid GetServiceId(int mediaId) => PlaylistManager.GetFieldValue(mediaId, EListType.eTrackList, 451, Guid.Empty); + + public static string ContributingArtistListToString(IList artists) => TrackDetails.ContributingArtistListToString(artists, TrackDetails._contributingArtistFormat); + + private static string ContributingArtistListToString(IList artists, string format) + { + string str = ""; + if (artists != null) + { + foreach (string artist in (IEnumerable)artists) + str = str.Length != 0 ? string.Format(format, (object)str, (object)artist) : artist; + } + return str; + } + + public static IList ContributingArtistStringToList(string contributingArtists) => TrackDetails.ContributingArtistStringToList(contributingArtists, TrackDetails._contributingArtistSeperator); + + private static IList ContributingArtistStringToList( + string contributingArtists, + string separator) + { + ArrayList arrayList = (ArrayList)null; + foreach (string str1 in contributingArtists.Split(separator.ToCharArray(0, 1))) + { + string str2 = str1.Trim(); + if (str2.Length > 0) + { + if (arrayList == null) + arrayList = new ArrayList(); + arrayList.Add((object)str2); + } + } + return (IList)arrayList; + } + } +} diff --git a/ZuneUI/TrackHelper.cs b/ZuneUI/TrackHelper.cs new file mode 100644 index 0000000..0aba326 --- /dev/null +++ b/ZuneUI/TrackHelper.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrackHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using ZuneXml; + +namespace ZuneUI +{ + public static class TrackHelper + { + public static void SetOrdinal(DataProviderObject item, int ordinal) + { + if (!(item is Track)) + return; + ((Track)item).Ordinal = ordinal; + } + } +} diff --git a/ZuneUI/TrackMetadataPropertySource.cs b/ZuneUI/TrackMetadataPropertySource.cs new file mode 100644 index 0000000..b7c6e47 --- /dev/null +++ b/ZuneUI/TrackMetadataPropertySource.cs @@ -0,0 +1,78 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrackMetadataPropertySource +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class TrackMetadataPropertySource : PropertySource + { + private static PropertySource _instance; + + protected TrackMetadataPropertySource() + { + } + + public static PropertySource Instance + { + get + { + if (TrackMetadataPropertySource._instance == null) + TrackMetadataPropertySource._instance = (PropertySource)new TrackMetadataPropertySource(); + return TrackMetadataPropertySource._instance; + } + } + + public override object Get(object media, PropertyDescriptor property) + { + TrackMetadata trackMetadata = media as TrackMetadata; + string descriptorName = property.DescriptorName; + if (descriptorName == MetadataEditMedia.s_Title.DescriptorName) + return (object)trackMetadata.TrackTitle; + if (descriptorName == MetadataEditMedia.s_Artist.DescriptorName) + return (object)trackMetadata.TrackArtist; + if (descriptorName == MetadataEditMedia.s_Genre.DescriptorName) + return (object)trackMetadata.Genre; + if (descriptorName == MetadataEditMedia.s_Composer.DescriptorName) + return (object)trackMetadata.Composer; + if (descriptorName == MetadataEditMedia.s_Conductor.DescriptorName) + return (object)trackMetadata.Conductor; + if (descriptorName == MetadataEditMedia.s_TrackNumber.DescriptorName) + return (object)trackMetadata.TrackNumber; + if (descriptorName == MetadataEditMedia.s_DiscNumber.DescriptorName) + return (object)trackMetadata.DiscNumber; + return descriptorName == MetadataEditMedia.s_MediaId.DescriptorName ? (object)trackMetadata.MediaId : (object)null; + } + + public override void Set(object media, PropertyDescriptor property, object value) + { + TrackMetadata trackMetadata = media as TrackMetadata; + string descriptorName = property.DescriptorName; + if (descriptorName == MetadataEditMedia.s_Title.DescriptorName) + trackMetadata.TrackTitle = (string)value; + else if (descriptorName == MetadataEditMedia.s_Artist.DescriptorName) + trackMetadata.TrackArtist = (string)value; + else if (descriptorName == MetadataEditMedia.s_Genre.DescriptorName) + trackMetadata.Genre = (string)value; + else if (descriptorName == MetadataEditMedia.s_Composer.DescriptorName) + trackMetadata.Composer = (string)value; + else if (descriptorName == MetadataEditMedia.s_Conductor.DescriptorName) + trackMetadata.Conductor = (string)value; + else if (descriptorName == MetadataEditMedia.s_TrackNumber.DescriptorName) + trackMetadata.TrackNumber = (int)value; + else if (descriptorName == MetadataEditMedia.s_DiscNumber.DescriptorName) + { + trackMetadata.DiscNumber = (int)value; + } + else + { + if (!(descriptorName == MetadataEditMedia.s_MediaId.DescriptorName)) + return; + trackMetadata.MediaId = (int)value; + } + } + } +} diff --git a/ZuneUI/TrackOptionGroupItem.cs b/ZuneUI/TrackOptionGroupItem.cs new file mode 100644 index 0000000..436af5b --- /dev/null +++ b/ZuneUI/TrackOptionGroupItem.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrackOptionGroupItem +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class TrackOptionGroupItem + { + private TrackMetadata _trackMetadata; + private bool _original; + + public TrackMetadata TrackMetadata + { + get => this._trackMetadata; + set => this._trackMetadata = value; + } + + public bool Original + { + get => this._original; + set => this._original = value; + } + } +} diff --git a/ZuneUI/TrackOptionsComparer.cs b/ZuneUI/TrackOptionsComparer.cs new file mode 100644 index 0000000..2bfa1ea --- /dev/null +++ b/ZuneUI/TrackOptionsComparer.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrackOptionsComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneUI +{ + public class TrackOptionsComparer : IComparer + { + public int Compare(object x, object y) + { + TrackOptionGroupItem trackOptionGroupItem1 = x as TrackOptionGroupItem; + TrackOptionGroupItem trackOptionGroupItem2 = y as TrackOptionGroupItem; + return trackOptionGroupItem1 != null && trackOptionGroupItem2 != null ? ((IComparable)trackOptionGroupItem1.Original).CompareTo((object)trackOptionGroupItem2.Original) : 1; + } + } +} diff --git a/ZuneUI/TrackSyncStatus.cs b/ZuneUI/TrackSyncStatus.cs new file mode 100644 index 0000000..007d7b1 --- /dev/null +++ b/ZuneUI/TrackSyncStatus.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrackSyncStatus +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum TrackSyncStatus + { + Syncing, + Synced, + Excluded, + } +} diff --git a/ZuneUI/TracksPanel.cs b/ZuneUI/TracksPanel.cs new file mode 100644 index 0000000..155427d --- /dev/null +++ b/ZuneUI/TracksPanel.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TracksPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class TracksPanel : MusicLibraryListPanelBase + { + internal TracksPanel(MusicLibraryPage libraryPage) + : base(libraryPage) + { + } + + public override IList SelectedLibraryIds + { + get => this.LibraryPage.SelectedTrackIds; + set => this.LibraryPage.SelectedTrackIds = value; + } + } +} diff --git a/ZuneUI/TrailerAttachment.cs b/ZuneUI/TrailerAttachment.cs new file mode 100644 index 0000000..946218e --- /dev/null +++ b/ZuneUI/TrailerAttachment.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrailerAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class TrailerAttachment : VideoAttachment + { + public const string RequestTypeString = "movietrailer"; + + public TrailerAttachment(Guid id, string title, string imageUri) + : base(id, title, string.Empty, imageUri) + { + this.AttachmentUI = "res://ZuneShellResources!SocialComposer.uix#TrailerAttachmentUI"; + this.Description = Shell.LoadString(StringId.IDS_COMPOSE_MESSAGE_TRAILER_ATTACHMENT); + } + + public override string RequestType => "movietrailer"; + } +} diff --git a/ZuneUI/TransportControlStyle.cs b/ZuneUI/TransportControlStyle.cs new file mode 100644 index 0000000..14f6de1 --- /dev/null +++ b/ZuneUI/TransportControlStyle.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TransportControlStyle +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum TransportControlStyle + { + Music, + Video, + Photo, + None, + } +} diff --git a/ZuneUI/TransportControls.cs b/ZuneUI/TransportControls.cs new file mode 100644 index 0000000..c22f924 --- /dev/null +++ b/ZuneUI/TransportControls.cs @@ -0,0 +1,2067 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TransportControls +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.PerfTrace; +using Microsoft.Zune.QuickMix; +using Microsoft.Zune.Service; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using MicrosoftZunePlayback; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using System.Threading; +using UIXControls; + +namespace ZuneUI +{ + public class TransportControls : SingletonModelItem + { + internal const long c_TicksPerSecond = 10000000; + private const long _rewindDelay = 50000000; + private const float c_overscanFactor = 0.1f; + private const int c_maxConsecutiveErrors = 5; + private const int c_ratingUnrated = -1; + private const string c_knownInvalidUri = ".:* INVALID URI *:."; + private PlayerInterop _playbackWrapper; + private BooleanChoice _shuffling; + private BooleanChoice _repeating; + private BooleanChoice _muted; + private BooleanChoice _showTotalTime; + private BooleanChoice _showNowPlayingList; + private BooleanChoice _fastforwarding; + private BooleanChoice _rewinding; + private RangedValue _volume; + private Command _play; + private Command _pause; + private Command _back; + private Command _forward; + private Command _stop; + private bool _playingVideo; + private bool _opening; + private bool _buffering; + private bool _seekEnabled; + private int _zoomScaleFactor; + private Command _fastforwardhotkey; + private Command _rewindhotkey; + private NowPlayingList _playlistPending; + private NowPlayingList _playlistCurrent; + private Microsoft.Iris.Timer _timerDelayedConfigPersist; + private VideoStream _videoStream; + private MCPlayerState _lastKnownPlayerState; + private MCTransportState _lastKnownTransportState; + private long _lastKnownPosition; + private Notification _nowPlayingNotification; + private float _currentTrackDuration; + private float _currentTrackPosition; + private float _downloadProgress; + private PlaybackTrack _lastKnownPreparedTrack; + private PlaybackTrack _lastKnownPlaybackTrack; + private List _tracksSubmittedToPlayer = new List(2); + private Dictionary _errors = new Dictionary(); + private int _consecutiveErrors; + private bool _showErrors = true; + private int _lastKnownSetUriCallID; + private static string _savedNowPlayingFilename = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Shell.LoadString(StringId.IDS_APPDATAFOLDERNAME).TrimStart('\\')), "NowPlaying.dat"); + private Shell _shellInstance; + private TransportControls.PlayerState _playerState; + private bool _streamingReportIsOpen; + private Guid _streamingReportMediaId; + private Guid _streamingReportMediaInstanceId; + private TaskbarPlayer _taskbarPlayer; + private bool _isInitialized; + private bool _resumeLastNowPlayingRequested; + private bool _shuffleAllRequested; + private JumpListPin _requestedJumpListPin; + private PlaybackContext _pagePlaybackContext; + private PlaybackTrack _currentTrack; + private bool _isPlaying; + private bool _hasPlaylist; + private bool _playlistSupportsShuffle = true; + private bool _hasPlayed; + private int _currentTrackIndex = -1; + private ArrayListDataSet _currentPlaylist; + private bool _isContextCompatible; + private bool _isStreamingVideo; + private bool _supressDownloads; + private DateTime _currentPlayStartTime = DateTime.MinValue; + private List _spectrumConfigList; + private bool _isSpectrumAvailable; + private int _lastKnownCurrentTrackRating; + private EventHandler _currentTrackRatingChangedEventHandler; + private Microsoft.Iris.Timer _isStreamingTimeoutTimer; + private bool _dontPlayMarketplaceTracks; + private int _bandwidthCapacity; + private BandwidthUpdateArgs _bandwidthUpdateInfo; + + public TransportControls() + { + this._playbackWrapper = PlayerInterop.Instance; + this._taskbarPlayer = TaskbarPlayer.Instance; + this._videoStream = new VideoStream(); + if (!this.CanRender3DVideo) + this._videoStream.DisplayDetailsChanged += new EventHandler(this.OnVideoDetailsChanged); + this._shuffling = new BooleanChoice((IModelItemOwner)this); + this._shuffling.Value = ClientConfiguration.Playback.ModeShuffle; + this._shuffling.ChosenChanged += new EventHandler(this.OnShufflingChanged); + this.UpdateShufflingDescription(); + this._repeating = new BooleanChoice((IModelItemOwner)this); + this._repeating.Value = ClientConfiguration.Playback.ModeLoop; + this._repeating.ChosenChanged += new EventHandler(this.OnRepeatingChanged); + this.UpdateRepeatingDescription(); + this._muted = new BooleanChoice((IModelItemOwner)this); + this._muted.Value = ClientConfiguration.Playback.Mute; + this._muted.ChosenChanged += new EventHandler(this.OnMutingChanged); + this.UpdateMutingDescription(); + this._showTotalTime = new BooleanChoice((IModelItemOwner)this); + this._showTotalTime.Value = ClientConfiguration.Playback.ShowTotalTime; + this._showTotalTime.ChosenChanged += new EventHandler(this.OnShowTotalTimeChanged); + this._showNowPlayingList = new BooleanChoice((IModelItemOwner)this); + this._showNowPlayingList.Value = ClientConfiguration.Playback.ShowNowPlayingList; + this._showNowPlayingList.ChosenChanged += new EventHandler(this.OnShowNowPlayingListChanged); + this.UpdateShowNowPlayingListDescription(); + this._fastforwarding = new BooleanChoice((IModelItemOwner)this); + this._fastforwarding.ChosenChanged += new EventHandler(this.OnFastforwardingChanged); + this._rewinding = new BooleanChoice((IModelItemOwner)this); + this._rewinding.ChosenChanged += new EventHandler(this.OnRewindingChanged); + float num = (float)ClientConfiguration.Playback.Volume; + if ((double)num < 0.0 || (double)num > 100.0) + num = 50f; + this._volume = new RangedValue((IModelItemOwner)this); + this._volume.MinValue = 0.0f; + this._volume.MaxValue = 100f; + this._volume.Value = num; + this._volume.PropertyChanged += new PropertyChangedEventHandler(this.OnVolumeControlChanged); + this._play = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_PLAY), new EventHandler(this.OnPlayClicked)); + this._play.Available = false; + this._pause = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_PAUSE), new EventHandler(this.OnPauseClicked)); + this._pause.Available = false; + this._back = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_PREVIOUS), new EventHandler(this.OnBackClicked)); + this._back.Available = false; + this._forward = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_NEXT), new EventHandler(this.OnForwardClicked)); + this._forward.Available = false; + this._stop = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_STOP), new EventHandler(this.OnStopClicked)); + this._stop.Available = false; + this._fastforwardhotkey = new Command((IModelItemOwner)this, new EventHandler(this.OnFastforwardHotkeyPressed)); + this._rewindhotkey = new Command((IModelItemOwner)this, new EventHandler(this.OnRewindHotkeyPressed)); + this._playbackWrapper.StatusChanged += new EventHandler(this.OnPlaybackStatusChanged); + this._playbackWrapper.TransportStatusChanged += new EventHandler(this.OnTransportStatusChanged); + this._playbackWrapper.TransportPositionChanged += new EventHandler(this.OnTransportPositionChanged); + this._playbackWrapper.UriSet += new EventHandler(this.OnUriSet); + this._playbackWrapper.AlertSent += new AnnouncementHandler(this.OnAlertSent); + this._playbackWrapper.PlayerPropertyChanged += new PlayerPropertyChangedEventHandler(this.OnPlayerPropertyChanged); + this._playbackWrapper.PlayerBandwithUpdate += new PlayerBandwithUpdateEventHandler(this.OnBandwidthCapacityUpdate); + this._lastKnownPlayerState = this._playbackWrapper.State; + this._lastKnownTransportState = this._playbackWrapper.TransportState; + this._lastKnownPosition = this._playbackWrapper.Position; + this._shellInstance = (Shell)ZuneShell.DefaultInstance; + this._shellInstance.PropertyChanged += new PropertyChangedEventHandler(this.OnShellPropertyChanged); + this._timerDelayedConfigPersist = new Microsoft.Iris.Timer(); + this._timerDelayedConfigPersist.Interval = 500; + this._timerDelayedConfigPersist.AutoRepeat = false; + this._timerDelayedConfigPersist.Tick += new EventHandler(this.OnDelayedConfigPersistTimerTick); + this._playerState = TransportControls.PlayerState.Stopped; + this._spectrumConfigList = new List(); + this._isSpectrumAvailable = false; + this.IsSeekEnabled = this._playbackWrapper.CanSeek; + Download.Instance.DownloadProgressEvent += new DownloadEventProgressHandler(this.OnDownloadProgressed); + this._lastKnownCurrentTrackRating = -1; + this._currentTrackRatingChangedEventHandler = new EventHandler(this.OnCurrentTrackRatingChanged); + this._isStreamingTimeoutTimer = new Microsoft.Iris.Timer((IModelItemOwner)this); + this._isStreamingTimeoutTimer.Interval = 30000; + this._isStreamingTimeoutTimer.AutoRepeat = false; + this._isStreamingTimeoutTimer.Tick += new EventHandler(this.OnIsStreamingTimeout); + SignIn.Instance.SignInStatusUpdatedEvent += new EventHandler(this.OnSignInEvent); + } + + protected override void OnDispose(bool fDisposing) + { + base.OnDispose(fDisposing); + if (!fDisposing) + return; + this.DisconnectAllSpectrumAnimationSources(); + this._isSpectrumAvailable = false; + Microsoft.Zune.Util.Notification.ResetNowPlaying(); + if (this.WillSaveCurrentPlaylistOnShutdown()) + { + try + { + using (Stream serializationStream = (Stream)File.Create(TransportControls._savedNowPlayingFilename)) + new BinaryFormatter().Serialize(serializationStream, (object)this._playlistCurrent); + } + catch (Exception ex) + { + } + } + else if (File.Exists(TransportControls._savedNowPlayingFilename)) + { + try + { + File.Delete(TransportControls._savedNowPlayingFilename); + } + catch (Exception ex) + { + } + } + if (this._lastKnownPlaybackTrack != null) + this._lastKnownPlaybackTrack.OnEndPlayback(false); + this._playbackWrapper.StatusChanged -= new EventHandler(this.OnPlaybackStatusChanged); + this._playbackWrapper.TransportStatusChanged -= new EventHandler(this.OnTransportStatusChanged); + this._playbackWrapper.TransportPositionChanged -= new EventHandler(this.OnTransportPositionChanged); + this._playbackWrapper.UriSet -= new EventHandler(this.OnUriSet); + this._playbackWrapper.AlertSent -= new AnnouncementHandler(this.OnAlertSent); + this._playbackWrapper.PlayerPropertyChanged -= new PlayerPropertyChangedEventHandler(this.OnPlayerPropertyChanged); + if (this._videoStream != null && !this.CanRender3DVideo) + this._videoStream.DisplayDetailsChanged -= new EventHandler(this.OnVideoDetailsChanged); + PlayerInterop.Instance.Dispose(); + if (this._videoStream != null) + { + this._videoStream.Dispose(); + this._videoStream = (VideoStream)null; + } + if (this._timerDelayedConfigPersist != null) + { + this._timerDelayedConfigPersist.Tick -= new EventHandler(this.OnDelayedConfigPersistTimerTick); + this._timerDelayedConfigPersist.Dispose(); + this._timerDelayedConfigPersist = (Microsoft.Iris.Timer)null; + } + this._shellInstance.PropertyChanged -= new PropertyChangedEventHandler(this.OnShellPropertyChanged); + Download.Instance.DownloadProgressEvent -= new DownloadEventProgressHandler(this.OnDownloadProgressed); + if (this._currentTrack != null) + this._currentTrack.RatingChanged.Invoked -= this._currentTrackRatingChangedEventHandler; + SignIn.Instance.SignInStatusUpdatedEvent -= new EventHandler(this.OnSignInEvent); + } + + private void OnSignInEvent(object sender, EventArgs args) + { + if (this._playlistCurrent != null) + this._playlistCurrent.UpdateTracks(); + if (this._playlistPending == null) + return; + this._playlistPending.UpdateTracks(); + } + + private void PersistSettings() + { + if (this._timerDelayedConfigPersist == null) + return; + this._timerDelayedConfigPersist.Stop(); + this._timerDelayedConfigPersist.Start(); + } + + private void OnDelayedConfigPersistTimerTick(object sender, EventArgs args) + { + ClientConfiguration.Playback.ModeShuffle = this._shuffling.Value; + ClientConfiguration.Playback.ModeLoop = this._repeating.Value; + ClientConfiguration.Playback.Mute = this._muted.Value; + ClientConfiguration.Playback.Volume = (int)this._volume.Value; + ClientConfiguration.Playback.ShowTotalTime = this._showTotalTime.Value; + ClientConfiguration.Playback.ShowNowPlayingList = this._showNowPlayingList.Value; + } + + private void OnCurrentTrackRatingChanged(object sender, EventArgs args) + { + int num = -1; + if (this.CurrentTrack != null && this.CurrentTrack.CanRate) + num = this.CurrentTrackRating; + if (num == this._lastKnownCurrentTrackRating) + return; + this.FirePropertyChanged("CurrentTrackRating"); + this._lastKnownCurrentTrackRating = num; + } + + public void TrackRatingUpdatedExternally(int mediaID, int newRating) + { + if (this.CurrentPlaylist == null) + return; + foreach (PlaybackTrack playbackTrack in (ListDataSet)this.CurrentPlaylist) + { + if (playbackTrack is LibraryPlaybackTrack libraryPlaybackTrack && libraryPlaybackTrack.MediaId == mediaID) + libraryPlaybackTrack.RatingUpdatedExternally(newRating); + } + } + + private void OnIsStreamingTimeout(object sender, EventArgs args) => this.SupressDownloads = false; + + private void DeserializeNowPlayingList(object arg) + { + string path = arg as string; + object args = (object)null; + if (path != null) + { + if (File.Exists(path)) + { + try + { + using (Stream serializationStream = (Stream)File.OpenRead(path)) + args = new BinaryFormatter().Deserialize(serializationStream); + } + catch (Exception ex) + { + } + } + } + if (args == null) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeserializationComplete), args); + } + + private void DeserializationComplete(object arg) + { + NowPlayingList nowPlayingList = arg as NowPlayingList; + if (this._playlistCurrent != null || nowPlayingList == null) + return; + this._playlistCurrent = nowPlayingList; + this.ShowNotification(); + this.UpdatePropertiesAndCommands(); + if (!this._resumeLastNowPlayingRequested) + return; + this.Play.Invoke(); + } + + public bool IsInitialized + { + get => this._isInitialized; + private set + { + if (this._isInitialized == value) + return; + this._isInitialized = value; + this.FirePropertyChanged(nameof(IsInitialized)); + } + } + + public bool HasPlayed + { + get => this._hasPlayed; + private set + { + if (this._hasPlayed == value) + return; + this._hasPlayed = value; + this.FirePropertyChanged(nameof(HasPlayed)); + } + } + + public event EventHandler PlaybackStopped; + + public BooleanChoice Shuffling => this._shuffling; + + public BooleanChoice Repeating => this._repeating; + + public BooleanChoice Muted => this._muted; + + public BooleanChoice ShowTotalTime => this._showTotalTime; + + public BooleanChoice ShowNowPlayingList => this._showNowPlayingList; + + public BooleanChoice Fastforwarding => this._fastforwarding; + + public BooleanChoice Rewinding => this._rewinding; + + public RangedValue Volume => this._volume; + + public Command Play => this._play; + + public Command Pause => this._pause; + + public Command Stop => this._stop; + + public Command Back => this._back; + + public Command Forward => this._forward; + + public bool Opening + { + get => this._opening; + private set + { + if (this._opening == value) + return; + this._opening = value; + this.FirePropertyChanged(nameof(Opening)); + } + } + + public bool Buffering + { + get => this._buffering; + private set + { + if (this._buffering == value) + return; + this._buffering = value; + this.FirePropertyChanged(nameof(Buffering)); + } + } + + public bool IsSeekEnabled + { + get => this._seekEnabled; + private set + { + if (this._seekEnabled == value) + return; + this._seekEnabled = value; + this.FirePropertyChanged(nameof(IsSeekEnabled)); + } + } + + public bool IsStreamingVideo + { + get => this._isStreamingVideo; + private set + { + if (this._isStreamingVideo == value) + return; + this._isStreamingVideo = value; + this.FirePropertyChanged(nameof(IsStreamingVideo)); + } + } + + public bool SupressDownloads + { + get => this._supressDownloads; + private set + { + if (this._supressDownloads == value) + return; + this._supressDownloads = value; + this.FirePropertyChanged(nameof(SupressDownloads)); + } + } + + public int ZoomScaleFactor + { + get => this._zoomScaleFactor; + set + { + this._zoomScaleFactor = value; + this.FirePropertyChanged(nameof(ZoomScaleFactor)); + } + } + + public bool Playing => this._isPlaying; + + public bool PlayingVideo + { + get => this._playingVideo; + private set + { + if (this._playingVideo == value) + return; + this._playingVideo = value; + this.FirePropertyChanged(nameof(PlayingVideo)); + } + } + + public Command FastforwardHotkey => this._fastforwardhotkey; + + public Command RewindHotkey => this._rewindhotkey; + + public int CurrentTrackIndex => this._currentTrackIndex; + + public bool WillSaveCurrentPlaylistOnShutdown() => this._playlistCurrent != null && this._playlistCurrent.CurrentTrack != null && !this._playlistCurrent.CurrentTrack.IsVideo && this._playlistCurrent.QuickMixSession == null; + + public void StartPlayingAt(PlaybackTrack track) + { + if (this._playlistCurrent == null || this._playlistCurrent.TrackList == null) + return; + int newCurrentIndex = this._playlistCurrent.TrackList.IndexOf((object)track); + if (newCurrentIndex <= -1) + return; + this.StartPlayingAt(newCurrentIndex); + } + + public void StartPlayingAt(int newCurrentIndex) + { + if (this._playlistCurrent == null) + return; + this._playlistCurrent.MoveToTrackIndex(newCurrentIndex); + if (this._playerState == TransportControls.PlayerState.Playing) + { + this.SetUriOnPlayer(); + } + else + { + this._playlistPending = this._playlistCurrent; + if (this._playerState == TransportControls.PlayerState.Paused) + this._playbackWrapper.Stop(); + else + this.PlayPendingList(); + } + } + + public void CloseCurrentSession() => this.Stop.Invoke(); + + public void SeekToPosition(float value) + { + long offsetIn100nsUnits = (long)((double)value * 10000000.0); + if (this._playbackWrapper != null) + this._playbackWrapper.SeekToAbsolutePosition(offsetIn100nsUnits); + this._rewinding.Value = false; + this._fastforwarding.Value = false; + } + + public float CurrentTrackDuration + { + get => this._currentTrackDuration; + private set + { + if ((double)this._currentTrackDuration == (double)value) + return; + this._currentTrackDuration = value; + this.FirePropertyChanged(nameof(CurrentTrackDuration)); + } + } + + public float CurrentTrackPosition + { + get => this._currentTrackPosition; + private set + { + if ((double)this._currentTrackPosition == (double)value) + return; + this._currentTrackPosition = value; + this.FirePropertyChanged(nameof(CurrentTrackPosition)); + } + } + + public float CurrentTrackDownloadProgress + { + get => this._downloadProgress; + private set + { + if ((double)this._downloadProgress == (double)value) + return; + this._downloadProgress = value; + this.FirePropertyChanged(nameof(CurrentTrackDownloadProgress)); + } + } + + public PlaybackTrack CurrentTrack => this._currentTrack; + + public int CurrentTrackRating => this.CurrentTrack == null || !this.CurrentTrack.CanRate ? 0 : this.CurrentTrack.UserRating; + + public bool ShowErrors + { + get => this._showErrors; + set + { + if (this._showErrors == value) + return; + this._showErrors = value; + this.FirePropertyChanged(nameof(ShowErrors)); + } + } + + public void ClearAllErrors() + { + if (this._errors.Count <= 0) + return; + this._errors.Clear(); + this.FirePropertyChanged("ErrorCount"); + } + + public bool IsCurrentTrack(Guid zuneMediaId) + { + PlaybackTrack currentTrack = this.CurrentTrack; + return currentTrack != null && !GuidHelper.IsEmpty(currentTrack.ZuneMediaId) && currentTrack.ZuneMediaId == zuneMediaId; + } + + public int GetErrorCode(Guid zuneMediaId) + { + if (this._errors.Count > 0) + { + foreach (KeyValuePair error in this._errors) + { + PlaybackTrack key = error.Key; + if (key != null && key.ZuneMediaId == zuneMediaId) + return error.Value; + } + } + return 0; + } + + public bool IsCurrentTrack(int id, MediaType type, Guid zuneMediaId) + { + if (!(this.CurrentTrack is LibraryPlaybackTrack currentTrack)) + return this.IsCurrentTrack(zuneMediaId); + return currentTrack.MediaId == id && currentTrack.MediaType == type; + } + + public int GetLibraryErrorCode(int id, MediaType type) + { + if (this._errors.Count > 0) + { + foreach (KeyValuePair error in this._errors) + { + if (error.Key is LibraryPlaybackTrack key && key.MediaId == id && key.MediaType == type) + return error.Value; + } + } + return 0; + } + + public int GetLibraryErrorCode(PlaybackTrack track) + { + int num; + return this._errors.TryGetValue(track, out num) ? num : 0; + } + + internal void ClearError(PlaybackTrack track) + { + if (!this._errors.Remove(track)) + return; + this.FirePropertyChanged("ErrorCount"); + } + + public int ErrorCount => this._errors.Count; + + public VideoStream VideoStream => this._videoStream; + + public bool CanRender3DVideo => Application.RenderingType != RenderingType.GDI; + + public bool HasPlaylist => this._hasPlaylist; + + public bool PlaylistSupportsShuffle => this._playlistSupportsShuffle; + + public ArrayListDataSet CurrentPlaylist => this._currentPlaylist; + + public string QuickMixTitle + { + get + { + string str = string.Empty; + if (this._playlistCurrent != null) + str = this._playlistCurrent.QuickMixTitle; + return str; + } + } + + public EQuickMixType QuickMixType + { + get + { + EQuickMixType equickMixType = EQuickMixType.eQuickMixTypeInvalid; + if (this._playlistCurrent != null) + equickMixType = this._playlistCurrent.QuickMixType; + return equickMixType; + } + } + + public bool DontPlayMarketplaceTracks + { + get => this._dontPlayMarketplaceTracks; + set + { + if (value == this._dontPlayMarketplaceTracks) + return; + this._dontPlayMarketplaceTracks = value; + if (this._playlistCurrent != null) + this._playlistCurrent.DontPlayMarketplaceTracks = this._dontPlayMarketplaceTracks; + if (this._playlistPending == null) + return; + this._playlistPending.DontPlayMarketplaceTracks = this._dontPlayMarketplaceTracks; + } + } + + public QuickMixSession QuickMixSession + { + get + { + QuickMixSession quickMixSession = (QuickMixSession)null; + if (this._playlistCurrent != null) + quickMixSession = this._playlistCurrent.QuickMixSession; + return quickMixSession; + } + } + + public bool IsPlaybackContextCompatible => this._isContextCompatible; + + public JumpListPin RequestedJumpListPin + { + get => !this.IsInitialized ? (JumpListPin)null : this._requestedJumpListPin; + set + { + if (this._requestedJumpListPin == value) + return; + this._requestedJumpListPin = value; + if (!this.IsInitialized) + return; + this.FirePropertyChanged(nameof(RequestedJumpListPin)); + } + } + + public bool ShuffleAllRequested + { + get => this.IsInitialized && this._shuffleAllRequested; + set + { + if (this._shuffleAllRequested == value) + return; + this._shuffleAllRequested = value; + if (!this.IsInitialized) + return; + this.FirePropertyChanged(nameof(ShuffleAllRequested)); + } + } + + public int BandwidthCapacity + { + get => this._bandwidthCapacity; + private set + { + this._bandwidthCapacity = value; + this.FirePropertyChanged(nameof(BandwidthCapacity)); + } + } + + public BandwidthUpdateArgs BandwidthUpdateInfo + { + get => this._bandwidthUpdateInfo; + private set + { + this._bandwidthUpdateInfo = value; + this.FirePropertyChanged(nameof(BandwidthUpdateInfo)); + } + } + + private void OnBandwidthCapacityUpdate(object sender, BandwidthUpdateArgs args) => Application.DeferredInvoke(new DeferredInvokeHandler(this.OnBandwidthCapacityUpdateOnApp), (object)args); + + private void OnBandwidthCapacityUpdateOnApp(object obj) + { + if (obj == null) + return; + BandwidthUpdateArgs bandwidthUpdateArgs = (BandwidthUpdateArgs)obj; + if (bandwidthUpdateArgs == null || bandwidthUpdateArgs.currentState != MBRHeuristicState.Playback) + return; + this.BandwidthCapacity = bandwidthUpdateArgs.RecentAverageBandwidth; + this.BandwidthUpdateInfo = bandwidthUpdateArgs; + } + + private void OnStreamingRestrictionResponse(HRESULT hr) + { + if (!hr.IsError) + return; + string title = Shell.LoadString(StringId.IDS_PLAYBACK_CANNOT_PLAY); + string description; + if (hr == HRESULT._ZEST_E_MAX_CONCURRENTSTREAMING_EXCEEDED || hr == HRESULT._ZEST_E_MULTITUNER_CONCURRENTSTREAMING_DETECTED || hr == HRESULT._ZEST_E_MEDIAINSTANCE_STREAMING_OCCUPIED) + description = Microsoft.Zune.ErrorMapperApi.ErrorMapperApi.GetMappedErrorDescriptionAndUrl(hr.Int).Description; + else + description = Shell.LoadString(StringId.IDS_PLAYBACK_UNKNOWN_CONCURRENT_STREAMING_RESTRICTION); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.Stop.Invoke(); + MessageBox.Show(title, description, (EventHandler)null); + }, DeferredInvokePriority.Low); + } + + private void ReportStreamingAction(TransportControls.PlayerState previousPlayerState) + { + if (this.CurrentTrack != null && this.CurrentTrack.IsVideo && this.CurrentTrack.IsStreaming) + { + Guid zuneMediaId = this.CurrentTrack.ZuneMediaId; + if (zuneMediaId != this._streamingReportMediaId && this._streamingReportIsOpen) + { + this._streamingReportIsOpen = false; + previousPlayerState = TransportControls.PlayerState.Stopped; + Microsoft.Zune.Service.Service.Instance.ReportStreamingAction(Microsoft.Zune.Service.EStreamingActionType.Stop, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse)); + } + if (previousPlayerState == TransportControls.PlayerState.Stopped && this._playerState == TransportControls.PlayerState.Playing) + { + this._streamingReportMediaInstanceId = this.CurrentTrack.ZuneMediaInstanceId; + if (!(this._streamingReportMediaInstanceId != Guid.Empty)) + return; + this._streamingReportIsOpen = true; + this._streamingReportMediaId = zuneMediaId; + Microsoft.Zune.Service.Service.Instance.ReportStreamingAction(Microsoft.Zune.Service.EStreamingActionType.Start, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse)); + } + else if (previousPlayerState == TransportControls.PlayerState.Paused && this._playerState == TransportControls.PlayerState.Playing) + Microsoft.Zune.Service.Service.Instance.ReportStreamingAction(Microsoft.Zune.Service.EStreamingActionType.Resume, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse)); + else if (this._playerState == TransportControls.PlayerState.Paused) + { + Microsoft.Zune.Service.Service.Instance.ReportStreamingAction(Microsoft.Zune.Service.EStreamingActionType.Pause, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse)); + } + else + { + if (this._playerState != TransportControls.PlayerState.Stopped) + return; + this._streamingReportIsOpen = false; + Microsoft.Zune.Service.Service.Instance.ReportStreamingAction(Microsoft.Zune.Service.EStreamingActionType.Stop, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse)); + } + } + else + { + if (!this._streamingReportIsOpen) + return; + this._streamingReportIsOpen = false; + Microsoft.Zune.Service.Service.Instance.ReportStreamingAction(Microsoft.Zune.Service.EStreamingActionType.Stop, this._streamingReportMediaInstanceId, new AsyncCompleteHandler(this.OnStreamingRestrictionResponse)); + } + } + + private void SetPlayerState(TransportControls.PlayerState stateNew) + { + TransportControls.PlayerState playerState = this._playerState; + if (stateNew != this._playerState) + { + this._playerState = stateNew; + if (this._playerState == TransportControls.PlayerState.Stopped) + { + this._rewinding.Value = false; + this._fastforwarding.Value = false; + ++this._lastKnownSetUriCallID; + this.FirePropertyChanged("PlaybackStopped"); + if (this.PlaybackStopped != null) + this.PlaybackStopped((object)this, (EventArgs)null); + } + } + this.UpdatePropertiesAndCommands(); + this.ReportStreamingAction(playerState); + } + + public void PlayItem( + object item, + PlayNavigationOptions playNavigationOptions, + PlaybackContext playbackContext) + { + ArrayListDataSet arrayListDataSet = new ArrayListDataSet(); + arrayListDataSet.Add(item); + this.PlayItemsWorker((IList)arrayListDataSet, -1, true, playNavigationOptions, playbackContext, (ContainerPlayMarker)null); + } + + public void PlayItem(object item) => this.PlayItem(item, PlayNavigationOptions.NavigateVideosToNowPlaying); + + public void PlayItem(object item, PlayNavigationOptions playNavigationOptions) + { + ArrayListDataSet arrayListDataSet = new ArrayListDataSet(); + arrayListDataSet.Add(item); + this.PlayItemsWorker((IList)arrayListDataSet, -1, true, playNavigationOptions, (ContainerPlayMarker)null); + } + + public void PlayItem(object item, PlaybackContext playbackContext) + { + ArrayListDataSet arrayListDataSet = new ArrayListDataSet(); + arrayListDataSet.Add(item); + this.PlayItemsWorker((IList)arrayListDataSet, -1, true, PlayNavigationOptions.NavigateVideosToNowPlaying, playbackContext, (ContainerPlayMarker)null); + } + + public void PlayItems(IList items) => this.PlayItemsWorker(items, -1, true, PlayNavigationOptions.NavigateVideosToNowPlaying, (ContainerPlayMarker)null); + + public void PlayItems(IList items, PlayNavigationOptions playNavigationOptions) => this.PlayItemsWorker(items, -1, true, playNavigationOptions, (ContainerPlayMarker)null); + + public void PlayItems( + IList items, + PlayNavigationOptions playNavigationOptions, + ContainerPlayMarker containerPlayMarker) + { + this.PlayItemsWorker(items, -1, true, playNavigationOptions, containerPlayMarker); + } + + public void PlayItems( + IList items, + PlayNavigationOptions playNavigationOptions, + PlaybackContext playbackContext) + { + this.PlayItemsWorker(items, -1, true, playNavigationOptions, playbackContext, (ContainerPlayMarker)null); + } + + public void PlayItems(IList items, PlaybackContext playbackContext) => this.PlayItemsWorker(items, -1, true, PlayNavigationOptions.NavigateVideosToNowPlaying, playbackContext, (ContainerPlayMarker)null); + + public void PlayItems(IList items, int startIndex) => this.PlayItemsWorker(items, startIndex, true, PlayNavigationOptions.NavigateVideosToNowPlaying, (ContainerPlayMarker)null); + + public void PlayItems( + IList items, + int startIndex, + PlayNavigationOptions playNavigationOptions, + ContainerPlayMarker containerPlayMarker) + { + this.PlayItemsWorker(items, startIndex, true, PlayNavigationOptions.NavigateVideosToNowPlaying, containerPlayMarker); + } + + public void AddToNowPlaying(IList items) + { + int count = this.PlayItemsWorker(items, -1, false, PlayNavigationOptions.NavigateVideosToNowPlaying, (ContainerPlayMarker)null); + if (count <= 0) + return; + PlaylistManager.Instance.NotifyItemsAdded(-1, count); + } + + private int PlayItemsWorker( + IList items, + int startIndex, + bool clearQueue, + PlayNavigationOptions playNavigationOptions, + ContainerPlayMarker containerPlayMarker) + { + return this.PlayItemsWorker(items, startIndex, clearQueue, playNavigationOptions, this._shellInstance.CurrentPage.PlaybackContext, containerPlayMarker); + } + + private int PlayItemsWorker( + IList items, + int startIndex, + bool clearQueue, + PlayNavigationOptions playNavigationOptions, + PlaybackContext playbackContext, + ContainerPlayMarker containerPlayMarker) + { + Microsoft.Zune.PerfTrace.PerfTrace.TraceUICollectionEvent(UICollectionEvent.PlayRequestIssued, ""); + bool flag = this._playlistCurrent != null; + int num; + if (clearQueue || !flag) + { + if (clearQueue || this._playlistPending == null) + { + if (this._playlistPending != null) + this._playlistPending.Dispose(); + this._playlistPending = new NowPlayingList(items, startIndex, playbackContext, playNavigationOptions, this._shuffling.Value, containerPlayMarker, this._dontPlayMarketplaceTracks); + num = this._playlistPending.Count; + } + else + num = this._playlistPending.AddItems(items); + if (playbackContext == PlaybackContext.QuickMix) + { + if (this._lastKnownTransportState == MCTransportState.Playing || this._lastKnownTransportState == MCTransportState.Paused) + this._playbackWrapper.Stop(); + else + this._playlistPending.PlayWhenReady = true; + } + else if (this._playlistPending.Count == 0) + { + this._playlistPending.Dispose(); + this._playlistPending = (NowPlayingList)null; + this.Stop.Invoke(); + } + else if (flag && (this._lastKnownTransportState == MCTransportState.Playing || this._lastKnownTransportState == MCTransportState.Paused)) + this._playbackWrapper.Stop(); + else + this.PlayPendingList(); + } + else + { + num = this._playlistCurrent.AddItems(items); + if (this._playlistPending != null) + this._playlistPending.Dispose(); + this._playlistPending = (NowPlayingList)null; + this.UpdateNextTrack(); + } + return num; + } + + internal void PlayPendingList() + { + if (this._playlistPending == null) + return; + if (this._playlistCurrent != null && this._playlistCurrent != this._playlistPending) + this._playlistCurrent.Dispose(); + this._playlistCurrent = this._playlistPending; + this._playlistPending = (NowPlayingList)null; + this._playlistCurrent.SetShuffling(this._shuffling.Value); + this._playlistCurrent.SetRepeating(this._repeating.Value); + this._consecutiveErrors = 0; + if (this._errors.Count > 0) + { + this.FirePropertyChanged("ErrorCount"); + this._errors.Clear(); + } + this.SetPlayerState(TransportControls.PlayerState.Playing); + this.SetUriOnPlayer(); + bool flag1 = false; + if (this._playlistCurrent != null) + { + PlaybackTrack currentTrack = this._playlistCurrent.CurrentTrack; + PlayNavigationOptions navigationOptions = this._playlistCurrent.PlayNavigationOptions; + bool flag2 = false; + if (currentTrack != null && currentTrack.IsVideo) + flag1 = true; + switch (navigationOptions) + { + case PlayNavigationOptions.None: + if (flag2) + { + NowPlayingLand.NavigateToLand(navigationOptions == PlayNavigationOptions.NavigateToNowPlayingWithMix, true); + break; + } + break; + case PlayNavigationOptions.NavigateVideosToNowPlaying: + if (flag1) + { + flag2 = true; + goto case PlayNavigationOptions.None; + } + else + goto case PlayNavigationOptions.None; + default: + flag2 = true; + this._playlistCurrent.PlayNavigationOptions = PlayNavigationOptions.NavigateVideosToNowPlaying; + goto case PlayNavigationOptions.None; + } + } + this.PlayingVideo = flag1; + } + + public void RemoveFromNowPlaying(IList indices) + { + if (this._playlistCurrent == null) + return; + bool flag = this._playlistCurrent.Remove(indices); + if (this._playlistCurrent.Count == 0) + this.Stop.Invoke(); + else if (flag) + this.SetUriOnPlayer(); + else + this.UpdateNextTrack(); + } + + public void ReorderNowPlaying(IList indices, int targetIndex) + { + if (this._playlistCurrent == null) + return; + this._playlistCurrent.Reorder(indices, targetIndex); + this.UpdateNextTrack(); + } + + public IList GetNextTracks(int count) + { + IList list = (IList)null; + if (this._playlistCurrent != null) + list = this._playlistCurrent.GetNextTracks(count); + return list; + } + + public IList CreateAlbumListForBackground(IList allAlbums, int totalDesired) + { + List objectList1 = new List(totalDesired); + Dictionary dictionary = new Dictionary(); + if (this._playlistCurrent != null) + { + int num = Math.Min(this._playlistCurrent.Count, totalDesired); + for (int itemIndex = 0; itemIndex < num; ++itemIndex) + { + if (this._playlistCurrent.TrackList[itemIndex] is LibraryPlaybackTrack track && track.MediaType == MediaType.Track) + dictionary[track.AlbumLibraryId] = (object)null; + } + } + List objectList2 = new List(totalDesired); + for (int index = 0; index < allAlbums.Count; ++index) + { + DataProviderObject allAlbum = (DataProviderObject)allAlbums[index]; + int property = (int)allAlbum.GetProperty("LibraryId"); + if ((bool)allAlbum.GetProperty("HasAlbumArt")) + { + if (dictionary.ContainsKey(property)) + objectList1.Add((object)allAlbum); + else if (objectList2.Count < totalDesired) + objectList2.Add((object)allAlbum); + } + if (objectList1.Count >= totalDesired) + break; + } + for (int index = 0; index < objectList2.Count && objectList1.Count < totalDesired; ++index) + objectList1.Add(objectList2[index]); + if (objectList1.Count == 0) + return (IList)null; + foreach (object album in objectList1) + this.DisableSlowDataThumbnailExtraction(album); + int num1 = 0; + while (objectList1.Count < totalDesired) + objectList1.Add(objectList1[num1++]); + Random random = new Random(); + for (int index1 = objectList1.Count - 1; index1 > 0; --index1) + { + int index2 = random.Next(index1 + 1); + object obj = objectList1[index2]; + objectList1[index2] = objectList1[index1]; + objectList1[index1] = obj; + } + return (IList)new ListDataSet((IList)objectList1); + } + + public void DisableSlowDataThumbnailExtraction(object album) + { + if (!(album is LibraryDataProviderItemBase providerItemBase)) + return; + providerItemBase.SetSlowDataThumbnailExtraction(false); + } + + public void Phase2Init() + { + if (!this.CanRender3DVideo) + this._playbackWrapper.WindowHandle = Application.Window.Handle; + else + this._playbackWrapper.DynamicImage = this._videoStream.StreamID; + ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncPhase2Init), (object)null); + } + + private void AsyncPhase2Init(object arg) + { + this._playbackWrapper.Initialize(); + Application.DeferredInvoke(new DeferredInvokeHandler(this.CompletePhase2Init), (object)null); + } + + private void CompletePhase2Init(object obj) + { + this._playbackWrapper.Volume = (int)this._volume.Value; + this._playbackWrapper.Mute = this._muted.Value; + this._isSpectrumAvailable = true; + this.ConnectAllSpectrumAnimationSources(); + this._taskbarPlayer.Initialize(Application.Window.Handle, new TaskbarPlayerCommandHandler(this.OnTaskbarPlayerCommand)); + this.IsInitialized = true; + ThreadPool.QueueUserWorkItem(new WaitCallback(this.DeserializeNowPlayingList), (object)TransportControls._savedNowPlayingFilename); + if (this.RequestedJumpListPin != null) + this.FirePropertyChanged("RequestedJumpListPin"); + if (!this.ShuffleAllRequested) + return; + this.FirePropertyChanged("ShuffleAllRequested"); + } + + private void OnTaskbarPlayerCommand(ETaskbarPlayerCommand command, int value) + { + switch (command) + { + case ETaskbarPlayerCommand.PC_Connect: + this.UpdateTaskbarPlayer(); + break; + case ETaskbarPlayerCommand.PC_Play: + this.Play.Invoke(); + break; + case ETaskbarPlayerCommand.PC_Pause: + this.Pause.Invoke(); + break; + case ETaskbarPlayerCommand.PC_Forward: + this.Forward.Invoke(); + break; + case ETaskbarPlayerCommand.PC_Back: + this.Back.Invoke(); + break; + case ETaskbarPlayerCommand.PC_Rate: + if (this.CurrentTrack == null || !this.CurrentTrack.CanRate) + break; + switch ((ETaskbarPlayerState)value) + { + case ETaskbarPlayerState.PS_RatingNotRated: + this.CurrentTrack.UserRating = 0; + break; + case ETaskbarPlayerState.PS_RatingLoveIt: + this.CurrentTrack.UserRating = 8; + break; + case ETaskbarPlayerState.PS_RatingHateIt: + this.CurrentTrack.UserRating = 2; + break; + } + this.UpdateTaskbarPlayer(); + break; + } + } + + private void UpdateTaskbarPlayer() + { + ETaskbarPlayerState etaskbarPlayerState1 = (ETaskbarPlayerState)(0 | (this._playerState == TransportControls.PlayerState.Playing ? 2 : 0) | (this._playerState == TransportControls.PlayerState.Paused ? 4 : 0) | (this._playerState == TransportControls.PlayerState.Stopped ? 1 : 0)); + ETaskbarPlayerState etaskbarPlayerState2; + if (this.CurrentTrack != null && this.CurrentTrack.CanRate) + { + RatingConstants userRating = (RatingConstants)this.CurrentTrack.UserRating; + etaskbarPlayerState2 = userRating != RatingConstants.Unrated ? (userRating > RatingConstants.MaxHateIt ? etaskbarPlayerState1 | ETaskbarPlayerState.PS_RatingLoveIt : etaskbarPlayerState1 | ETaskbarPlayerState.PS_RatingHateIt) : etaskbarPlayerState1 | ETaskbarPlayerState.PS_RatingNotRated; + } + else + etaskbarPlayerState2 = etaskbarPlayerState1 | ETaskbarPlayerState.PS_RatingNotRated; + ETaskbarPlayerState state = etaskbarPlayerState2 | (this.Play.Available ? ETaskbarPlayerState.PS_CanPlay : (ETaskbarPlayerState)0) | (this.Pause.Available ? ETaskbarPlayerState.PS_CanPause : (ETaskbarPlayerState)0) | (this.Forward.Available ? ETaskbarPlayerState.PS_CanForward : (ETaskbarPlayerState)0) | (this.Back.Available ? ETaskbarPlayerState.PS_CanBack : (ETaskbarPlayerState)0); + if (this.CurrentTrack != null && this.CurrentTrack.CanRate) + state |= ETaskbarPlayerState.PS_CanRate; + this._taskbarPlayer.UpdateToolbar(state); + } + + public int CreateSpectrumAnimationSource( + int numBands, + bool outputFrequencyData, + bool outputWaveformData, + bool enableStereoOutput) + { + Dictionary dictionary = new Dictionary(); + for (int index = 0; index < numBands; ++index) + { + if (outputFrequencyData) + { + if (!enableStereoOutput) + { + dictionary[string.Format("Frequency{0}", (object)index)] = index; + } + else + { + dictionary[string.Format("FrequencyL{0}", (object)index)] = index; + dictionary[string.Format("FrequencyR{0}", (object)index)] = index + 1024; + } + } + if (outputWaveformData) + { + if (!enableStereoOutput) + { + dictionary[string.Format("Waveform{0}", (object)index)] = index + 2048; + } + else + { + dictionary[string.Format("WaveformL{0}", (object)index)] = index + 2048; + dictionary[string.Format("WaveformR{0}", (object)index)] = index + 3072; + } + } + } + int externalAnimationInput = Application.CreateExternalAnimationInput((IDictionary)dictionary); + TransportControls.SpectrumOutputConfig spectrumOutputConfig = new TransportControls.SpectrumOutputConfig(); + spectrumOutputConfig.SourceId = (uint)externalAnimationInput; + spectrumOutputConfig.NumBands = (uint)numBands; + spectrumOutputConfig.Frequency = outputFrequencyData; + spectrumOutputConfig.Waveform = outputWaveformData; + spectrumOutputConfig.Stereo = enableStereoOutput; + spectrumOutputConfig.IsConnected = this._isSpectrumAvailable; + this._spectrumConfigList.Add(spectrumOutputConfig); + if (this._isSpectrumAvailable) + this._playbackWrapper.ConnectAnimationsToSpectrumAnalyzer(spectrumOutputConfig.SourceId, spectrumOutputConfig.NumBands, spectrumOutputConfig.Frequency, spectrumOutputConfig.Waveform, spectrumOutputConfig.Stereo); + return externalAnimationInput; + } + + public void DisposeSpectrumAnimationSource(int inputSourceId) + { + if (inputSourceId <= 0) + return; + for (int index = 0; index < this._spectrumConfigList.Count; ++index) + { + TransportControls.SpectrumOutputConfig spectrumConfig = this._spectrumConfigList[index]; + if ((long)spectrumConfig.SourceId == (long)inputSourceId) + { + if (spectrumConfig.IsConnected) + { + this._playbackWrapper.DisconnectAnimationsFromSpectrumAnalyzer(spectrumConfig.SourceId); + spectrumConfig.IsConnected = false; + } + Application.DisposeExternalAnimationInput(inputSourceId); + this._spectrumConfigList.RemoveAt(index); + break; + } + } + } + + public void ConnectAllSpectrumAnimationSources() + { + for (int index = 0; index < this._spectrumConfigList.Count; ++index) + { + TransportControls.SpectrumOutputConfig spectrumConfig = this._spectrumConfigList[index]; + if (!spectrumConfig.IsConnected) + { + this._playbackWrapper.ConnectAnimationsToSpectrumAnalyzer(spectrumConfig.SourceId, spectrumConfig.NumBands, spectrumConfig.Frequency, spectrumConfig.Waveform, spectrumConfig.Stereo); + spectrumConfig.IsConnected = true; + this._spectrumConfigList[index] = spectrumConfig; + } + } + } + + public void DisconnectAllSpectrumAnimationSources() + { + if (!this._isSpectrumAvailable) + return; + for (int index = 0; index < this._spectrumConfigList.Count; ++index) + { + TransportControls.SpectrumOutputConfig spectrumConfig = this._spectrumConfigList[index]; + if (spectrumConfig.IsConnected) + { + this._playbackWrapper.DisconnectAnimationsFromSpectrumAnalyzer(spectrumConfig.SourceId); + spectrumConfig.IsConnected = false; + this._spectrumConfigList[index] = spectrumConfig; + } + } + } + + public void ResumeLastNowPlayingHandler() + { + if (!this.IsInitialized) + { + this._resumeLastNowPlayingRequested = true; + } + else + { + if (this._isPlaying) + return; + this.Play.Invoke(); + } + } + + private void OnShellPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "CurrentPage")) + return; + this._pagePlaybackContext = this._shellInstance.CurrentPage.PlaybackContext; + this.UpdatePropertiesAndCommands(); + } + + private void OnDownloadProgressed(Guid zuneMediaId, float percent) + { + if (this.CurrentTrack == null || !(this.CurrentTrack.ZuneMediaId == zuneMediaId)) + return; + this.CurrentTrackDownloadProgress = percent; + } + + private void OnShufflingChanged(object sender, EventArgs e) + { + if (this._playlistCurrent != null) + { + this._playlistCurrent.SetShuffling(this._shuffling.Value); + this.UpdateNextTrack(); + } + this.UpdateShufflingDescription(); + this.PersistSettings(); + SQMLog.Log(SQMDataId.ShuffleClicks, 1); + } + + private void UpdateShufflingDescription() => this._shuffling.Description = Shell.LoadString(!this._shuffling.Value ? StringId.IDS_SHUFFLE_ON : StringId.IDS_SHUFFLE_OFF); + + private void OnRepeatingChanged(object sender, EventArgs e) + { + if (this._playlistCurrent != null) + { + this._playlistCurrent.SetRepeating(this._repeating.Value); + this.UpdateNextTrack(); + } + SQMLog.Log(SQMDataId.RepeatClicks, 1); + this.UpdateRepeatingDescription(); + this.PersistSettings(); + } + + private void UpdateRepeatingDescription() => this._repeating.Description = Shell.LoadString(!this._repeating.Value ? StringId.IDS_REPEAT_ON : StringId.IDS_REPEAT_OFF); + + private void OnMutingChanged(object sender, EventArgs e) + { + this.UpdateMutingDescription(); + this._playbackWrapper.Mute = this._muted.Value; + SQMLog.Log(SQMDataId.VolumeMuteClicks, 1); + this.PersistSettings(); + } + + private void UpdateMutingDescription() => this._muted.Description = Shell.LoadString(!this._muted.Value ? StringId.IDS_MUTE : StringId.IDS_UNMUTE); + + private void OnShowTotalTimeChanged(object sender, EventArgs e) => this.PersistSettings(); + + private void OnShowNowPlayingListChanged(object sender, EventArgs e) + { + this.UpdateShowNowPlayingListDescription(); + this.PersistSettings(); + } + + private void UpdateShowNowPlayingListDescription() => this._showNowPlayingList.Description = Shell.LoadString(!this._showNowPlayingList.Value ? StringId.IDS_NOWPLAYINGLIST_ON : StringId.IDS_NOWPLAYINGLIST_OFF); + + private void OnPlayingChanged(object sender, EventArgs e) + { + } + + private void OnPlayClicked(object sender, EventArgs e) + { + if (!this._play.Available) + return; + SQMLog.Log(SQMDataId.PlayClicks, 1); + if (this.Playing || this._playlistCurrent == null) + return; + if (this._lastKnownPlayerState != MCPlayerState.Closed) + { + this.SetPlayerState(TransportControls.PlayerState.Playing); + this._playbackWrapper.Play(); + if (!this.PlayingVideo || this._playlistCurrent.PlayNavigationOptions != PlayNavigationOptions.NavigateVideosToNowPlaying) + return; + NowPlayingLand.NavigateToLand(); + } + else + { + if (this._playlistPending != null) + this._playlistPending.Dispose(); + this._playlistPending = this._playlistCurrent; + this.PlayPendingList(); + } + } + + private void OnPauseClicked(object sender, EventArgs e) + { + if (!this._pause.Available) + return; + SQMLog.Log(SQMDataId.PauseClicks, 1); + if (!this.Playing) + return; + this.SetPlayerState(TransportControls.PlayerState.Paused); + this._playbackWrapper.Pause(); + } + + private void OnStopClicked(object sender, EventArgs e) + { + if (!this._stop.Available) + return; + SQMLog.Log(SQMDataId.StopClicks, 1); + if (this._playlistPending != null) + this._playlistPending.Dispose(); + this._playlistPending = (NowPlayingList)null; + if (this._playlistCurrent != null) + this._playlistCurrent.Dispose(); + this._playlistCurrent = (NowPlayingList)null; + if (this._playerState != TransportControls.PlayerState.Stopped) + { + this.SetPlayerState(TransportControls.PlayerState.Stopped); + this._playbackWrapper.Stop(); + } + else + this.UpdatePropertiesAndCommands(); + } + + private void OnBackClicked(object sender, EventArgs e) + { + if (!this._back.Available || this._playlistCurrent == null) + return; + SQMLog.Log(SQMDataId.SkipBackwardClicks, 1); + if (this._lastKnownPosition > 50000000L || !this._playlistCurrent.CanRetreat) + { + this._playbackWrapper.SeekToAbsolutePosition(0L); + } + else + { + this._playlistCurrent.Retreat(); + this.SetUriOnPlayer(); + } + } + + private void OnForwardClicked(object sender, EventArgs e) + { + if (!this._forward.Available || this._playlistCurrent == null) + return; + SQMLog.Log(SQMDataId.SkipForwardClicks, 1); + if (this._currentTrack != null && this._currentTrack.IsVideo) + return; + if (this._lastKnownPlaybackTrack != null) + this._lastKnownPlaybackTrack.OnSkip(); + if (this._playlistCurrent.CanAdvance) + { + this._playlistCurrent.Advance(); + this.SetUriOnPlayer(); + } + else + { + this.SetPlayerState(TransportControls.PlayerState.Stopped); + this._playbackWrapper.Stop(); + } + } + + private void OnFastforwardingChanged(object sender, EventArgs e) + { + if ((this._currentTrack == null || !this._currentTrack.IsVideo || this._playbackWrapper.CanChangeVideoRate) && this._fastforwarding.Value) + { + this._rewinding.Value = false; + this._playbackWrapper.Rate = 5f; + } + else + this._playbackWrapper.Rate = 1f; + } + + private void OnRewindingChanged(object sender, EventArgs e) + { + if ((this._currentTrack == null || !this._currentTrack.IsVideo || this._playbackWrapper.CanChangeVideoRate) && this._rewinding.Value) + { + this._fastforwarding.Value = false; + this._playbackWrapper.Rate = -5f; + } + else + this._playbackWrapper.Rate = 1f; + } + + private void OnFastforwardHotkeyPressed(object sender, EventArgs e) => this._fastforwarding.Value = !this._fastforwarding.Value; + + private void OnRewindHotkeyPressed(object sender, EventArgs e) => this._rewinding.Value = !this._rewinding.Value; + + private void OnPlaybackStatusChanged(object sender, EventArgs e) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredPlaybackStatusChanged), (object)new object[2] + { + (object) this._playbackWrapper.State, + (object) this._playbackWrapper.EndOfMedia + }); + + private void OnTransportStatusChanged(object sender, EventArgs e) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredTransportStatusChanged), (object)new object[3] + { + (object) this._playbackWrapper.TransportState, + (object) this._playbackWrapper.EndOfMedia, + (object) this._playbackWrapper.CanSeek + }); + + private void OnTransportPositionChanged(object sender, EventArgs e) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredTransportPositionChanged), (object)this._playbackWrapper.Position); + + private void OnUriSet(object sender, EventArgs e) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredUriSet), (object)new object[2] + { + (object) this._playbackWrapper.CurrentUri, + (object) this._playbackWrapper.CurrentUriID + }); + + private void OnAlertSent(Announcement alert) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredAlertHandler), (object)alert); + + private void OnPlayerPropertyChanged(object sender, PlayerPropertyChangedEventArgs e) + { + if (e.Key == "presentationinfo") + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredPresentationInfoChangedHandler), e.Value); + else if (e.Key == "volumeinfo") + { + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredVolumeInfoChangedHandler), e.Value); + } + else + { + if (!(e.Key == "canchangevideorate")) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredCanChangeVideoRateHandler), e.Value); + } + } + + private void OnVolumeControlChanged(object sender, PropertyChangedEventArgs e) + { + if (!(e.PropertyName == "Value")) + return; + this._muted.Value = false; + this._playbackWrapper.Mute = false; + this._playbackWrapper.Volume = (int)this._volume.Value; + SQMLog.Log(SQMDataId.VolumeAdjustmentClicks, 1); + this.PersistSettings(); + } + + private void OnVideoDetailsChanged(object sender, EventArgs args) + { + this._playbackWrapper.VideoPosition = new VideoWindow(this._videoStream.DisplayPosition.X, this._videoStream.DisplayPosition.Y, this._videoStream.DisplayPosition.X + this._videoStream.DisplaySize.Width, this._videoStream.DisplayPosition.Y + this._videoStream.DisplaySize.Height); + this._playbackWrapper.ShowGDIVideo = this._videoStream.DisplayVisibility; + } + + private void DeferredPlaybackStatusChanged(object obj) + { + if (this.IsDisposed) + return; + object[] objArray = (object[])obj; + MCPlayerState mcPlayerState = (MCPlayerState)objArray[0]; + bool endOfMedia = (bool)objArray[1]; + bool flag = false; + switch (mcPlayerState) + { + case MCPlayerState.Closed: + if (this.Playing) + { + this.SetUriOnPlayer(); + break; + } + break; + case MCPlayerState.Open: + this._rewinding.Value = false; + this._fastforwarding.Value = false; + flag = true; + break; + case MCPlayerState.Built: + if (this.Playing && this._lastKnownPlaybackTrack != null) + { + this._lastKnownPlaybackTrack.OnEndPlayback(endOfMedia); + this._lastKnownPlaybackTrack = this._lastKnownPreparedTrack; + this._lastKnownPreparedTrack = (PlaybackTrack)null; + if (this._lastKnownPlaybackTrack != null) + this._lastKnownPlaybackTrack.OnBeginPlayback(this._playbackWrapper); + } + this.CurrentTrackDuration = this._playbackWrapper.Duration >= 0L ? (float)this._playbackWrapper.Duration / 1E+07f : 0.0f; + break; + } + this._lastKnownPlayerState = mcPlayerState; + if (this._opening == flag) + return; + this.Opening = flag; + } + + private void ShowNotification() + { + if (this._nowPlayingNotification == null) + { + this._nowPlayingNotification = (Notification)new NowPlayingNotification(); + NotificationArea.Instance.Add(this._nowPlayingNotification); + } + else + NotificationArea.Instance.ForceToFront(this._nowPlayingNotification); + } + + private void HideNotification() + { + if (this._nowPlayingNotification == null) + return; + NotificationArea.Instance.Remove(this._nowPlayingNotification); + this._nowPlayingNotification = (Notification)null; + } + + public void ShowPreparingNotification() + { + this.HideNotification(); + this.HidePreparingNotification(false); + NotificationArea.Instance.Add((Notification)new PreparingPlayNotification()); + } + + public void HidePreparingNotification() => this.HidePreparingNotification(true); + + private void HidePreparingNotification(bool restoreNowPlayingNotification) + { + NotificationArea.Instance.RemoveAll(NotificationTask.PreparingPlay, NotificationState.Normal); + if (!restoreNowPlayingNotification || this._playlistCurrent == null) + return; + this.ShowNotification(); + } + + private void DeferredTransportStatusChanged(object obj) + { + if (this.IsDisposed) + return; + object[] objArray = (object[])obj; + MCTransportState mcTransportState = (MCTransportState)objArray[0]; + bool endOfMedia = (bool)objArray[1]; + this.IsSeekEnabled = (bool)objArray[2]; + if (mcTransportState == MCTransportState.Buffering) + { + this.Buffering = true; + this.UpdatePropertiesAndCommands(); + } + else + { + if (this.Buffering) + { + this.Buffering = false; + this.UpdatePropertiesAndCommands(); + } + switch (mcTransportState) + { + case MCTransportState.Stopped: + bool flag = this._playlistCurrent != null && this._playlistCurrent.Count == 1 && this._repeating.Value && endOfMedia; + if (this._lastKnownPlaybackTrack != null) + { + this._lastKnownPlaybackTrack.OnEndPlayback(endOfMedia); + if (!flag) + this._lastKnownPlaybackTrack = (PlaybackTrack)null; + } + if (this._playlistPending != null) + { + if (this._playlistPending.TrackList != null && this._playlistPending.TrackList.Count > 0) + { + this.PlayPendingList(); + break; + } + this.SetPlayerState(TransportControls.PlayerState.Stopped); + this._playlistPending.PlayWhenReady = true; + break; + } + if (this._lastKnownPreparedTrack != null) + { + this._lastKnownPlaybackTrack = this._lastKnownPreparedTrack; + this._lastKnownPlaybackTrack.OnBeginPlayback(this._playbackWrapper); + if (this.Playing) + this._playbackWrapper.Play(); + this._lastKnownPreparedTrack = (PlaybackTrack)null; + break; + } + if (flag && this._lastKnownPlaybackTrack != null) + { + this._lastKnownPlaybackTrack.OnBeginPlayback(this._playbackWrapper); + this._playbackWrapper.SeekToAbsolutePosition(0L); + this._playbackWrapper.Play(); + break; + } + if (this._playlistCurrent != null) + this._playlistCurrent.ResetForReplay(); + this.SetPlayerState(TransportControls.PlayerState.Stopped); + this._playbackWrapper.Close(); + break; + case MCTransportState.Playing: + Microsoft.Zune.PerfTrace.PerfTrace.TraceUICollectionEvent(UICollectionEvent.PlayRequestComplete, ""); + break; + } + } + this._lastKnownTransportState = mcTransportState; + } + + private void DeferredTransportPositionChanged(object obj) + { + if (this.IsDisposed) + return; + this._lastKnownPosition = (long)obj; + this.CurrentTrackPosition = (float)this._lastKnownPosition / 1E+07f; + if (this._lastKnownPlaybackTrack == null) + return; + if (this._lastKnownPosition > 0L) + this._consecutiveErrors = 0; + this._lastKnownPlaybackTrack.OnPositionChanged(this._lastKnownPosition); + } + + private void DeferredUriSet(object obj) + { + if (this.IsDisposed) + return; + object[] objArray = (object[])obj; + string str = (string)objArray[0]; + int num1 = (int)objArray[1]; + this._lastKnownPreparedTrack = (PlaybackTrack)null; + int num2; + for (num2 = 0; num2 < this._tracksSubmittedToPlayer.Count; ++num2) + { + PlaybackTrack playbackTrack = this._tracksSubmittedToPlayer[num2]; + if (playbackTrack.PlaybackID == num1) + { + this._lastKnownPreparedTrack = playbackTrack; + ++num2; + break; + } + } + this._tracksSubmittedToPlayer.RemoveRange(0, num2); + if (this._lastKnownPreparedTrack == null || this._tracksSubmittedToPlayer.Count != 0) + return; + if (this._playlistCurrent != null) + this._playlistCurrent.SyncCurrentTrackTo(this._lastKnownPreparedTrack); + this.UpdateNextTrack(); + } + + private void DeferredAlertHandler(object obj) + { + if (this.IsDisposed || !(obj is Announcement announcement)) + return; + PlaybackTrack playbackTrack = (PlaybackTrack)null; + if (this.CurrentTrack != null && this.CurrentTrack.PlaybackID == announcement.PlaybackID) + { + playbackTrack = this.CurrentTrack; + } + else + { + for (int index = this._tracksSubmittedToPlayer.Count - 1; index >= 0; --index) + { + if (this._tracksSubmittedToPlayer[index].PlaybackID == announcement.PlaybackID) + { + playbackTrack = this._tracksSubmittedToPlayer[index]; + break; + } + } + } + if (playbackTrack != null) + { + ++this._consecutiveErrors; + this._errors[playbackTrack] = announcement.HResult; + if (this._playlistCurrent != null) + this._playlistCurrent.SyncCurrentTrackTo(playbackTrack); + this.FirePropertyChanged("ErrorCount"); + } + bool flag = (HRESULT)announcement.HResult == HRESULT._NS_E_CD_BUSY; + if (this._consecutiveErrors < 5 && !flag && this.Playing && (this._playlistCurrent != null && this._playlistCurrent.CanAdvance)) + { + this._playlistCurrent.Advance(); + this._playbackWrapper.Close(); + } + else + { + this.SetPlayerState(TransportControls.PlayerState.Stopped); + this._playbackWrapper.Close(); + if (this._lastKnownPlaybackTrack != null) + { + this._lastKnownPlaybackTrack.OnEndPlayback(false); + this._lastKnownPlaybackTrack = (PlaybackTrack)null; + } + if (flag || !this.ShowErrors) + return; + ErrorDialogInfo.Show(announcement.HResult, Shell.LoadString(StringId.IDS_PLAYBACK_ERROR)); + } + } + + private void DeferredPresentationInfoChangedHandler(object obj) + { + if (this.IsDisposed || this._videoStream == null) + return; + PresentationInfo presentationInfo = (PresentationInfo)obj; + this._videoStream.ContentWidth = presentationInfo.ContentWidth; + this._videoStream.ContentHeight = presentationInfo.ContentHeight; + this._videoStream.ContentAspectWidth = presentationInfo.ContentAspectWidth; + this._videoStream.ContentAspectHeight = presentationInfo.ContentAspectHeight; + this._videoStream.ContentOverscanPercent = presentationInfo.NeedOverscan ? 0.1f : 0.0f; + this.FirePropertyChanged("VideoStream"); + } + + private void DeferredVolumeInfoChangedHandler(object obj) + { + this._volume.Value = (float)this._playbackWrapper.Volume; + this.FirePropertyChanged("Volume"); + this._muted.Value = this._playbackWrapper.Mute; + this.FirePropertyChanged("Mute"); + } + + private void DeferredCanChangeVideoRateHandler(object obj) + { + if (this._currentTrack == null || !this._currentTrack.IsVideo) + return; + this._forward.Available = this._playbackWrapper.CanChangeVideoRate; + } + + private void SetUriOnPlayer() + { + PlaybackTrack track = (PlaybackTrack)null; + if (this._playlistCurrent != null) + track = this._playlistCurrent.CurrentTrack; + PlaybackTrack nextTrack = (PlaybackTrack)null; + if (this._playlistCurrent != null && this._playlistCurrent.Count > 1) + nextTrack = this._playlistCurrent.NextTrack; + if (track != null) + { + this.SetUrisOnPlayerAsync(track, nextTrack); + } + else + { + this.SetPlayerState(TransportControls.PlayerState.Stopped); + this._playbackWrapper.Close(); + this.UpdatePropertiesAndCommands(); + } + } + + private void SetNextUriOnPlayer() + { + PlaybackTrack nextTrack = (PlaybackTrack)null; + if (this._playlistCurrent != null) + nextTrack = this._playlistCurrent.NextTrack; + if (nextTrack != null && this._playlistCurrent.Count > 1) + this.SetUrisOnPlayerAsync((PlaybackTrack)null, nextTrack); + else + this._playbackWrapper.CancelNext(); + } + + private void SetUrisOnPlayerAsync(PlaybackTrack track, PlaybackTrack nextTrack) + { + int myID = ++this._lastKnownSetUriCallID; + ThreadPool.QueueUserWorkItem((WaitCallback)(args => + { + if (track != null) + { + string trackUri; + HRESULT uri = track.GetURI(out trackUri); + if (string.IsNullOrEmpty(trackUri)) + trackUri = ".:* INVALID URI *:."; + if (uri.IsSuccess) + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed || myID != this._lastKnownSetUriCallID) + return; + this._playbackWrapper.SetUri(trackUri, 0L, track.PlaybackID); + this.ReportStreamingAction(TransportControls.PlayerState.Stopped); + this._tracksSubmittedToPlayer.Remove(track); + this._tracksSubmittedToPlayer.Add(track); + if (nextTrack != null) + return; + this._playbackWrapper.CancelNext(); + this.UpdatePropertiesAndCommands(); + }, (object)null); + else + this.OnAlertSent(new Announcement() + { + HResult = uri.Int, + PlaybackID = track.PlaybackID + }); + } + if (nextTrack == null) + return; + string nextTrackUri; + HRESULT uri1 = nextTrack.GetURI(out nextTrackUri); + if (string.IsNullOrEmpty(nextTrackUri)) + nextTrackUri = ".:* INVALID URI *:."; + if (!uri1.IsSuccess) + return; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed || myID != this._lastKnownSetUriCallID) + return; + this._playbackWrapper.SetNextUri(nextTrackUri, 0L, nextTrack.PlaybackID); + this._tracksSubmittedToPlayer.Remove(nextTrack); + this._tracksSubmittedToPlayer.Add(nextTrack); + this.UpdatePropertiesAndCommands(); + }, (object)null); + }), (object)null); + } + + private void UpdateNextTrack() + { + this.SetNextUriOnPlayer(); + this.UpdatePropertiesAndCommands(); + } + + private bool AreContextsCompatible(PlaybackContext contextCurrent, PlaybackContext contextNext) => contextCurrent == PlaybackContext.None || contextNext == contextCurrent; + + public bool IsCurrentPlaylistContextCompatible(PlaybackContext context) + { + bool flag = true; + if (this._playlistCurrent != null) + flag = this.AreContextsCompatible(context, this._playlistCurrent.PlaybackContext); + return flag; + } + + private void UpdatePropertiesAndCommands() + { + bool flag1 = this._playerState == TransportControls.PlayerState.Playing; + ArrayListDataSet arrayListDataSet; + bool flag2; + bool flag3; + PlaybackTrack playbackTrack; + int num; + bool flag4; + if (this._playlistCurrent != null) + { + arrayListDataSet = this._playlistCurrent.TrackList; + flag2 = true; + flag3 = this.IsCurrentPlaylistContextCompatible(this._pagePlaybackContext); + playbackTrack = this._playlistCurrent.CurrentTrack; + num = this._playlistCurrent.ListIndexOfCurrentTrack; + flag4 = this._playlistCurrent.QuickMixSession == null; + } + else + { + flag2 = false; + arrayListDataSet = (ArrayListDataSet)null; + flag3 = true; + playbackTrack = (PlaybackTrack)null; + num = -1; + this.PlayingVideo = false; + flag4 = true; + } + if (arrayListDataSet != this._currentPlaylist) + { + this._currentPlaylist = arrayListDataSet; + this.FirePropertyChanged("CurrentPlaylist"); + } + if (flag2 != this._hasPlaylist) + { + this._hasPlaylist = flag2; + this.FirePropertyChanged("HasPlaylist"); + } + if (flag4 != this._playlistSupportsShuffle) + { + this._playlistSupportsShuffle = flag4; + this.FirePropertyChanged("PlaylistSupportsShuffle"); + } + if (flag1 != this._isPlaying) + { + this._isPlaying = flag1; + this.FirePropertyChanged("Playing"); + if (this._isPlaying) + { + this.HasPlayed = true; + this._currentPlayStartTime = DateTime.Now; + } + else if (this._currentPlayStartTime != DateTime.MinValue) + { + Telemetry.Instance.ReportPlaybackTime((int)DateTime.Now.Subtract(this._currentPlayStartTime).TotalSeconds); + this._currentPlayStartTime = DateTime.MinValue; + } + } + if (num != this._currentTrackIndex) + { + if (this._currentPlayStartTime != DateTime.MinValue) + { + Telemetry.Instance.ReportPlaybackTime((int)DateTime.Now.Subtract(this._currentPlayStartTime).TotalSeconds); + this._currentPlayStartTime = DateTime.Now; + } + this._currentTrackIndex = num; + this.FirePropertyChanged("CurrentTrackIndex"); + } + if (!object.ReferenceEquals((object)playbackTrack, (object)this._currentTrack)) + { + if (this._currentTrack != null) + this._currentTrack.RatingChanged.Invoked -= this._currentTrackRatingChangedEventHandler; + this._currentTrack = playbackTrack; + if (this._currentTrack != null) + this._currentTrack.RatingChanged.Invoked += this._currentTrackRatingChangedEventHandler; + this.FirePropertyChanged("CurrentTrack"); + this.OnCurrentTrackRatingChanged((object)this, (EventArgs)null); + this.CurrentTrackDownloadProgress = 0.0f; + if (this._currentTrack != null) + this.ShowNotification(); + else + this.HideNotification(); + this.ZoomScaleFactor = 0; + } + if (flag3 != this._isContextCompatible) + { + this._isContextCompatible = flag3; + this.FirePropertyChanged("IsPlaybackContextCompatible"); + } + this.UpdateAvailabilityOfCommands(); + if (this.Playing && this.CurrentTrack != null && (this.CurrentTrack.IsVideo && this.CurrentTrack.IsStreaming)) + { + this._isStreamingTimeoutTimer.Enabled = false; + this.IsStreamingVideo = true; + this.SupressDownloads = true; + } + else + { + if (this.SupressDownloads) + this._isStreamingTimeoutTimer.Enabled = true; + this.IsStreamingVideo = false; + } + } + + private void UpdateAvailabilityOfCommands() + { + bool playing = this.Playing; + bool flag = this._playlistCurrent != null; + this._play.Available = !playing && flag && !this.Buffering; + this._pause.Available = playing && !this.Buffering; + this._stop.Available = flag; + if (this._playerState == TransportControls.PlayerState.Stopped || this.Buffering) + { + this._forward.Available = false; + this._back.Available = false; + } + else if (this._playerState == TransportControls.PlayerState.Playing) + { + if (this._currentTrack == null) + { + this._forward.Available = false; + this._back.Available = false; + } + else + { + this._forward.Available = !this._currentTrack.IsVideo || this._playbackWrapper.CanChangeVideoRate; + this._back.Available = true; + } + } + else + { + this._forward.Available = this._currentTrack == null ? this._playlistCurrent != null : this._playlistCurrent != null && !this._currentTrack.IsVideo; + this._back.Available = this._playlistCurrent != null && this._playlistCurrent.CanRetreat; + } + this.UpdateTaskbarPlayer(); + } + + public static string FormatDuration(float seconds, bool prefixWithNegative) => Shell.TimeSpanToString(new TimeSpan(0, 0, (int)seconds), prefixWithNegative); + + public static string FormatDuration(float seconds) => TransportControls.FormatDuration(seconds, false); + + [Conditional("DEBUG_TRANSPORT")] + private static void _DEBUG_Trace(string message, params object[] args) + { + } + + [Conditional("DEBUG_TRANSPORT_PROPERTIES")] + private static void _DEBUG_TracePropChange(string name, object arg) + { + } + + private struct SpectrumOutputConfig + { + public uint SourceId; + public uint NumBands; + public bool Frequency; + public bool Waveform; + public bool Stereo; + public bool IsConnected; + } + + private enum PlayerState + { + Stopped, + Playing, + Paused, + } + } +} diff --git a/ZuneUI/TrimmedList.cs b/ZuneUI/TrimmedList.cs new file mode 100644 index 0000000..c5ea52d --- /dev/null +++ b/ZuneUI/TrimmedList.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TrimmedList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class TrimmedList : VirtualList + { + private IList _source; + private int _maxCount; + + public IList Source + { + get => this._source; + set + { + if (this._source == value) + return; + this._source = value; + this.FirePropertyChanged(nameof(Source)); + this.Reset(); + } + } + + public int MaxCount + { + get => this._maxCount; + set + { + if (this._maxCount == value) + return; + this._maxCount = value; + this.FirePropertyChanged(nameof(MaxCount)); + this.Reset(); + } + } + + protected void Reset() + { + this.Clear(); + this.Count = this._source != null ? Math.Min(this._source.Count, this._maxCount) : 0; + } + + protected override object OnRequestItem(int index) => this._source[index]; + } +} diff --git a/ZuneUI/TypePropertyDescriptor.cs b/ZuneUI/TypePropertyDescriptor.cs new file mode 100644 index 0000000..1668d10 --- /dev/null +++ b/ZuneUI/TypePropertyDescriptor.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.TypePropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class TypePropertyDescriptor : PropertyDescriptor + { + public TypePropertyDescriptor(string name, string multiValueString, string unknownString) + : base(name, multiValueString, unknownString) + { + } + + public override string ConvertToString(object value) => VideoDescriptions.GetDescription((int)value); + + public override object ConvertFromString(string value) => (object)(int)VideoDescriptions.GetCategory(value); + } +} diff --git a/ZuneUI/UIDevice.cs b/ZuneUI/UIDevice.cs new file mode 100644 index 0000000..d18031c --- /dev/null +++ b/ZuneUI/UIDevice.cs @@ -0,0 +1,2123 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.UIDevice +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Security; +using System.Threading; +using UIXControls; +using ZuneXml; + +namespace ZuneUI +{ + public class UIDevice : ModelItem + { + private IDeviceIconSet _iconSet; + private static readonly UIDevice.INewRuleMessageType[] _newRuleMessageLookupTable = new UIDevice.INewRuleMessageType[11] + { + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.Track, StringId.IDS_ADDED_1_TRACK, StringId.IDS_ADDED_N_TRACKS), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.Album, StringId.IDS_ADDED_1_ALBUM, StringId.IDS_ADDED_N_ALBUMS), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.Artist, StringId.IDS_ADDED_1_ARTIST, StringId.IDS_ADDED_N_ARTISTS), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.Genre, StringId.IDS_ADDED_1_GENRE, StringId.IDS_ADDED_N_GENRES), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.Playlist, StringId.IDS_ADDED_1_PLAYLIST, StringId.IDS_ADDED_N_PLAYLISTS), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.Video, StringId.IDS_ADDED_1_VIDEO, StringId.IDS_ADDED_N_VIDEOS), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.Photo, StringId.IDS_ADDED_1_PHOTO, StringId.IDS_ADDED_N_PHOTOS), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.MediaFolder, StringId.IDS_ADDED_1_FOLDER, StringId.IDS_ADDED_N_FOLDERS), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.PodcastEpisode, StringId.IDS_ADDED_1_PODCAST_EPISODE, StringId.IDS_ADDED_N_PODCAST_EPISODES), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.Podcast, StringId.IDS_ADDED_1_PODCAST, StringId.IDS_ADDED_N_PODCASTS), + (UIDevice.INewRuleMessageType) new UIDevice.NewRuleMessageType(MediaType.UserCard, StringId.IDS_ADDED_1_FRIEND, StringId.IDS_ADDED_N_FRIENDS) + }; + private static readonly UIDevice.INewRuleMessageType _channelNewRuleMessage = (UIDevice.INewRuleMessageType)new UIDevice.NewRuleMessageType(MediaType.Playlist, StringId.IDS_ADDED_1_CHANNEL, StringId.IDS_ADDED_N_CHANNELS); + private static readonly UIDevice.INewRuleMessageType _genericNewRuleMessage = (UIDevice.INewRuleMessageType)new UIDevice.NewRuleMessageType(MediaType.Undefined, StringId.IDS_ADDED_1_ITEM, StringId.IDS_ADDED_N_ITEMS); + private static bool _isOosDialogVisible; + private static string _syncStatusTitleDivider = ZuneUI.Shell.LoadString(StringId.IDS_SYNCITEM_TITLE_SEPARATOR); + private static string _syncStatusDatumDivider = ZuneUI.Shell.LoadString(StringId.IDS_SYNCITEM_METADATUM_SEPARATOR); + private UIFirmwareUpdater _firmwareUpdater; + private UIFirmwareRestorer _firmwareRestorer; + private Device _device; + private UIGasGauge _actualGasGauge; + private UIGasGauge _predictedGasGauge; + private SyncNotification _syncProgress; + private Command _syncBegun; + private Command _syncProgressed; + private Command _syncCompleted; + private bool _currentlySyncing; + private bool _currentlyFormatting; + private bool _isWirelessSyncEnabled; + private EEndpointStatus _lastDeviceState; + private bool _isReadyForSync; + private bool _isLocked; + private bool _userStoppedLastSync; + private Microsoft.Iris.Timer _formatSanityTimer; + private string _lastConnectTimestring; + private string _lastSyncStartTimestring; + private HRESULT _lastLoginFailure; + private HRESULT _lastSyncFailure; + private MessageBox _pinUnlockMessageBox; + + public IDeviceIconSet IconSet + { + get + { + if (this._iconSet == null) + this._iconSet = !this.IsValid || this._device.DeviceAssetSet == null ? DeviceIconSetFactory.DefaultIconSet : DeviceIconSetFactory.BuildDeviceIconSet(this._device.DeviceAssetSet, new DeviceIconSetFactory.DeviceIconSetConstructionCompletedCallback(this.SetDeviceIconSetCallback)); + return this._iconSet; + } + private set + { + if (this._iconSet == value) + return; + this._iconSet = value; + this.FirePropertyChanged(nameof(IconSet)); + } + } + + private void ReloadIconSet() => this.IconSet = (IDeviceIconSet)null; + + private void SetDeviceIconSetCallback(IDeviceIconSet iconSet) => this.IconSet = iconSet; + + public event FallibleEventHandler FormatCompletedEvent; + + public event FallibleEventHandler EnumeratedEvent; + + public event FallibleEventHandler WiFiRemovalCompletedEvent; + + public event FallibleEventHandler WiFiProfilesSentEvent; + + public event FallibleEventHandler WiFiProfilesReceivedEvent; + + public event FallibleEventHandler WiFiTestCompletedEvent; + + public event FallibleEventHandler WiFiAssociationCompletedEvent; + + public event FallibleEventHandler ComputerWiFiProfilesLoadedEvent; + + public event FallibleEventHandler WiFiScanCompletedEvent; + + internal UIDevice(IModelItemOwner owner, Device device) + : base(owner) + { + this._device = device; + this._lastLoginFailure = HRESULT._S_OK; + this._lastSyncFailure = HRESULT._S_OK; + if (this._device != null) + { + this._device.FriendlyNameChangedEvent += new FriendlyNameChangedHandler(this.OnNameChange); + this._device.DeviceStatusChangedEvent += new DeviceStatusChangedHandler(this.OnDeviceStatusChanged); + this._device.FormatCompleteEvent += new FormatCompleteHandler(this.OnFormatPhase1Completed); + this._device.SyncBegan += new SyncBeganHandler(this.OnSyncBegun); + this._device.SyncProgressed += new SyncProgressedHandler(this.OnSyncProgressed); + this._device.SyncCompleted += new SyncCompletedHandler(this.OnSyncCompleted); + this._device.UnassociateWlanDeviceCompleteEvent += new UnassociateWlanDeviceCompleteHandler(this.OnUnassociateWlanCompleted); + this._device.SetDeviceWlanProfilesCompleteEvent += new SetDeviceWlanProfilesCompleteHandler(this.OnSetDeviceWlanProfilesCompleted); + this._device.GetDeviceWlanProfilesCompleteEvent += new GetDeviceWlanProfilesCompleteHandler(this.OnGetDeviceWlanProfilesCompleted); + this._device.TestDeviceWlanCompleteEvent += new TestDeviceWlanCompleteHandler(this.OnTestWlanCompleted); + this._device.AssociateWlanDeviceCompleteEvent += new AssociateWlanDeviceCompleteHandler(this.OnAssociateWlanCompleted); + this._device.GetWlanProfilesCompleteEvent += new GetWlanProfilesCompleteHandler(this.OnGetWlanProfilesCompleted); + this._device.GetDeviceWlanNetworksCompleteEvent += new GetDeviceWlanNetworksCompleteHandler(this.OnGetDeviceWlanVisibleNetworksCompleted); + this._actualGasGauge = new UIGasGauge((IModelItemOwner)this, this._device.ActualGasGauge); + this._predictedGasGauge = new UIGasGauge((IModelItemOwner)this, this._device.PredictedGasGauge); + if (this._device.PredictedGasGauge != null) + this._device.PredictedGasGauge.DeviceOverflowEvent += new DeviceOverflowHandler(this.OnDeviceOverfill); + EEndpointStatus currentStatus = this._device.DeviceStatus; + if (currentStatus != EEndpointStatus.eEndpointStatusUndefined) + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.HandleDeviceState(currentStatus, HRESULT._S_OK); + }, (object)null); + } + else + { + this._actualGasGauge = new UIGasGauge((IModelItemOwner)this, (GasGauge)null); + this._predictedGasGauge = new UIGasGauge((IModelItemOwner)this, (GasGauge)null); + } + this._syncBegun = new Command((IModelItemOwner)this); + this._syncProgressed = new Command((IModelItemOwner)this); + this._syncCompleted = new Command((IModelItemOwner)this); + } + + protected override void OnDispose(bool disposing) + { + if (this._device != null) + { + this._device.FriendlyNameChangedEvent -= new FriendlyNameChangedHandler(this.OnNameChange); + this._device.DeviceStatusChangedEvent -= new DeviceStatusChangedHandler(this.OnDeviceStatusChanged); + this._device.FormatCompleteEvent -= new FormatCompleteHandler(this.OnFormatPhase1Completed); + if (this._device.PredictedGasGauge != null) + this._device.PredictedGasGauge.DeviceOverflowEvent -= new DeviceOverflowHandler(this.OnDeviceOverfill); + this._device.SyncBegan -= new SyncBeganHandler(this.OnSyncBegun); + this._device.SyncProgressed -= new SyncProgressedHandler(this.OnSyncProgressed); + this._device.SyncCompleted -= new SyncCompletedHandler(this.OnSyncCompleted); + this._device.UnassociateWlanDeviceCompleteEvent -= new UnassociateWlanDeviceCompleteHandler(this.OnUnassociateWlanCompleted); + this._device.SetDeviceWlanProfilesCompleteEvent -= new SetDeviceWlanProfilesCompleteHandler(this.OnSetDeviceWlanProfilesCompleted); + this._device.GetDeviceWlanProfilesCompleteEvent -= new GetDeviceWlanProfilesCompleteHandler(this.OnGetDeviceWlanProfilesCompleted); + this._device.TestDeviceWlanCompleteEvent -= new TestDeviceWlanCompleteHandler(this.OnTestWlanCompleted); + this._device.AssociateWlanDeviceCompleteEvent -= new AssociateWlanDeviceCompleteHandler(this.OnAssociateWlanCompleted); + this._device.GetWlanProfilesCompleteEvent -= new GetWlanProfilesCompleteHandler(this.OnGetWlanProfilesCompleted); + this._device.GetDeviceWlanNetworksCompleteEvent -= new GetDeviceWlanNetworksCompleteHandler(this.OnGetDeviceWlanVisibleNetworksCompleted); + } + base.OnDispose(disposing); + } + + public bool IsValid => this._device != null && !this.IsDisposed && this._lastDeviceState > EEndpointStatus.eEndpointStatusUndefined; + + public int ID => !this.IsValid ? 0 : this._device.DeviceID; + + public string MyPhoneDeviceID + { + get + { + string str = string.Empty; + if (this.IsValid && this.SupportsMyPhoneLinks && this._device.MyPhoneDeviceID != null) + str = this._device.MyPhoneDeviceID; + return str; + } + } + + public string EndpointId => !this.IsValid ? string.Empty : this._device.EndpointId; + + public string CanonicalName => !this.IsConnectedToClient ? string.Empty : this._device.CanonicalName; + + public DeviceClass Class => !this.IsValid ? DeviceClass.Invalid : (DeviceClass)this._device.ClassID; + + public int AdvertisedCapacity => !this.IsValid ? 0 : (int)this._device.StatedCapacity; + + public bool AllowChainedUpdates { get; set; } + + public bool NavigateToDeviceSummaryAfterUpdate { get; set; } + + public int SequentialUpdatesInstalled { get; set; } + + public bool SkipFutureBackupRequests { get; set; } + + public bool SupportsTVOutput + { + get + { + bool fIsTvOutSupported = false; + if (this.IsValid) + this._device.GetIsTvOutSupported(ref fIsTvOutSupported); + return fIsTvOutSupported; + } + } + + public bool SupportsClassicGames + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityInstallFirmwareGames, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsLiveId + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityLiveId, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsOOBECompleted + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityOOBECompleted, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsRestorePoint + { + get + { + bool fHasCapability = false; + return (!this.IsValid || ((HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityRestorePoint, ref fHasCapability)).IsSuccess) && fHasCapability; + } + } + + public bool RequiresAutoRestore => this.SupportsRestorePoint && !this._device.InStandardMode; + + public bool InStandardMode => this.IsValid && this._device.InStandardMode; + + public bool SupportsSyncApplications + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilitySyncApps, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsPaidApplications + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityPaidApps, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsStoreApplications => this.SupportsSyncApplications || this.SupportsPaidApplications; + + public bool SupportsHD + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityHdVideo, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsWiFi + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityWireless, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsWirelessSetupMethod1 + { + get + { + bool fHasCapability = true; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityWirelessSetupMethod1, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsWirelessSetupMethod2 + { + get + { + bool fHasCapability = true; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityWirelessSetupMethod2, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsFirmwareUpdate + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityFirmwareUpdate, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsMyPhoneLinks + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityMyPhoneLinks, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsRental + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityRental, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsUserCards + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityCloudSync, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsChannels + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityCloudSync, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsFormat + { + get + { + bool fHasCapability = true; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityFormat, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsZuneTagLinking + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityZuneTagLinking, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool SupportsUsageData + { + get + { + bool fHasCapability = false; + HRESULT hresult = HRESULT._S_OK; + if (this.IsValid) + hresult = (HRESULT)this._device.GetCapability(EEndpointCapability.eEndpointCapabilityUsageData, ref fHasCapability); + return hresult.IsSuccess && fHasCapability; + } + } + + public bool HasOffloadedContent => this.IsValid && !string.IsNullOrEmpty(this.OffloadedContentMessage) && !string.IsNullOrEmpty(this.OffloadedContentUrl); + + public string OffloadedContentMessage + { + get + { + string str = (string)null; + if (this.IsValid) + str = this._device.PicturesVideosViewText; + return str ?? string.Empty; + } + } + + public string OffloadedContentUrl + { + get + { + string str = (string)null; + if (this.IsValid) + str = this._device.PicturesVideosViewUrl; + return str ?? string.Empty; + } + } + + public bool HasRestorePoint => this.SupportsRestorePoint && this.UIFirmwareRestorer != null && this.UIFirmwareRestorer.RestorePoint != null; + + public string RestorePointDate => !this.HasRestorePoint ? string.Empty : StringFormatHelper.Format(this.UIFirmwareRestorer.RestorePoint.CreationDate.ToLocalTime(), StringFormatHelper.FriendlyMonthYearPattern); + + public string Manufacturer + { + get + { + string strManufacturer = (string)null; + if (this.IsValid) + this._device.GetManufacturer(ref strManufacturer); + return strManufacturer ?? string.Empty; + } + } + + public string ModelName + { + get + { + string strModelName = (string)null; + if (this.IsValid) + this._device.GetModelName(ref strModelName); + return strModelName ?? string.Empty; + } + } + + public bool IsConnectedToPC => this.IsValid && this._lastDeviceState >= EEndpointStatus.eEndpointStatusConnected; + + public bool IsConnectedToClient => this.IsValid && this._lastDeviceState >= EEndpointStatus.eEndpointStatusAvailable; + + public bool IsConnectedToClientWirelessly => this.IsValid && this.IsConnectedToClient && this._device.IsConnectedWirelessly; + + public bool IsConnectedToClientPhysically => this.IsConnectedToClient && !this.IsConnectedToClientWirelessly; + + public bool IsConnectedToSideloader => this.IsValid && this._lastDeviceState == EEndpointStatus.eEndpointStatusInUse; + + public string OwnerApplicationName => !this.IsConnectedToSideloader ? string.Empty : this._device.OwnerApplicationName; + + public bool IsReadyForSync + { + get => this.IsConnectedToClient && this._isReadyForSync; + private set + { + if (!this.IsValid || this._isReadyForSync == value) + return; + this._isReadyForSync = value; + this.FirePropertyChanged(nameof(IsReadyForSync)); + } + } + + public bool IsFormatting + { + get => this._currentlyFormatting; + private set + { + if (!this.IsValid || this._currentlyFormatting == value) + return; + this._currentlyFormatting = value; + this.FirePropertyChanged(nameof(IsFormatting)); + } + } + + public bool IsLockedAgainstSyncing + { + get => this._isLocked; + set + { + if (!this.IsValid || this._isLocked == value) + return; + this._isLocked = value; + if (!this._isLocked) + return; + this.EndSync(); + } + } + + public bool UserStoppedLastSync + { + get => this._userStoppedLastSync; + private set + { + if (this._userStoppedLastSync == value) + return; + this._userStoppedLastSync = value; + this.FirePropertyChanged(nameof(UserStoppedLastSync)); + } + } + + public HRESULT LastFailedLoginError + { + get => this._lastLoginFailure; + set + { + if (!(this._lastLoginFailure != value)) + return; + this._lastLoginFailure = value; + this.FirePropertyChanged(nameof(LastFailedLoginError)); + this.FirePropertyChanged("HasFailedLogin"); + } + } + + public bool HasFailedLogin => this.LastFailedLoginError.IsError; + + public HRESULT LastSyncError + { + get => this._lastSyncFailure; + private set + { + if (!(this._lastSyncFailure != value)) + return; + this._lastSyncFailure = value; + this.FirePropertyChanged(nameof(LastSyncError)); + this.FirePropertyChanged("HasFailedSync"); + } + } + + public bool HasFailedSync => this.LastSyncError.IsError; + + public string PivotDescription => ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_PIVOT); + + public bool IsWirelessSyncEnabled + { + get => this.IsValid && this._isWirelessSyncEnabled; + private set + { + if (this._isWirelessSyncEnabled == value) + return; + this._isWirelessSyncEnabled = value; + this.FirePropertyChanged(nameof(IsWirelessSyncEnabled)); + } + } + + public DeviceRelationship Relationship + { + get + { + DeviceRelationship deviceRelationship = DeviceRelationship.None; + if (this.IsValid) + { + ESyncRelationship relationship = ESyncRelationship.srNone; + if (((HRESULT)this._device.GetSyncRelationship(ref relationship)).IsSuccess) + deviceRelationship = (DeviceRelationship)relationship; + } + return deviceRelationship; + } + set + { + if (!this.IsValid || this.Relationship == value) + return; + this._device.SetSyncRelationship((ESyncRelationship)value); + if (value == DeviceRelationship.Permanent) + this.SetGeoId(); + this._device.SetTimeZoneBias(Convert.ToInt32(TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes)); + int num = this.HasFailedLogin ? 1 : 0; + this.FirePropertyChanged(nameof(Relationship)); + } + } + + public bool IsGuest + { + get + { + if (!this.IsValid) + return false; + return this.Relationship == DeviceRelationship.Guest || this.Relationship == DeviceRelationship.None; + } + } + + public string GetLocalizedDevicePath(string devicePath) + { + if (!this.IsValid) + return devicePath; + string strPath = devicePath; + return !((HRESULT)this._device.GetLocalizedDevicePath(ref strPath)).IsSuccess ? devicePath : strPath; + } + + public string Name + { + get + { + if (!this.IsValid) + return ZuneUI.Shell.LoadString(StringId.IDS_NO_DEVICE); + string strName = (string)null; + return !((HRESULT)this._device.GetFriendlyName(ref strName)).IsSuccess ? ZuneUI.Shell.LoadString(StringId.IDS_SYNC_DEFAULT_DEVICE_WORD) : strName; + } + set + { + if (!this.IsConnectedToClient) + return; + this._device.SetFriendlyName(value); + } + } + + public string NameXMLEscaped => SecurityElement.Escape(this.Name); + + public bool IsPermanentGuest + { + get + { + bool bPromptGuest = true; + if (this.IsValid) + this._device.GetPromptGuest(ref bPromptGuest); + return !bPromptGuest; + } + set + { + if (!this.IsValid || this.IsPermanentGuest == value) + return; + this._device.SetPromptGuest(!value); + this.FirePropertyChanged(nameof(IsPermanentGuest)); + } + } + + public Guid UserGuid + { + get + { + Guid empty = Guid.Empty; + if (this.IsValid) + this._device.GetUserGuid(ref empty); + return empty; + } + } + + public int UserId + { + get + { + int userId = 0; + if (this.IsValid) + this._device.GetUserId(ref userId); + return userId; + } + } + + public string ZuneTag + { + get + { + string empty = string.Empty; + if (this.IsConnectedToClient) + this._device.GetZuneTag(ref empty); + return empty; + } + } + + public string LiveId + { + get + { + string empty = string.Empty; + if (this.SupportsLiveId) + this._device.GetLiveId(ref empty); + return empty; + } + } + + public bool OOBECompleted + { + get + { + bool oobeCompleted = false; + if (this.SupportsOOBECompleted && this.IsConnectedToClient) + { + if (!this._device.InStandardMode) + return true; + this._device.GetOOBECompleted(ref oobeCompleted); + } + return oobeCompleted; + } + } + + public bool ExcludeDislikedContent + { + get + { + bool fDontSyncHatedContent = false; + if (this.IsValid) + this._device.Rules.GetDontSyncHatedContent(ref fDontSyncHatedContent); + return fDontSyncHatedContent; + } + set + { + if (!this.IsValid || this.ExcludeDislikedContent == value) + return; + this._device.Rules.SetDontSyncHatedContent(value); + this.FirePropertyChanged(nameof(ExcludeDislikedContent)); + } + } + + private bool ReverseSyncPicsFromPhone + { + get + { + bool bReverseSync = false; + if (this.IsValid) + this._device.GetPhotoVideoReverseSync(ref bReverseSync); + return bReverseSync; + } + set + { + if (!this.IsValid || this.ReverseSyncPicsFromPhone == value) + return; + this._device.SetPhotoVideoReverseSync(value); + this.FirePropertyChanged(nameof(ReverseSyncPicsFromPhone)); + } + } + + public bool DeletePicsFromPhoneAfterReverseSync + { + get + { + bool bDeleteAfterSync = false; + if (this.IsValid) + this._device.GetDeletePhotoVideoAfterReverseSync(ref bDeleteAfterSync); + return bDeleteAfterSync; + } + set + { + if (!this.IsValid || this.DeletePicsFromPhoneAfterReverseSync == value) + return; + this._device.SetDeletePhotoVideoAfterReverseSync(value); + this.FirePropertyChanged(nameof(DeletePicsFromPhoneAfterReverseSync)); + } + } + + public ETranscodePhotoSetting ImageTranscodeQuality + { + get + { + ETranscodePhotoSetting ePhotoSetting = ETranscodePhotoSetting.tsPhotoSettingInvalid; + if (this.IsValid) + this._device.GetPhotoTranscodeSetting(ref ePhotoSetting); + return ePhotoSetting; + } + set + { + if (!this.IsValid || this.ImageTranscodeQuality == value) + return; + this._device.SetPhotoTranscodeSetting(value); + this.FirePropertyChanged(nameof(ImageTranscodeQuality)); + } + } + + public string CameraRollDestinationPath + { + get + { + string empty = string.Empty; + if (this.IsValid) + this._device.GetCameraRollDestinationFolder(ref empty); + return empty; + } + set + { + if (!this.IsValid) + return; + this._device.SetCameraRollDestinationFolder(value); + this.FirePropertyChanged(nameof(CameraRollDestinationPath)); + } + } + + public string SavedFolderDestinationPath + { + get + { + string empty = string.Empty; + if (this.IsValid) + this._device.GetSavedDestinationFolder(ref empty); + return empty; + } + set + { + if (!this.IsValid) + return; + this._device.SetSavedDestinationFolder(value); + this.FirePropertyChanged(nameof(SavedFolderDestinationPath)); + } + } + + public int AudioTranscodeLimit + { + get + { + int audioThresholdBitRate = 0; + int audioTargetBitRate = 0; + if (this.IsValid) + this._device.GetAudioTranscodeParams(ref audioThresholdBitRate, ref audioTargetBitRate); + return audioThresholdBitRate; + } + set + { + if (!this.IsValid) + return; + this._device.SetAudioTranscodeParams(value, this.AudioTranscodeTarget); + this.FirePropertyChanged(nameof(AudioTranscodeLimit)); + } + } + + public int AudioTranscodeTarget + { + get + { + int audioThresholdBitRate = 0; + int audioTargetBitRate = 0; + if (this.IsValid) + this._device.GetAudioTranscodeParams(ref audioThresholdBitRate, ref audioTargetBitRate); + return audioTargetBitRate; + } + set + { + if (!this.IsValid) + return; + this._device.SetAudioTranscodeParams(this.AudioTranscodeLimit, value); + this.FirePropertyChanged(nameof(AudioTranscodeTarget)); + } + } + + public bool OptimizeVideoForTV + { + get + { + ETranscodeOptimization transcodeOptimization = ETranscodeOptimization.toOptimizeForSize; + if (this.IsValid) + this._device.GetVideoTranscodeOptimization(ref transcodeOptimization); + return transcodeOptimization == ETranscodeOptimization.toOptimizeForQuality; + } + set + { + if (!this.IsValid || this.OptimizeVideoForTV == value) + return; + if (value) + this._device.SetVideoTranscodeOptimization(ETranscodeOptimization.toOptimizeForQuality); + else + this._device.SetVideoTranscodeOptimization(ETranscodeOptimization.toOptimizeForSize); + this.FirePropertyChanged(nameof(OptimizeVideoForTV)); + } + } + + public bool PurchaseEnabled + { + get + { + bool purchaseEnabled = false; + if (this.IsConnectedToClient) + this._device.GetPurchaseEnabled(ref purchaseEnabled); + return purchaseEnabled; + } + set + { + if (!this.IsConnectedToClient || this.PurchaseEnabled == value) + return; + this._device.SetPurchaseEnabled(value); + this.FirePropertyChanged(nameof(PurchaseEnabled)); + } + } + + public int PercentReserved + { + get + { + uint ulPercentage = 0; + if (this.IsValid) + this._device.GetPercentSpaceReserved(ref ulPercentage); + return (int)ulPercentage; + } + set + { + if (!this.IsValid) + return; + this._device.SetPercentSpaceReserved((uint)value); + this.FirePropertyChanged(nameof(PercentReserved)); + } + } + + public bool PromptForAccountLinkage + { + get + { + bool bPromptLink = false; + if (this.IsValid) + this._device.GetPromptLink(ref bPromptLink); + return bPromptLink; + } + set + { + if (!this.IsValid) + return; + this._device.SetPromptLink(value); + this.FirePropertyChanged(nameof(PromptForAccountLinkage)); + } + } + + public bool RequiresClientUpdate => this.IsConnectedToClient && this._device.ClientUpdateRequired; + + public bool RequiresFirmwareUpdate => this.IsConnectedToClient && this._device.FirmwareUpdateRequired; + + public UIFirmwareUpdater UIFirmwareUpdater + { + get + { + if (this._firmwareUpdater == null && this.IsValid && (this._device.FirmwareUpdater != null && this.IsConnectedToClientPhysically)) + this.UIFirmwareUpdater = new UIFirmwareUpdater(this, this._device.FirmwareUpdater); + return this._firmwareUpdater; + } + private set + { + if (this._firmwareUpdater == value) + return; + this._firmwareUpdater = value; + this.FirePropertyChanged(nameof(UIFirmwareUpdater)); + } + } + + public UIFirmwareRestorer UIFirmwareRestorer + { + get + { + if (this._firmwareRestorer == null && this.IsValid && (this._device.FirmwareUpdater != null && this.IsConnectedToClientPhysically)) + this.UIFirmwareRestorer = new UIFirmwareRestorer(this._device.FirmwareUpdater.Restorer, this.RequiresAutoRestore); + return this._firmwareRestorer; + } + private set + { + this._firmwareRestorer = value; + this.FirePropertyChanged(nameof(UIFirmwareRestorer)); + } + } + + public string FirmwareVersion + { + get + { + string empty = string.Empty; + if (this.IsConnectedToClient) + this._device.GetFirmwareVersion(ref empty); + return empty; + } + } + + public bool IsSyncing + { + get => this._currentlySyncing; + private set + { + if (!this.IsValid || this._currentlySyncing == value) + return; + this._currentlySyncing = value; + this.FirePropertyChanged(nameof(IsSyncing)); + } + } + + public SyncNotification SyncProgress + { + get => this._syncProgress; + private set + { + if (!this.IsValid || this._syncProgress == value) + return; + this._syncProgress = value; + this.FirePropertyChanged(nameof(SyncProgress)); + } + } + + public Command SyncBegun => this._syncBegun; + + public Command SyncProgressed => this._syncProgressed; + + public Command SyncCompleted => this._syncCompleted; + + private Microsoft.Iris.Timer FormatSanityTimer + { + get + { + if (this._formatSanityTimer == null) + { + this._formatSanityTimer = new Microsoft.Iris.Timer((IModelItemOwner)this); + this._formatSanityTimer.Interval = 60000; + this._formatSanityTimer.AutoRepeat = false; + this._formatSanityTimer.Tick += new EventHandler(this.FormatSanityFailed); + } + return this._formatSanityTimer; + } + } + + public DateTime LastConnectTime + { + get + { + DateTime dateTime = DateTime.MinValue; + if (this.IsValid) + dateTime = this._device.LastConnectTime; + return dateTime; + } + } + + public string LastSyncTime + { + get + { + string str = string.Empty; + if (this.IsValid) + { + DateTime lastSyncTime = this._device.LastSyncTime; + if (lastSyncTime.Year >= 2006) + str = !(lastSyncTime.Date == DateTime.Now.Date) ? lastSyncTime.ToString("d") : lastSyncTime.ToString("t"); + } + return str; + } + } + + public string LastConnectTimestring + { + get => this._lastConnectTimestring ?? string.Empty; + private set + { + if (!(this._lastConnectTimestring != value)) + return; + this._lastConnectTimestring = value; + this.FirePropertyChanged(nameof(LastConnectTimestring)); + } + } + + public string LastSyncStartTimestring + { + get => this._lastSyncStartTimestring ?? this.LastConnectTimestring; + private set + { + if (!(this._lastSyncStartTimestring != value)) + return; + this._lastSyncStartTimestring = value; + this.FirePropertyChanged(nameof(LastSyncStartTimestring)); + } + } + + public UIGasGauge ActualGasGauge + { + get => this._actualGasGauge; + private set + { + if (this._actualGasGauge == value) + return; + this._actualGasGauge = value; + this.FirePropertyChanged(nameof(ActualGasGauge)); + } + } + + public UIGasGauge PredictedGasGauge + { + get => this._predictedGasGauge; + private set + { + if (this._predictedGasGauge == value) + return; + this._predictedGasGauge = value; + this.FirePropertyChanged(nameof(PredictedGasGauge)); + } + } + + public bool EnableWatson + { + get + { + uint dwWatsonSetting = 0; + if (this.IsConnectedToClient) + this._device.GetWatsonSetting(ref dwWatsonSetting); + return dwWatsonSetting > 0U; + } + set + { + if (!this.IsConnectedToClient || this.EnableWatson == value) + return; + this._device.SetWatsonSetting(value ? 1U : 0U); + this.FirePropertyChanged(nameof(EnableWatson)); + } + } + + public SyncMode GetSyncMode(SyncCategory schema) => this.GetSyncMode(schema, false); + + internal SyncMode GetSyncMode(SyncCategory schema, bool fEstablishingPartnership) + { + ESyncMode mode = ESyncMode.eSyncModeInvalid; + if (this.IsValid && this.SupportsSyncCategory(schema)) + this._device.Rules.GetCategorySyncMode((ESyncCategory)schema, ref mode, fEstablishingPartnership); + return (SyncMode)mode; + } + + public void SetSyncMode(SyncCategory schema, SyncMode mode) + { + if (!this.IsValid) + return; + this._device.Rules.SetCategorySyncMode((ESyncCategory)schema, (ESyncMode)mode); + } + + public bool IsManualFor(MediaType type) => this.IsManualFor(UIDeviceList.MapMediaTypeToSyncCategory(type)); + + public bool IsManualFor(SyncCategory type) => this.IsManualFor(type, false); + + internal bool IsManualFor(SyncCategory type, bool fEstablishingPartnership) => this.GetSyncMode(type, fEstablishingPartnership) == SyncMode.Manual; + + public bool IsSyncAllFor(MediaType schema) => this.IsSyncAllFor(UIDeviceList.MapMediaTypeToSyncCategory(schema)); + + public bool IsSyncAllFor(SyncCategory schema) => this.IsSyncAllFor(schema, false); + + internal bool IsSyncAllFor(SyncCategory schema, bool fEstablishingPartnership) => this.GetSyncMode(schema, fEstablishingPartnership) == SyncMode.SyncAll; + + public void AddSyncRule(IList items) + { + throw new NotImplementedException(); + /*// ISSUE: object of a compiler-generated type is created + // ISSUE: variable of a compiler-generated type + UIDevice.c__DisplayClass6 cDisplayClass6_1 = new UIDevice.c__DisplayClass6(); + // ISSUE: reference to a compiler-generated field + cDisplayClass6_1.items = items; + // ISSUE: reference to a compiler-generated field + cDisplayClass6_1.<>4__this = this; + // ISSUE: reference to a compiler-generated field + // ISSUE: reference to a compiler-generated field + if (cDisplayClass6_1.items == null || cDisplayClass6_1.items.Count <= 0 || !this.IsValid) + return; + TypeDiscoveringSyncEventArgs args = new TypeDiscoveringSyncEventArgs(); + args.Device = this._device; + long startingSize = this.ActualGasGauge.UsedSpace; + // ISSUE: reference to a compiler-generated field + this.MaterializeMarketplaceMedia(cDisplayClass6_1.items); + // ISSUE: reference to a compiler-generated field + MediaIdAndType[] threadSafeItems = this.GenerateThreadSafeDatabaseItems(cDisplayClass6_1.items); + ThreadPool.QueueUserWorkItem((WaitCallback) delegate + { + // ISSUE: variable of a compiler-generated type + UIDevice.c__DisplayClass6 cDisplayClass6 = cDisplayClass6_1; + bool actionSucceeded = LibraryDataProvider.ActOnItems((IList) threadSafeItems, BulkItemAction.AddSyncRules, (EventArgs) args); + Application.DeferredInvoke((DeferredInvokeHandler) delegate + { + if (actionSucceeded) + { + string message = (string) null; + MediaType mediaType = args.ContainedTypes == null || args.ContainedTypes.Count != 1 ? MediaType.Undefined : (MediaType) args.ContainedTypes[0]; + // ISSUE: reference to a compiler-generated field + if (mediaType == MediaType.Playlist && cDisplayClass6.items[0] is IDatabaseMedia databaseMedia) + { + int mediaId; + databaseMedia.GetMediaIdAndType(out mediaId, out EMediaTypes _); + if (PlaylistManager.IsChannel(mediaId)) + { + // ISSUE: reference to a compiler-generated field + message = UIDevice._channelNewRuleMessage.GetMessageForCount(cDisplayClass6.items.Count); + } + } + if (message == null) + { + foreach (UIDevice.INewRuleMessageType newRuleMessageType in UIDevice._newRuleMessageLookupTable) + { + if (newRuleMessageType.Type == mediaType) + { + // ISSUE: reference to a compiler-generated field + message = newRuleMessageType.GetMessageForCount(cDisplayClass6.items.Count); + break; + } + } + } + if (message == null) + { + // ISSUE: reference to a compiler-generated field + message = UIDevice._genericNewRuleMessage.GetMessageForCount(cDisplayClass6.items.Count); + } + // ISSUE: reference to a compiler-generated field + NotificationArea.Instance.Override((Notification) new SyncNewRuleAddedNotification(message, startingSize, cDisplayClass6.<>4__this.PredictedGasGauge)); + } + // ISSUE: reference to a compiler-generated field + cDisplayClass6.<>4__this.BeginSync(true, false); + }, (object) null); + }, (object) null);*/ + } + + public void AddPlaylistSyncRule(int dbPlaylistId) => this.AddSyncRule((IList)new MediaIdAndType[1] + { + new MediaIdAndType(dbPlaylistId, MediaType.Playlist) + }); + + public void RemoveSyncRule(IList items) + { + if (items == null || items.Count <= 0 || !this.IsValid) + return; + SyncEventArgs args = new SyncEventArgs(); + args.Device = this._device; + MediaIdAndType[] threadSafeItems = this.GenerateThreadSafeDatabaseItems(items); + ThreadPool.QueueUserWorkItem((WaitCallback)delegate + { + LibraryDataProvider.ActOnItems((IList)threadSafeItems, BulkItemAction.RemoveSyncRules, (EventArgs)args); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.BeginSync(true, false); + }, (object)null); + }, (object)null); + } + + public void Exclude(IList items) + { + if (items == null || items.Count <= 0 || !this.IsValid) + return; + SyncEventArgs args = new SyncEventArgs(); + args.Device = this._device; + MediaIdAndType[] threadSafeItems = this.GenerateThreadSafeDatabaseItems(items); + bool shouldBeginSyncAfter = false; + foreach (object obj in (IEnumerable)items) + { + if (obj is LibraryDataProviderItemBase providerItemBase) + { + object property = providerItemBase.GetProperty("SyncState"); + if (property != null) + { + switch ((ESyncState)property) + { + case ESyncState.eSyncStateCurrentlySyncing: + case ESyncState.eSyncStateOnDevice: + break; + default: + continue; + } + } + } + shouldBeginSyncAfter = true; + break; + } + ThreadPool.QueueUserWorkItem((WaitCallback)delegate + { + LibraryDataProvider.ActOnItems((IList)threadSafeItems, BulkItemAction.ExcludeFromSync, (EventArgs)args); + if (!shouldBeginSyncAfter) + return; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.BeginSync(true, false); + }, (object)null); + }, (object)null); + } + + public void Unexclude(IList items) + { + if (items == null || items.Count <= 0 || !this.IsValid) + return; + SyncEventArgs args = new SyncEventArgs(); + args.Device = this._device; + MediaIdAndType[] threadSafeItems = this.GenerateThreadSafeDatabaseItems(items); + ThreadPool.QueueUserWorkItem((WaitCallback)delegate + { + LibraryDataProvider.ActOnItems((IList)threadSafeItems, BulkItemAction.UnexcludeFromSync, (EventArgs)args); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.BeginSync(true, false); + }, (object)null); + }, (object)null); + } + + public void DeleteAndExclude(IList items) + { + if (items == null || items.Count <= 0 || !this.IsReadyForSync) + return; + DeferrableSyncEventArgs args = new DeferrableSyncEventArgs(); + args.Device = this._device; + MediaIdAndType[] threadSafeItems = this.GenerateThreadSafeDatabaseItems(items); + ThreadPool.QueueUserWorkItem((WaitCallback)delegate + { + LibraryDataProvider.ActOnItems((IList)threadSafeItems, BulkItemAction.DeleteFromDevice, (EventArgs)args); + }, (object)null); + } + + public SyncGroupList GenerateSyncGroupList( + IModelItemOwner owner, + bool expandSyncAllEntries) + { + SyncRulesView syncRulesView = (SyncRulesView)null; + if (this.IsValid) + { + HRESULT snapshot = (HRESULT)this._device.Rules.GenerateSnapshot(expandSyncAllEntries, ref syncRulesView); + } + return new SyncGroupList(owner, this, syncRulesView, expandSyncAllEntries); + } + + public PodcastSyncLimit GetPodcastSyncLimit(int podcastID) + { + EDeviceSyncRuleType ruleType = EDeviceSyncRuleType.eDeviceSyncRuleTypeInvalid; + if (this.IsValid) + this._device.Rules.GetSyncRuleForMedia(EMediaTypes.eMediaTypePodcastSeries, podcastID, ref ruleType); + return (PodcastSyncLimit)ruleType; + } + + public void SetPodcastSyncLimit(int podcastID, PodcastSyncLimit limit) + { + if (!this.IsValid) + return; + this._device.Rules.Add(new int[1] { podcastID }, EMediaTypes.eMediaTypePodcastSeries, (EDeviceSyncRuleType)limit); + } + + public int GetPodcastSyncLimitWithValue(int podcastID) + { + int iValue = -1; + if (this.IsValid && this._device != null && this._device.Rules != null) + this._device.Rules.GetSyncRuleValueForMedia(podcastID, ref iValue); + return iValue; + } + + public void SetPodcastSyncLimitWithValue(int podcastID, int value) + { + if (!this.IsValid) + return; + int[] rgIds = new int[1] { podcastID }; + if (this._device == null || this._device.Rules == null) + return; + this._device.Rules.AddDeviceSyncRuleWithValue(rgIds, value); + } + + public void BeginSync() => this.BeginSync(false, false); + + public void BeginSync(bool userInitiated, bool syncOnNextNotify) + { + if (!this.IsReadyForSync || this.IsLockedAgainstSyncing || !userInitiated && this.UserStoppedLastSync) + return; + if (syncOnNextNotify) + this._device.StartSyncNextNotify(); + else + this._device.StartSync(); + } + + public void EndSync() => this.EndSync(false); + + public void EndSync(bool userInitiated) + { + if (this.SyncProgress != null) + this.SyncProgress.SyncCanceled = true; + if (this.IsConnectedToClient) + this._device.StopSync(); + if (!userInitiated) + return; + if (this.IsGuest) + this._device.ClearRules(); + else + this._device.ClearManualModeRules(); + this.UserStoppedLastSync = true; + } + + public bool ReverseSync(IList items) + { + if (items != null && items.Count > 0 && (this.IsConnectedToClient && this.IsReadyForSync)) + { + DeferrableSyncEventArgs deferrableSyncEventArgs = new DeferrableSyncEventArgs(); + deferrableSyncEventArgs.Device = this._device; + LibraryDataProvider.ActOnItems(items, BulkItemAction.ReverseSync, (EventArgs)deferrableSyncEventArgs); + if (deferrableSyncEventArgs.Status == ESyncOperationStatus.osDeferred) + return false; + } + return true; + } + + public HRESULT Enumerate() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.StartEnumeration(); + + public HRESULT Format() + { + if (!this.IsConnectedToClient) + return HRESULT._E_UNEXPECTED; + this.IsFormatting = true; + return (HRESULT)this._device.Format(); + } + + public HRESULT DeleteAllGuestContent() + { + if (!this.IsConnectedToClient) + return HRESULT._E_UNEXPECTED; + ESyncOperationStatus operationStatus = ESyncOperationStatus.osInvalid; + return (HRESULT)this._device.DeleteAllGuestContent(ref operationStatus); + } + + public HRESULT ForceAppUpdate() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.ForceAppUpdate(); + + public HRESULT ClearAccountAssociation() + { + HRESULT hresult = HRESULT._E_UNEXPECTED; + if (this.IsConnectedToClient) + { + hresult = (HRESULT)this._device.ClearUserGuidandZuneTag(); + int num = this.HasFailedLogin ? 1 : 0; + this.FirePropertyChanged("UserId"); + this.FirePropertyChanged("ZuneTag"); + this.PurchaseEnabled = false; + } + return hresult; + } + + public HRESULT AssociateWithAccount(Guid guid, string tag) + { + HRESULT hresult = HRESULT._E_UNEXPECTED; + if (this.IsConnectedToClient) + { + hresult = (HRESULT)this._device.SetUserGuidandZuneTag(guid, tag); + if (hresult.IsSuccess) + hresult = this.SetGeoId(); + int num = this.HasFailedLogin ? 1 : 0; + this.FirePropertyChanged("UserId"); + this.FirePropertyChanged("ZuneTag"); + } + return hresult; + } + + public void SendMarketplaceCredentials(string username, string password) + { + if (!this.IsConnectedToClient) + return; + SecureString secureUsername = ZuneUI.Shell.MakeSecureString(username, true); + SecureString securePassword = ZuneUI.Shell.MakeSecureString(password, true); + ThreadPool.QueueUserWorkItem((WaitCallback)delegate + { + this._device.SetMarketplaceCredentials(secureUsername, securePassword); + }); + } + + public HRESULT SetGeoId() + { + HRESULT hresult = HRESULT._E_UNEXPECTED; + if (this.IsValid) + { + uint num = CultureHelper.GeoId(); + if (!CultureHelper.IsValidGeoId(num)) + num = 0U; + hresult = (HRESULT)this._device.SetGeoId(num); + } + return hresult; + } + + public HRESULT RemoveWiFiAssociation() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.UnassociateWlanDevice(); + + public HRESULT SetWiFiProfileList(WlanProfileList list) => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.SetWlanProfileList(list); + + public HRESULT GetWiFiProfileList(ref WlanProfileList list) => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.GetWlanProfileList(ref list); + + public HRESULT SendWiFiProfiles() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.SetDeviceWlanProfiles(); + + public HRESULT ReceiveWiFiProfiles() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.GetDeviceWlanProfiles(); + + public HRESULT TestWiFi() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.TestDeviceWlan(); + + public HRESULT CancelWiFiTest() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.CancelTestDeviceWlan(); + + public HRESULT AssociateWiFi() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.AssociateWlanDevice(); + + public HRESULT LoadComputerWiFiProfiles() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.GetWlanProfiles(); + + public HRESULT ScanForWiFiNetworks() => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.GetDeviceWlanNetworks(); + + public HRESULT GetDisconnectedWiFiUUID(ref string uuid) => !this.IsValid ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.GetDisconnectedWlanDeviceUuid(ref uuid); + + public HRESULT UnassociateWiFiUUID(string uuid) => !this.IsValid ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.UnassociateWlanDeviceUuid(uuid); + + public bool WirelessEnableRequiresElevation() + { + bool bEnabled = true; + if (this.IsValid) + this._device.IsWlanFirewallEnabled(ref bEnabled); + return Environment.OSVersion.Version.Major >= 6 && !bEnabled; + } + + public HRESULT GetWiFiAuthorizationCipherList(ref WlanAuthCipherPairList list) => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.GetWlanDeviceAuthCipherPairList(ref list); + + public HRESULT GetWifiConnectedSSID(ref string connectedSSID) => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.GetDeviceWlanConnectedSSID(ref connectedSSID); + + public HRESULT IsWlanDeviceDisabled(ref bool disabled) => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.IsWlanDeviceDisabled(ref disabled); + + public HRESULT GetWifiMediaSyncSSID(ref string mediaSyncSSID) => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.GetDeviceWlanMediaSyncSSID(ref mediaSyncSSID); + + public HRESULT SetWifiMediaSyncSSID(string mediaSyncSSID) => !this.IsConnectedToClient ? HRESULT._E_UNEXPECTED : (HRESULT)this._device.SetDeviceWlanMediaSyncSSID(mediaSyncSSID); + + public override bool Equals(object obj) => obj is UIDevice uiDevice ? this._device == uiDevice._device : base.Equals(obj); + + public override int GetHashCode() => this._device == null ? 0 : this._device.GetHashCode(); + + public bool SupportsRentalOfVideo(bool isHD) + { + if (!this.SupportsRental) + return false; + return !isHD || this.SupportsHD; + } + + public bool SupportsBrandingType(DeviceBranding brand) + { + bool flag = false; + switch (this.Class) + { + case DeviceClass.Invalid: + case DeviceClass.Reserved: + return flag; + case DeviceClass.WindowsPhone: + flag = brand == DeviceBranding.WindowsPhone; + goto case DeviceClass.Invalid; + case DeviceClass.Kin: + flag = brand == DeviceBranding.Kin; + goto case DeviceClass.Invalid; + default: + flag = brand == DeviceBranding.Zune; + goto case DeviceClass.Invalid; + } + } + + private void OnNameChange(Device device, string newName) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this.FirePropertyChanged("Name"); + this.FirePropertyChanged("NameXMLEscaped"); + }, (object)null); + + private void OnDeviceOverfill(GasGauge gasGauge) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this.EndSync(); + if (this.IsGuest) + this._device.ClearRules(); + ZuneShell shell = ZuneShell.DefaultInstance; + if (shell.CurrentPage is PlaybackPage) + shell.NavigateBack(); + if (shell.CurrentPage is DialogPage || UIDevice._isOosDialogVisible) + return; + UIDevice._isOosDialogVisible = true; + if (this.IsGuest) + { + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_OUT_OF_SPACE_TITLE), string.Format(ZuneUI.Shell.LoadString(StringId.IDS_GUEST_OUT_OF_SPACE_MESSAGE), (object)this.Name), (EventHandler)null, (EventHandler)null, (EventHandler)null, (EventHandler)delegate + { + UIDevice._isOosDialogVisible = false; + }); + } + else + { + Command okCommand = new Command((IModelItemOwner)this, ZuneUI.Shell.LoadString(StringId.IDS_HANDLE_DEVICE_OUT_OF_SPACE_BUTTON), (EventHandler)delegate + { + shell.NavigateToPage((ZunePage)new DeviceOverfillLand(this)); + UIDevice._isOosDialogVisible = false; + }); + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_OUT_OF_SPACE_TITLE), string.Format(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_OUT_OF_SPACE_MESSAGE), (object)this.Name), okCommand, (string)null, (EventHandler)delegate + { + UIDevice._isOosDialogVisible = false; + }, false); + } + }, (object)null); + + private void OnDeviceStatusChanged(Device device, int rawHR, EEndpointStatus endpointStatus) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this.HandleDeviceState(endpointStatus, (HRESULT)rawHR); + }, (object)null); + + private void OnFormatPhase1Completed(Device device, int rawHR) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + HRESULT hr = (HRESULT)rawHR; + if (hr.IsError) + this.OnFormatCompleted(hr); + else + this.FormatSanityTimer.Start(); + }, (object)null); + + private void OnSyncBegun(Device device) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this.SyncProgress = new SyncNotification(this); + this.IsSyncing = true; + this.SyncBegun.Invoke(); + this.SyncProgressed.Invoke(); + if (this.IsLockedAgainstSyncing) + this.EndSync(); + else + this.UserStoppedLastSync = false; + this.LastSyncStartTimestring = this.GenerateSyncTimestring(); + this.FirePropertyChanged("LastSyncTime"); + }, (object)null); + + private void OnSyncProgressed( + Device device, + uint percent, + uint percentItem, + uint percentTitle, + string group, + string title, + ESyncEngineState engineState) + { + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + if (this.SyncProgress != null) + this.SyncProgress.UpdateProgress((int)percent, (int)percentItem, (int)percentTitle, group, title, engineState); + this.SyncProgressed.Invoke(); + }, (object)null); + } + + private void OnSyncCompleted(Device device, ESyncEventReason reason) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + if (this.SyncProgress != null) + { + this.SyncProgress.Complete(reason); + this.SyncProgress = (SyncNotification)null; + this.LastSyncError = reason != ESyncEventReason.eSyncEventSucceeded ? HRESULT._E_FAIL : HRESULT._S_OK; + } + this.IsSyncing = false; + this.SyncProgressed.Invoke(); + this.SyncCompleted.Invoke(); + this.FirePropertyChanged("LastSyncTime"); + }, (object)null); + + private void FormatSanityFailed(object sender, EventArgs e) + { + if (!this.IsFormatting) + return; + this.OnFormatCompleted(HRESULT._E_FAIL); + SingletonModelItem.Instance.HideDevice(this); + } + + private void OnUnassociateWlanCompleted(Device device, int hr) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this.UpdateWirelessSyncEnabled(); + if (this.WiFiRemovalCompletedEvent == null) + return; + this.WiFiRemovalCompletedEvent((object)this, new FallibleEventArgs((HRESULT)hr)); + }, (object)null); + + private void OnSetDeviceWlanProfilesCompleted(Device device, int hr) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this.UpdateWirelessSyncEnabled(); + if (this.WiFiProfilesSentEvent == null) + return; + this.WiFiProfilesSentEvent((object)this, new FallibleEventArgs((HRESULT)hr)); + }, (object)null); + + private void OnGetDeviceWlanProfilesCompleted(Device device, int hr) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed || this.WiFiProfilesReceivedEvent == null) + return; + this.WiFiProfilesReceivedEvent((object)this, new FallibleEventArgs((HRESULT)hr)); + }, (object)null); + + private void OnTestWlanCompleted(Device device, WlanTestResultCode result, int hr) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.UpdateWirelessSyncEnabled(); + if (this.IsDisposed || this.WiFiTestCompletedEvent == null) + return; + this.WiFiTestCompletedEvent((object)this, new FallibleEventArgs((HRESULT)hr)); + }, (object)null); + + private void OnAssociateWlanCompleted(Device device, int hr) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.UpdateWirelessSyncEnabled(); + if (this.IsDisposed || this.WiFiAssociationCompletedEvent == null) + return; + this.WiFiAssociationCompletedEvent((object)this, new FallibleEventArgs((HRESULT)hr)); + }, (object)null); + + private void OnGetWlanProfilesCompleted(Device device, int hr) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed || this.ComputerWiFiProfilesLoadedEvent == null) + return; + this.ComputerWiFiProfilesLoadedEvent((object)this, new FallibleEventArgs((HRESULT)hr)); + }, (object)null); + + private void OnGetDeviceWlanVisibleNetworksCompleted(Device device, int hr) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed || this.WiFiScanCompletedEvent == null) + return; + this.WiFiScanCompletedEvent((object)this, new FallibleEventArgs((HRESULT)hr)); + }, (object)null); + + private void ReleaseFirmwareObjects() + { + this.UIFirmwareUpdater = (UIFirmwareUpdater)null; + this.UIFirmwareRestorer = (UIFirmwareRestorer)null; + } + + private void MaterializeMarketplaceMedia(IList items) + { + List intList = new List(items.Count); + for (int index = 0; index < items.Count; ++index) + { + if (items[index] is DataProviderObject dataProviderObject) + { + switch (dataProviderObject) + { + case Track _: + Track track = (Track)dataProviderObject; + int dbMediaId1 = -1; + if (!ZuneApplication.Service.InCompleteCollection(track.Id, Microsoft.Zune.Service.EContentType.MusicTrack, out dbMediaId1, out bool _) && (track.IsDownloading || track.CanDownload || track.CanPurchase)) + dbMediaId1 = ZuneApplication.ZuneLibrary.AddTrack(track.Id, track.AlbumId, track.TrackNumber, track.Title, track.Duration, track.AlbumTitle, track.Artist, track.PrimaryGenre.Title); + if (dbMediaId1 >= 0) + { + track.LibraryId = dbMediaId1; + continue; + } + continue; + case Album _: + Album album = (Album)dataProviderObject; + int num = ZuneApplication.ZuneLibrary.AddAlbum(album.Id, album.Title, album.Artist); + if (num >= 0) + { + album.LibraryId = num; + continue; + } + continue; + case PodcastSeries _: + PodcastSeries podcastSeries = (PodcastSeries)dataProviderObject; + string sourceUrl = podcastSeries.SourceUrl; + if (!string.IsNullOrEmpty(sourceUrl)) + { + SubscriptionState subscriptionState = ZuneShell.DefaultInstance.Management.GetSubscriptionState(sourceUrl, EMediaTypes.eMediaTypePodcastSeries); + if (subscriptionState != null && !subscriptionState.IsSubscribed) + { + ZuneShell.DefaultInstance.Management.SubscribeToPodcastFeed(sourceUrl, podcastSeries.Title, podcastSeries.Id, ESubscriptionSource.eSubscriptionSourceZMP); + continue; + } + continue; + } + continue; + case MusicVideo _: + MusicVideo musicVideo = (MusicVideo)dataProviderObject; + int dbMediaId2 = -1; + if (!ZuneApplication.Service.InCompleteCollection(musicVideo.Id, Microsoft.Zune.Service.EContentType.Video, out dbMediaId2, out bool _) && (musicVideo.IsDownloading || musicVideo.CanPurchase)) + dbMediaId2 = ZuneApplication.ZuneLibrary.AddVideo(musicVideo.Id, musicVideo.Title, musicVideo.Duration); + if (dbMediaId2 >= 0) + { + musicVideo.LibraryId = dbMediaId2; + continue; + } + continue; + default: + continue; + } + } + } + } + + private void HandleDeviceState(EEndpointStatus state, HRESULT hr) + { + bool isValid = this.IsValid; + bool isConnectedToPc = this.IsConnectedToPC; + bool connectedToClient = this.IsConnectedToClient; + bool connectedToSideloader = this.IsConnectedToSideloader; + bool isReadyForSync = this.IsReadyForSync; + this._lastDeviceState = state; + if (isValid != this.IsValid) + { + this.ReverseSyncPicsFromPhone = true; + this.FirePropertyChanged("IsValid"); + } + if (isConnectedToPc != this.IsConnectedToPC) + { + this.FirePropertyChanged("IsConnectedToPC"); + if (!FeatureEnablement.IsFeatureEnabled(Features.eDevice)) + { + ClientConfiguration.FeaturesOverride.Device = 1; + FeatureEnablement.ForceFeatureOn(Features.eDevice); + } + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + ZuneUI.Shell.MainFrame.Device.UpdateShowDevice(); + ZuneUI.Shell.SettingsFrame.Settings.ShowDevice(true); + }, (object)null); + } + if (connectedToClient != this.IsConnectedToClient) + { + if (this.IsConnectedToClient) + { + this.ReloadIconSet(); + if (this.IsFormatting) + this.OnFormatCompleted(HRESULT._S_OK); + } + if (!this.ShouldSuppressConnectionNotifications()) + { + this.OnConnectivityChanged(); + this.FirePropertyChanged("IsConnectedToClient"); + this.FirePropertyChanged("IsConnectedToClientWirelessly"); + this.FirePropertyChanged("IsConnectedToClientPhysically"); + if (isReadyForSync != this.IsReadyForSync) + this.FirePropertyChanged("IsReadyForSync"); + } + } + if (connectedToSideloader != this.IsConnectedToSideloader) + { + this.FirePropertyChanged("IsConnectedToSideloader"); + this.FirePropertyChanged("OwnerApplicationName"); + } + if (!this.IsConnectedToPC) + this.IsReadyForSync = false; + else if (state >= EEndpointStatus.eEndpointStatusReadyForSync) + this.IsReadyForSync = true; + switch (state - 6) + { + case EEndpointStatus.eEndpointStatusUndefined: + this.HidePinUnlockDialog(false); + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_PHONE_TLS_ERROR_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_PHONE_TLS_ERROR_TEXT), (EventHandler)null); + break; + case EEndpointStatus.eEndpointStatusNotPresent: + this.ShowPinUnlockDialog(); + break; + case EEndpointStatus.eEndpointStatusHidden: + this.HidePinUnlockDialog(true); + break; + case EEndpointStatus.eEndpointStatusAuthenticationRequired: + if (!hr.IsSuccess) + { + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_ENUMERATION_FAILED_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_DEVICE_ENUMERATION_FAILED_BODY), (EventHandler)null); + SingletonModelItem.Instance.HideDevice(this); + } + if (this.EnumeratedEvent == null) + break; + this.EnumeratedEvent((object)this, new FallibleEventArgs(hr)); + break; + case EEndpointStatus.eEndpointStatusAuthenticationCompleted: + if (this.IsFormatting) + { + this.OnFormatCompleted(HRESULT._S_OK); + break; + } + this.BeginSync(); + if (!this.SupportsPaidApplications) + break; + this.ForceAppUpdate(); + break; + case EEndpointStatus.eEndpointStatusDetectingProxy: + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_PHONE_NO_IP_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_PHONE_NO_IP_TEXT), (EventHandler)null); + break; + } + } + + private void OnConnectivityChanged() + { + if (this.IsConnectedToClient) + { + HRESULT hresult = HRESULT._S_OK; + if (this.UserGuid != Guid.Empty) + { + int hrLogin = 0; + if (((HRESULT)this._device.GetAndResetLastLoginError(ref hrLogin)).IsSuccess) + hresult = (HRESULT)hrLogin; + } + this.LastFailedLoginError = hresult; + } + else + { + if (this.SyncProgress != null) + { + this.SyncProgress.SyncCanceled = true; + this.SyncProgress.Complete(ESyncEventReason.eSyncEventSucceeded); + this.SyncProgress = (SyncNotification)null; + } + this.ReleaseFirmwareObjects(); + } + if (this.ActualGasGauge != null) + this.ActualGasGauge.Dispose(); + if (this.PredictedGasGauge != null) + this.PredictedGasGauge.Dispose(); + this.ActualGasGauge = new UIGasGauge((IModelItemOwner)this, this._device.ActualGasGauge); + this.PredictedGasGauge = new UIGasGauge((IModelItemOwner)this, this._device.PredictedGasGauge); + if (this._device.PredictedGasGauge != null) + { + this._device.PredictedGasGauge.DeviceOverflowEvent -= new DeviceOverflowHandler(this.OnDeviceOverfill); + this._device.PredictedGasGauge.DeviceOverflowEvent += new DeviceOverflowHandler(this.OnDeviceOverfill); + } + this.UpdateWirelessSyncEnabled(); + this.FirePropertyChanged("CanonicalName"); + this.FirePropertyChanged("ZuneTag"); + this.FirePropertyChanged("RequiresClientUpdate"); + this.FirePropertyChanged("RequiresFirmwareUpdate"); + this.FirePropertyChanged("FirmwareVersion"); + this.UserStoppedLastSync = false; + this.LastConnectTimestring = this.GenerateSyncTimestring(); + } + + private void OnFormatCompleted(HRESULT hr) + { + this.FormatSanityTimer.Stop(); + this.IsFormatting = false; + if (this.FormatCompletedEvent == null) + return; + this.FormatCompletedEvent((object)this, new FallibleEventArgs(hr)); + } + + private bool ShouldSuppressConnectionNotifications() + { + if (this.IsFormatting || this.UIFirmwareUpdater != null && this.UIFirmwareUpdater.UpdateInProgress) + return true; + return this.UIFirmwareRestorer != null && this.UIFirmwareRestorer.RestoreInProgress; + } + + private void UpdateWirelessSyncEnabled() + { + bool flag = false; + if (this.IsConnectedToClient) + { + string mediaSyncSSID = (string)null; + bool disabled = false; + HRESULT hresult = this.IsWlanDeviceDisabled(ref disabled); + if (hresult.IsSuccess) + hresult = this.GetWifiMediaSyncSSID(ref mediaSyncSSID); + if (hresult.IsSuccess) + flag = !disabled && !string.IsNullOrEmpty(mediaSyncSSID); + } + this.IsWirelessSyncEnabled = flag; + } + + private void ShowPinUnlockDialog() + { + if (this._pinUnlockMessageBox == null) + { + this._pinUnlockMessageBox = MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_PHONE_PIN_UNLOCK_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_PHONE_PIN_UNLOCK_TEXT), (Command)null, ZuneUI.Shell.LoadString(StringId.IDS_CANCEL_BUTTON), new EventHandler(this.PinUnlockCancelled), false); + } + else + { + if (Application.RenderingType == RenderingType.GDI && SingletonModelItem.Instance.PlayingVideo) + SingletonModelItem.Instance.Stop.Invoke(); + this._pinUnlockMessageBox.Show(); + } + } + + private void HidePinUnlockDialog(bool unlockSucceeded) + { + if (this._pinUnlockMessageBox == null) + return; + if (unlockSucceeded) + this._pinUnlockMessageBox.Hide(); + else + this._pinUnlockMessageBox.Cancel.Invoke(); + this._pinUnlockMessageBox = (MessageBox)null; + } + + private void PinUnlockCancelled(object sender, EventArgs args) => SingletonModelItem.Instance.HideDevice(this); + + private string GenerateSyncTimestring() => DateTime.UtcNow.ToString("yyyy-MM-dd HH\\:mm\\:ss.fff", (IFormatProvider)CultureInfo.CreateSpecificCulture("en-US")); + + private bool SupportsSyncCategory(SyncCategory category) + { + bool flag; + switch (category) + { + case SyncCategory.Friend: + flag = this.SupportsUserCards; + break; + case SyncCategory.Channel: + flag = this.SupportsChannels; + break; + case SyncCategory.Application: + flag = this.SupportsSyncApplications; + break; + default: + flag = true; + break; + } + return flag; + } + + private MediaIdAndType[] GenerateThreadSafeDatabaseItems(IList source) + { + MediaIdAndType[] mediaIdAndTypeArray = new MediaIdAndType[source.Count]; + for (int index = 0; index < source.Count; ++index) + { + if (source[index] is IDatabaseMedia databaseMedia) + { + int mediaId; + EMediaTypes mediaType; + databaseMedia.GetMediaIdAndType(out mediaId, out mediaType); + mediaIdAndTypeArray[index] = new MediaIdAndType(mediaId, mediaType); + } + } + return mediaIdAndTypeArray; + } + + public static void WarnUserAboutFriendSyncSize() + { + if (!ClientConfiguration.MediaStore.AlertSyncAllFriendsBehavior) + return; + BooleanChoice neverAlertSyncAllFriendsBehavior = new BooleanChoice((IModelItemOwner)ZuneShell.DefaultInstance, ZuneUI.Shell.LoadString(StringId.IDS_DONT_SHOW_THIS_MESSAGE_AGAIN)); + neverAlertSyncAllFriendsBehavior.Value = false; + neverAlertSyncAllFriendsBehavior.ChosenChanged += (EventHandler)delegate + { + ClientConfiguration.MediaStore.AlertSyncAllFriendsBehavior = !neverAlertSyncAllFriendsBehavior.Value; + }; + MessageBox.Show(ZuneUI.Shell.LoadString(StringId.IDS_SYNC_FRIENDS_NOTICE_TITLE), ZuneUI.Shell.LoadString(StringId.IDS_SYNC_FRIENDS_NOTICE), (Command)null, neverAlertSyncAllFriendsBehavior); + } + + public static string FormatSyncStatus(object title, IList metadata) + { + string str1 = (title ?? (object)string.Empty).ToString(); + bool flag = false; + foreach (object obj in (IEnumerable)metadata) + { + string str2 = (obj ?? (object)string.Empty).ToString(); + if (!string.IsNullOrEmpty(str2)) + { + if (flag) + { + str1 += UIDevice._syncStatusDatumDivider; + } + else + { + str1 += UIDevice._syncStatusTitleDivider; + flag = true; + } + str1 += str2; + } + } + return str1; + } + + public static string FormatDeviceClass(DeviceClass deviceClass) + { + if (deviceClass == DeviceClass.ZuneHD) + return ZuneUI.Shell.LoadString(StringId.IDS_AppsZuneHDDeviceName); + return deviceClass == DeviceClass.WindowsPhone ? ZuneUI.Shell.LoadString(StringId.IDS_AppsWindowsPhoneDeviceName) : ZuneUI.Shell.LoadString(StringId.IDS_GENERIC_ERROR); + } + + public static DeviceClass ToDeviceClass(int deviceClass) => (DeviceClass)deviceClass; + + public static DeviceClass ToDeviceClass(object deviceClass) + { + DeviceClass? nullable = (DeviceClass?)deviceClass; + return !nullable.HasValue ? DeviceClass.Invalid : nullable.Value; + } + + public static int ToInt32(DeviceClass deviceClass) => (int)deviceClass; + + protected interface INewRuleMessageType + { + MediaType Type { get; } + + string SingularMessage { get; } + + string PluralMessage { get; } + + string GetMessageForCount(int count); + } + + protected class NewRuleMessageType : UIDevice.INewRuleMessageType + { + private MediaType _type; + private string _singular; + private string _plural; + + public NewRuleMessageType(MediaType type, StringId singular, StringId plural) + { + this._type = type; + this._singular = ZuneUI.Shell.LoadString(singular); + this._plural = ZuneUI.Shell.LoadString(plural); + } + + public MediaType Type => this._type; + + public string SingularMessage => this._singular; + + public string PluralMessage => this._plural; + + public string GetMessageForCount(int count) => count == 1 ? this.SingularMessage : string.Format(this.PluralMessage, (object)count); + } + } +} diff --git a/ZuneUI/UIDeviceList.cs b/ZuneUI/UIDeviceList.cs new file mode 100644 index 0000000..a77dafd --- /dev/null +++ b/ZuneUI/UIDeviceList.cs @@ -0,0 +1,364 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.UIDeviceList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using MicrosoftZuneLibrary; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Threading; + +namespace ZuneUI +{ + public class UIDeviceList : SingletonModelItem, IEnumerable, IEnumerable + { + private static UIDevice _nullDevice; + private DeviceList _deviceList; + private Dictionary _deviceToUiMap; + private Dictionary _uiToDeviceMap; + private bool _allowUnreadyDevices = true; + private bool _allowDeviceConnections = true; + private List _deferredConnectedDevices; + private List _deferredUnreadyDevices; + private bool _isDisposed; + private object _initializationLock; + + internal event DeviceListEventHandler DeviceAddedEvent; + + internal event DeviceListEventHandler DeviceRemovedEvent; + + public event DeviceListEventHandler DeviceConnectedEvent; + + public event DeviceListEventHandler DeviceDisconnectedEvent; + + public UIDeviceList() + { + this._deviceToUiMap = new Dictionary(); + this._uiToDeviceMap = new Dictionary(); + this._deferredConnectedDevices = new List(); + this._deferredUnreadyDevices = new List(); + this._initializationLock = new object(); + } + + public void Phase2Init() => ThreadPool.QueueUserWorkItem((WaitCallback)delegate + { + lock (this._initializationLock) + { + if (this._isDisposed) + return; + this._deviceList = DeviceList.Instance; + if (this._deviceList == null) + return; + this._deviceList.Added += new DeviceAddedHandler(this.OnDeviceAdded); + if (this._deviceList.Initialized) + return; + HRESULT hresult = (HRESULT)this._deviceList.InitializeAndEnumerate(); + } + }, (object)null); + + protected override void OnDispose(bool disposing) + { + if (this._deviceList != null) + { + lock (this._initializationLock) + { + this._isDisposed = true; + this._deviceList.Added -= new DeviceAddedHandler(this.OnDeviceAdded); + } + foreach (ModelItem modelItem in this._deviceToUiMap.Values) + modelItem.PropertyChanged -= new PropertyChangedEventHandler(this.OnUIDevicePropertyChanged); + } + base.OnDispose(disposing); + } + + public static UIDevice NullDevice + { + get + { + if (UIDeviceList._nullDevice == null) + UIDeviceList._nullDevice = new UIDevice((IModelItemOwner)SingletonModelItem.Instance, (Device)null); + return UIDeviceList._nullDevice; + } + } + + public void HideDevice(UIDevice device) + { + if (!this.IsListReady) + return; + this._deviceList.HideDevice(this._uiToDeviceMap[device]); + } + + public HRESULT DeleteDevice(UIDevice device) + { + HRESULT hresult = HRESULT._E_UNEXPECTED; + if (this.IsListReady) + { + hresult = (HRESULT)this._uiToDeviceMap[device].ClearCache(); + if (this.DeviceDisconnectedEvent != null) + { + this.DeviceDisconnectedEvent((object)this, new DeviceListEventArgs(device)); + this.FirePropertyChanged("DeviceDisconnectedEvent"); + } + if (this.DeviceRemovedEvent != null) + this.DeviceRemovedEvent((object)this, new DeviceListEventArgs(device)); + } + return hresult; + } + + public bool AllowUnreadyDevices + { + get => this._allowUnreadyDevices; + set + { + if (this._allowUnreadyDevices == value) + return; + this._allowUnreadyDevices = value; + this.FirePropertyChanged(nameof(AllowUnreadyDevices)); + if (!this._allowUnreadyDevices) + return; + if (this._deferredUnreadyDevices.Count > 0) + { + this._deferredConnectedDevices.AddRange((IEnumerable)this._deferredUnreadyDevices); + this._deferredUnreadyDevices.Clear(); + } + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.HandleDeferredConnectedDevices(); + }, DeferredInvokePriority.Low); + } + } + + public bool AllowDeviceConnections + { + get => this._allowDeviceConnections; + set + { + if (this._allowDeviceConnections == value) + return; + this._allowDeviceConnections = value; + this.FirePropertyChanged(nameof(AllowDeviceConnections)); + if (!this._allowDeviceConnections) + return; + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.HandleDeferredConnectedDevices(); + }, DeferredInvokePriority.Low); + } + } + + public string TranscodedFilesCachePath + { + get + { + string empty = string.Empty; + if (this.IsListReady) + this._deviceList.GetTranscodedFilesCachePath(ref empty); + return empty; + } + set + { + if (!this.IsListReady) + return; + this._deviceList.SetTranscodedFilesCachePath(value); + this.FirePropertyChanged("TranscodeCachePath"); + } + } + + public int TranscodedFilesCacheSize + { + get + { + int num = 0; + if (this.IsListReady) + num = ClientConfiguration.Transcode.TranscodedFilesCacheSize; + return num; + } + set + { + if (!this.IsListReady || this.TranscodedFilesCacheSize == value) + return; + this._deviceList.SetTranscodedFilesCacheSize(value); + this.FirePropertyChanged(nameof(TranscodedFilesCacheSize)); + } + } + + public HRESULT ClearTranscodeCache() => !this.IsListReady ? HRESULT._E_UNEXPECTED : (HRESULT)this._deviceList.ClearTranscodeCache(); + + public IEnumerator GetEnumerator() + { + if (this.IsListReady) + { + for (int i = 0; i < this._deviceList.Count; ++i) + { + UIDevice device = this.GetUIDevice(this._deviceList.GetItem(i)); + if (device.IsConnectedToPC || !device.IsGuest) + yield return device; + } + } + } + + IEnumerator IEnumerable.GetEnumerator() => (IEnumerator)this.GetEnumerator(); + + private void OnDeviceAdded(Device rawDevice) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this.GetUIDevice(rawDevice); + }, (object)null); + + private void OnUIDevicePropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(sender is UIDevice device)) + return; + if (args.PropertyName == "IsValid") + { + if (!device.IsValid) + return; + this.OnDeviceValid(device); + } + else + { + if (!(args.PropertyName == "IsConnectedToClient")) + return; + if (device.IsConnectedToClient) + this.OnDeviceConnected(device); + else + this.OnDeviceDisconnected(device); + } + } + + private void OnDeviceValid(UIDevice device) + { + if (!device.IsGuest && this.DeviceAddedEvent != null) + this.DeviceAddedEvent((object)this, new DeviceListEventArgs(device)); + if (!device.SupportsSyncApplications) + return; + ClientConfiguration.Shell.ShowApplicationPivot = true; + Shell.MainFrame.Collection.UpdateApplicationPivot(); + } + + private void OnDeviceConnected(UIDevice device) + { + if (!this.AllowDeviceConnections) + { + if (this._deferredConnectedDevices.Contains(device)) + return; + this._deferredConnectedDevices.Add(device); + } + else if (!this.AllowUnreadyDevices && !UIDeviceList.IsSuitableForConnection(device)) + { + if (this._deferredUnreadyDevices.Contains(device)) + return; + this._deferredUnreadyDevices.Add(device); + } + else + { + if (device.IsGuest && this.DeviceAddedEvent != null) + this.DeviceAddedEvent((object)this, new DeviceListEventArgs(device)); + if (this.DeviceConnectedEvent == null) + return; + this.DeviceConnectedEvent((object)this, new DeviceListEventArgs(device)); + this.FirePropertyChanged("DeviceConnectedEvent"); + } + } + + private void OnDeviceDisconnected(UIDevice device) + { + if (this._deferredConnectedDevices.Contains(device)) + this._deferredConnectedDevices.Remove(device); + if (this._deferredUnreadyDevices.Contains(device)) + this._deferredUnreadyDevices.Remove(device); + if (this.DeviceDisconnectedEvent != null) + { + this.DeviceDisconnectedEvent((object)this, new DeviceListEventArgs(device)); + this.FirePropertyChanged("DeviceDisconnectedEvent"); + } + if (!device.IsGuest || this.DeviceRemovedEvent == null) + return; + this.DeviceRemovedEvent((object)this, new DeviceListEventArgs(device)); + } + + private UIDevice GetUIDevice(Device device) + { + if (!this._deviceToUiMap.ContainsKey(device)) + { + UIDevice key = new UIDevice((IModelItemOwner)this, device); + this._deviceToUiMap.Add(device, key); + this._uiToDeviceMap.Add(key, device); + key.PropertyChanged += new PropertyChangedEventHandler(this.OnUIDevicePropertyChanged); + } + return this._deviceToUiMap[device]; + } + + private void HandleDeferredConnectedDevices() + { + if (!this.AllowDeviceConnections) + return; + for (int index = 0; index < this._deferredConnectedDevices.Count; ++index) + this.OnDeviceConnected(this._deferredConnectedDevices[index]); + this._deferredConnectedDevices.Clear(); + } + + public static bool IsSuitableForConnection(UIDevice device) + { + bool requiresFirmwareUpdate = device.RequiresFirmwareUpdate; + bool flag = device.Relationship == DeviceRelationship.None; + return !requiresFirmwareUpdate && !flag; + } + + private bool IsListReady => this._deviceList != null && this._deviceList.Initialized; + + public static SyncCategory MapMediaTypeToSyncCategory(MediaType mediaType) + { + switch (mediaType) + { + case MediaType.Track: + case MediaType.Playlist: + case MediaType.Album: + case MediaType.Genre: + case MediaType.PlaylistContentItem: + case MediaType.Artist: + return SyncCategory.Music; + case MediaType.Video: + return SyncCategory.Video; + case MediaType.Photo: + case MediaType.MediaFolder: + return SyncCategory.Photo; + case MediaType.PodcastEpisode: + case MediaType.Podcast: + return SyncCategory.Podcast; + case MediaType.UserCard: + return SyncCategory.Friend; + case MediaType.Application: + return SyncCategory.Application; + default: + return SyncCategory.Undefined; + } + } + + public static MediaType MapSyncCategoryToMediaType(SyncCategory mediaType) + { + switch (mediaType) + { + case SyncCategory.Music: + return MediaType.Track; + case SyncCategory.Video: + return MediaType.Video; + case SyncCategory.Photo: + return MediaType.Photo; + case SyncCategory.Podcast: + return MediaType.PodcastEpisode; + case SyncCategory.Friend: + return MediaType.UserCard; + case SyncCategory.Application: + return MediaType.Application; + default: + return MediaType.Undefined; + } + } + } +} diff --git a/ZuneUI/UIFirmwareRestorer.cs b/ZuneUI/UIFirmwareRestorer.cs new file mode 100644 index 0000000..2caa695 --- /dev/null +++ b/ZuneUI/UIFirmwareRestorer.cs @@ -0,0 +1,236 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.UIFirmwareRestorer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; + +namespace ZuneUI +{ + public class UIFirmwareRestorer : ModelItem + { + private FirmwareRestorer _restorer; + private FirmwareRestorePoint _restorePoint; + private bool _restoreInProgress; + private bool _restorePointCollectionRefreshInProgress; + private HRESULT _lastRestoreResult; + private HRESULT _lastRefreshRestorePointResult; + private UpdateStep _currentStep; + private FirmwareUpdateErrorInfo _lastFirmwareRestoreErrorInfo; + private bool _inRecoveryMode; + private bool _needsCollectionRefresh = true; + private bool _fCancelInProgress; + + internal UIFirmwareRestorer(FirmwareRestorer restorer, bool inRecoveryMode) + { + this._restorer = restorer; + this._lastFirmwareRestoreErrorInfo = (FirmwareUpdateErrorInfo)null; + this._inRecoveryMode = inRecoveryMode; + } + + internal FirmwareRestorer FirmwareRestorer => this._restorer; + + public int EstimatedRestoreTime + { + get + { + int num = 0; + if (this._restorePoint != null && this._restorePoint.EstimatedRestoreTime != TimeSpan.Zero) + num = (int)this._restorePoint.EstimatedRestoreTime.TotalMinutes; + return num; + } + } + + public void StartRefreshRestorePointCollection() + { + this.IsCheckingForRestorePoints = true; + this.LastRefreshRestorePointResult = HRESULT._E_PENDING; + if (!this._restorer.StartGetRestorePointCollection(new DeferredInvokeHandler(this.OnRefreshRestorePointCollectionComplete)).IsError) + return; + this.LastRefreshRestorePointResult = HRESULT._E_FAIL; + this.IsCheckingForRestorePoints = false; + } + + private void OnRefreshRestorePointCollectionComplete(object data) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + FirmwareRestorePointCollection restorePointCollection = (FirmwareRestorePointCollection)data; + if (restorePointCollection != null && restorePointCollection.Count > 0) + { + this._restorePoint = restorePointCollection.GetRestorePoint(0); + this.LastRefreshRestorePointResult = HRESULT._S_OK; + } + else + { + this._restorePoint = (FirmwareRestorePoint)null; + this.LastRefreshRestorePointResult = HRESULT._ZUNE_E_NO_AVAILABLE_RESTORE_POINT; + } + this.NeedsCollectionRefresh = false; + this.IsCheckingForRestorePoints = false; + }, data); + + public FirmwareRestorePoint RestorePoint => this._restorePoint; + + public bool IsCheckingForRestorePoints + { + get => this._restorePointCollectionRefreshInProgress; + private set + { + if (this._restorePointCollectionRefreshInProgress == value) + return; + this._restorePointCollectionRefreshInProgress = value; + this.FirePropertyChanged(nameof(IsCheckingForRestorePoints)); + } + } + + public bool NeedsCollectionRefresh + { + get => this._needsCollectionRefresh; + private set + { + if (this._needsCollectionRefresh == value) + return; + this._needsCollectionRefresh = value; + this.FirePropertyChanged(nameof(NeedsCollectionRefresh)); + } + } + + public bool RestoreInProgress + { + get => this._restoreInProgress; + private set + { + if (this._restoreInProgress == value) + return; + this._restoreInProgress = value; + this.FirePropertyChanged(nameof(RestoreInProgress)); + if (this._restoreInProgress) + { + if (this._restorer.EnterContinuousPowerMode()) + ; + } + else + this._restorer.LeaveContinuousPowerMode(); + } + } + + public HRESULT LastRestoreResult + { + get => this._lastRestoreResult; + private set + { + if (!(this._lastRestoreResult != value)) + return; + this._lastRestoreResult = value; + this.FirePropertyChanged(nameof(LastRestoreResult)); + } + } + + public HRESULT LastRefreshRestorePointResult + { + get => this._lastRefreshRestorePointResult; + private set + { + if (!(this._lastRefreshRestorePointResult != value)) + return; + this._lastRefreshRestorePointResult = value; + this.FirePropertyChanged(nameof(LastRefreshRestorePointResult)); + } + } + + public UpdateStep CurrentStep + { + get => this._currentStep; + private set + { + if (this._currentStep == value) + return; + if (this._currentStep != null) + this._currentStep.Dispose(); + this._currentStep = value; + this.FirePropertyChanged(nameof(CurrentStep)); + } + } + + public string LastFirmwareRestoreErrorDescription + { + get + { + string str = string.Empty; + if (this._lastFirmwareRestoreErrorInfo != null && !string.IsNullOrEmpty(this._lastFirmwareRestoreErrorInfo.Description)) + str = this._lastFirmwareRestoreErrorInfo.Description; + else if (this.RestorePoint == null) + str = !this._inRecoveryMode ? Shell.LoadString(StringId.IDS_DEVICE_RESTORE_ERROR_NO_POINTS) : Shell.LoadString(StringId.IDS_DEVICE_RECOVERY_ERROR_NO_POINTS); + return str; + } + } + + public string LastFirmwareRestoreErrorWebHelpUrl => this._lastFirmwareRestoreErrorInfo == null || string.IsNullOrEmpty(this._lastFirmwareRestoreErrorInfo.Url) ? (string)null : this._lastFirmwareRestoreErrorInfo.Url; + + public bool IsOnBatteryPower + { + get + { + bool fOnBatteryPower; + return this._restorer.CheckPowerRequirements(out fOnBatteryPower).IsError || fOnBatteryPower; + } + } + + public void CancelFirmwareRestore() + { + Shell.IgnoreAppNavigationsArgs = false; + if (this._fCancelInProgress || !this.RestoreInProgress && !this.IsCheckingForRestorePoints) + return; + this._fCancelInProgress = true; + this._restorer.Cancel(); + } + + public void StartRestore() + { + if (this.RestoreInProgress) + return; + this.RestoreInProgress = true; + this._lastFirmwareRestoreErrorInfo = (FirmwareUpdateErrorInfo)null; + this.LastRestoreResult = this._restorer.StartFirmwareRestore(this.RestorePoint, new DeferredInvokeHandler(this.OnFirmwareRestoreStepBegin), new DeferredInvokeHandler(this.OnFirmwareRestoreStepProgress), new DeferredInvokeHandler(this.OnFirmwareRestoreCompleted)); + if (this.LastRestoreResult.IsError) + this.RestoreInProgress = false; + else + Shell.IgnoreAppNavigationsArgs = true; + } + + private void OnFirmwareRestoreStepBegin(object data) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!this.RestoreInProgress) + return; + this.CurrentStep = ((FirmwareUpdateBeginArgs)data).Step; + }, data); + + private void OnFirmwareRestoreStepProgress(object data) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!this.RestoreInProgress) + return; + this.CurrentStep = ((FirmwareUpdateProgressArgs)data).Step; + }, data); + + private void OnFirmwareRestoreCompleted(object data) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!this.RestoreInProgress) + return; + FirmwareProcessCompleteArgs processCompleteArgs = (FirmwareProcessCompleteArgs)data; + switch (processCompleteArgs.Action) + { + case CompletionAction.Complete: + this.CurrentStep = (UpdateStep)null; + this.NeedsCollectionRefresh = true; + this.RestoreInProgress = false; + this._fCancelInProgress = false; + this.LastRestoreResult = processCompleteArgs.ErrorInfo.HrStatus; + this._lastFirmwareRestoreErrorInfo = processCompleteArgs.ErrorInfo; + Shell.IgnoreAppNavigationsArgs = false; + break; + } + }, data); + } +} diff --git a/ZuneUI/UIFirmwareUpdater.cs b/ZuneUI/UIFirmwareUpdater.cs new file mode 100644 index 0000000..a588fcf --- /dev/null +++ b/ZuneUI/UIFirmwareUpdater.cs @@ -0,0 +1,577 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.UIFirmwareUpdater +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using MicrosoftZuneLibrary; +using System; +using System.Threading; + +namespace ZuneUI +{ + public class UIFirmwareUpdater : ModelItem + { + private FirmwareUpdater _updater; + private bool _installFirmware; + private bool _installGames; + private UpdatePackageCollection _updateCollection; + private bool _isUpdateAvailable; + private bool _rollbackStarted; + private bool _isCheckingForUpdates; + private bool _updateInProgress; + private UpdateStep _currentStep; + private HRESULT _lastCheckForUpdatesResult; + private HRESULT _lastCheckForDiskSpaceResult; + private FirmwareUpdateErrorInfo _lastCheckForUpdateErrorInfo; + private HRESULT _lastUpdateResult; + private FirmwareUpdateErrorInfo _lastFirmwareUpdateErrorInfo; + private bool _isSoftFailure; + private bool _canCancel; + private bool _needsCollectionRefresh; + private bool _launchWizardIfUpdatesFound; + private bool _fCancelInProgress; + private int _estimatedUpdateTime; + private bool _estimatedUpdateTimeInProgress; + private UIDevice _device; + private bool _requiresSyncBeforeUpdate; + private FirmwareUpdateOption _updateOption; + private CheckDiskSpaceArgs _diskSpaceInfo; + + internal UIFirmwareUpdater(UIDevice device, FirmwareUpdater updater) + { + this._device = device; + this._updater = updater; + this.ResetState(); + } + + private void ResetState() + { + this._installFirmware = false; + this._installGames = false; + this._updateCollection = (UpdatePackageCollection)null; + this._isUpdateAvailable = false; + this._isCheckingForUpdates = false; + this._updateInProgress = false; + this._currentStep = (UpdateStep)null; + this._lastCheckForUpdatesResult = HRESULT._S_OK; + this._lastCheckForDiskSpaceResult = HRESULT._S_OK; + this._lastCheckForUpdateErrorInfo = (FirmwareUpdateErrorInfo)null; + this._lastUpdateResult = HRESULT._S_OK; + this._lastFirmwareUpdateErrorInfo = (FirmwareUpdateErrorInfo)null; + this._isSoftFailure = false; + this._canCancel = true; + this._needsCollectionRefresh = true; + this._launchWizardIfUpdatesFound = false; + this._fCancelInProgress = false; + this._rollbackStarted = false; + this._estimatedUpdateTime = 0; + this._estimatedUpdateTimeInProgress = false; + this._requiresSyncBeforeUpdate = false; + this._updateOption = FirmwareUpdateOption.None; + this._diskSpaceInfo = (CheckDiskSpaceArgs)null; + this.FirePropertyChanged("IsUpdateAvailable"); + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + this._updater.Dispose(); + this._updater = (FirmwareUpdater)null; + this.UpdateCollection = (UpdatePackageCollection)null; + this.CurrentStep = (UpdateStep)null; + } + base.OnDispose(disposing); + } + + internal FirmwareUpdater FirmwareUpdater => this._updater; + + public UpdatePackageCollection UpdateCollection + { + get => this._updateCollection; + private set + { + if (this._updateCollection == value) + return; + if (this._updateCollection != null) + this._updateCollection.Dispose(); + this.UpdateEstimatedTime = 0; + this._updateCollection = value; + this.FirePropertyChanged(nameof(UpdateCollection)); + } + } + + public UpdateStep CurrentStep + { + get => this._currentStep; + private set + { + if (this._currentStep == value) + return; + if (this._currentStep != null) + this._currentStep.Dispose(); + this._currentStep = value; + this.FirePropertyChanged(nameof(CurrentStep)); + this.CanCancel = this._currentStep != null && this._currentStep.Cancelable; + } + } + + public bool CanCancel + { + get => this._canCancel; + private set + { + if (this._canCancel == value) + return; + this._canCancel = value; + this.FirePropertyChanged(nameof(CanCancel)); + } + } + + public bool IsCheckingForUpdates + { + get => this._isCheckingForUpdates; + private set + { + if (this._isCheckingForUpdates == value) + return; + this._isCheckingForUpdates = value; + this.FirePropertyChanged(nameof(IsCheckingForUpdates)); + } + } + + public bool NeedsCollectionRefresh + { + get => this._needsCollectionRefresh; + private set + { + if (this._needsCollectionRefresh == value) + return; + this._needsCollectionRefresh = value; + this.FirePropertyChanged(nameof(NeedsCollectionRefresh)); + } + } + + public FirmwareUpdateOption UpdateOption + { + get => this._updateOption; + set + { + if (this._updateOption == value) + return; + this._updateOption = value; + this.FirePropertyChanged(nameof(UpdateOption)); + } + } + + public CheckDiskSpaceArgs DiskSpaceInfo + { + get => this._diskSpaceInfo; + private set + { + if (this._diskSpaceInfo == value) + return; + this._diskSpaceInfo = value; + this.FirePropertyChanged(nameof(DiskSpaceInfo)); + } + } + + public void StartEstimatedUpdateTimeCalculation() + { + if (this.IsCheckingForUpdates || this._estimatedUpdateTimeInProgress || (this._updateCollection == null || this._updateCollection.FirmwarePackage == null)) + return; + this._estimatedUpdateTimeInProgress = true; + ThreadPool.QueueUserWorkItem(new WaitCallback(this.EstimatedUpdateTimeCalculationWorker), (object)null); + } + + private void EstimatedUpdateTimeCalculationWorker(object args) + { + int estimatedTime = 0; + if (this._updateCollection != null) + { + FirmwareUpdatePackage firmwarePackage = this._updateCollection.FirmwarePackage; + if (firmwarePackage != null) + { + TimeSpan updateEstimatedTime = firmwarePackage.UpdateEstimatedTime; + this._estimatedUpdateTime = -1; + estimatedTime = (int)updateEstimatedTime.TotalMinutes; + } + } + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.UpdateEstimatedTime = estimatedTime; + this._estimatedUpdateTimeInProgress = false; + }, (object)null); + } + + public void StartCheckForUpdates(bool forceServerRequest, bool launchWizardIfUpdatesFound) + { + if (this.IsCheckingForUpdates || !SyncControls.Instance.CurrentDeviceOverride.IsConnectedToClientPhysically) + return; + if (this._device.AllowChainedUpdates && !forceServerRequest) + { + if (this.IsUpdateAvailable && launchWizardIfUpdatesFound) + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)new DeviceUpdateLandPage()); + }, (object)null); + else + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this._device.AllowChainedUpdates = false; + this._device.NavigateToDeviceSummaryAfterUpdate = false; + Shell.MainFrame.Device.Invoke(); + }, (object)null); + } + else + { + this.ResetState(); + this.IsCheckingForUpdates = true; + this._lastCheckForUpdateErrorInfo = (FirmwareUpdateErrorInfo)null; + this._launchWizardIfUpdatesFound = launchWizardIfUpdatesFound; + this.LastCheckForUpdatesResult = this._updater.StartCheckForUpdates(forceServerRequest, new DeferredInvokeHandler(this.OnCheckForUpdatesComplete)); + if (!this.LastCheckForUpdatesResult.IsError) + return; + this.IsCheckingForUpdates = false; + } + } + + private void OnCheckForUpdatesComplete(object data) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + CheckForUpdatesArgs checkForUpdatesArgs = (CheckForUpdatesArgs)data; + this.LastCheckForUpdatesResult = checkForUpdatesArgs.ErrorInfo.HrStatus; + this._lastCheckForUpdateErrorInfo = checkForUpdatesArgs.ErrorInfo; + this._lastFirmwareUpdateErrorInfo = checkForUpdatesArgs.ErrorInfo; + this.RequiresSyncBeforeUpdate = checkForUpdatesArgs.RequiresSyncBeforeUpdate; + if (this.LastCheckForUpdatesResult.IsSuccess) + { + this.UpdateCollection = checkForUpdatesArgs.UpdatePackages; + this.IsUpdateAvailable = this.UpdateCollection != null && this.UpdateCollection.Count > 0; + } + else + this.UpdateCollection = (UpdatePackageCollection)null; + this.NeedsCollectionRefresh = false; + this.IsCheckingForUpdates = false; + if (!this.IsUpdateAvailable || !this._launchWizardIfUpdatesFound || ZuneShell.DefaultInstance.CurrentPage is QuickplayPage && ClientConfiguration.FUE.ShowArtistChooser || (ZuneShell.DefaultInstance.Management.CurrentCategoryPage != null && ZuneShell.DefaultInstance.Management.CurrentCategoryPage.IsWizard || (Shell.SettingsFrame.IsCurrent || ZuneShell.DefaultInstance.CurrentPage is SetupLandPage))) + return; + ZuneShell.DefaultInstance.NavigateToPage((ZunePage)new DeviceUpdateLandPage()); + }, data); + + public void StartCheckForDiskSpace() + { + this._diskSpaceInfo = (CheckDiskSpaceArgs)null; + this.LastCheckForDiskSpaceResult = this._updater.StartCheckForDiskSpace(new DeferredInvokeHandler(this.OnCheckForDiskSpaceComplete)); + } + + private void OnCheckForDiskSpaceComplete(object data) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + CheckDiskSpaceArgs checkDiskSpaceArgs = (CheckDiskSpaceArgs)data; + this.LastCheckForDiskSpaceResult = (HRESULT)checkDiskSpaceArgs.HrStatus; + this.DiskSpaceInfo = checkDiskSpaceArgs; + }, data); + + public void StartFirmwareUpdate() + { + if (this.UpdateInProgress) + return; + this.UpdateInProgress = true; + this._currentStep = (UpdateStep)null; + this._lastUpdateResult = HRESULT._S_OK; + this._lastFirmwareUpdateErrorInfo = (FirmwareUpdateErrorInfo)null; + this._canCancel = true; + this._rollbackStarted = false; + this.LastUpdateResult = this._updater.StartFirmwareUpdate(this._updateCollection, new DeferredInvokeHandler(this.OnFirmwareUpdateStepBegin), new DeferredInvokeHandler(this.OnFirmwareUpdateStepProgress), new DeferredInvokeHandler(this.OnFirmwareUpdateCompleted), this.UpdateOption); + if (this.LastUpdateResult.IsError) + this.UpdateInProgress = false; + else + Shell.IgnoreAppNavigationsArgs = true; + } + + private void OnFirmwareUpdateStepBegin(object data) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!this.UpdateInProgress) + return; + this.CurrentStep = ((FirmwareUpdateBeginArgs)data).Step; + }, data); + + private void OnFirmwareUpdateStepProgress(object data) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!this.UpdateInProgress) + return; + this.CurrentStep = ((FirmwareUpdateProgressArgs)data).Step; + }, data); + + private void OnFirmwareUpdateCompleted(object data) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (!this.UpdateInProgress) + return; + FirmwareProcessCompleteArgs processCompleteArgs = (FirmwareProcessCompleteArgs)data; + switch (processCompleteArgs.Action) + { + case CompletionAction.Reboot: + if (!this.IsLegacyZuneDevice()) + break; + this.CanCancel = true; + break; + case CompletionAction.Rollback: + this.CanCancel = false; + this.RollbackStarted = true; + break; + case CompletionAction.Complete: + this.CurrentStep = (UpdateStep)null; + this.CanCancel = true; + this.NeedsCollectionRefresh = true; + this.UpdateInProgress = false; + this._fCancelInProgress = false; + this.LastUpdateResult = processCompleteArgs.ErrorInfo.HrStatus; + this._lastFirmwareUpdateErrorInfo = processCompleteArgs.ErrorInfo; + this.IsUpdateAvailable = this.LastUpdateResult.IsError && !this.IsSoftFailure; + Shell.IgnoreAppNavigationsArgs = false; + break; + } + }, data); + + public HRESULT LastCheckForUpdatesResult + { + get => this._lastCheckForUpdatesResult; + private set + { + if (!(this._lastCheckForUpdatesResult != value)) + return; + this._lastCheckForUpdatesResult = value; + this.FirePropertyChanged(nameof(LastCheckForUpdatesResult)); + } + } + + public HRESULT LastCheckForDiskSpaceResult + { + get => this._lastCheckForDiskSpaceResult; + private set + { + if (!(this._lastCheckForDiskSpaceResult != value)) + return; + this._lastCheckForDiskSpaceResult = value; + this.FirePropertyChanged(nameof(LastCheckForDiskSpaceResult)); + } + } + + public string LastCheckForUpdateErrorOverrideDescription => this._lastCheckForUpdateErrorInfo == null || string.IsNullOrEmpty(this._lastCheckForUpdateErrorInfo.Description) ? (string)null : this._lastCheckForUpdateErrorInfo.Description; + + public string LastCheckForUpdateErrorWebHelpUrl => this._lastCheckForUpdateErrorInfo == null || string.IsNullOrEmpty(this._lastCheckForUpdateErrorInfo.Url) ? (string)null : this._lastCheckForUpdateErrorInfo.Url; + + public HRESULT LastUpdateResult + { + get => this._lastUpdateResult; + private set + { + if (!(this._lastUpdateResult != value)) + return; + this._lastUpdateResult = value; + this.FirePropertyChanged(nameof(LastUpdateResult)); + this.IsSoftFailure = this._lastUpdateResult == HRESULT._NS_E_FIRMWARE_UPDATE_DISK_FULL; + } + } + + public string LastFirmwareUpdateErrorOverrideDescription => this._lastFirmwareUpdateErrorInfo == null || string.IsNullOrEmpty(this._lastFirmwareUpdateErrorInfo.Description) ? (string)null : this._lastFirmwareUpdateErrorInfo.Description; + + public string LastFirmwareUpdateErrorWebHelpUrl => this._lastFirmwareUpdateErrorInfo == null || string.IsNullOrEmpty(this._lastFirmwareUpdateErrorInfo.Url) ? (string)null : this._lastFirmwareUpdateErrorInfo.Url; + + public bool IsSoftFailure + { + get => this._isSoftFailure; + private set + { + if (this._isSoftFailure == value) + return; + this._isSoftFailure = value; + this.FirePropertyChanged(nameof(IsSoftFailure)); + } + } + + public bool UpdateInProgress + { + get => this._updateInProgress; + private set + { + if (this._updateInProgress == value) + return; + this._updateInProgress = value; + this.FirePropertyChanged(nameof(UpdateInProgress)); + if (this._updateInProgress) + { + if (this._updater.EnterContinuousPowerMode()) + ; + } + else + this._updater.LeaveContinuousPowerMode(); + } + } + + public bool RollbackStarted + { + get => this._rollbackStarted; + set + { + if (this._rollbackStarted == value) + return; + this._rollbackStarted = value; + this.FirePropertyChanged(nameof(RollbackStarted)); + } + } + + public bool IsUpdateAvailable + { + get => this._isUpdateAvailable; + private set + { + if (this._isUpdateAvailable == value) + return; + this._isUpdateAvailable = value; + this.FirePropertyChanged(nameof(IsUpdateAvailable)); + } + } + + public string AvailableFirmwareDescription + { + get + { + string str = (string)null; + if (this._updateCollection != null) + { + FirmwareUpdatePackage firmwarePackage = this._updateCollection.FirmwarePackage; + if (firmwarePackage != null) + str = !SyncControls.Instance.CurrentDeviceOverride.SupportsBrandingType(DeviceBranding.WindowsPhone) ? StringParserHelper.FormatFirmwareVersion(firmwarePackage.Version) : firmwarePackage.Name; + } + return str; + } + } + + public string NewFirmwareEULAContent + { + get + { + string str = (string)null; + if (this._updateCollection != null) + { + FirmwareUpdatePackage firmwarePackage = this._updateCollection.FirmwarePackage; + if (firmwarePackage != null) + str = firmwarePackage.EULAContent; + } + return str; + } + } + + public string MoreInfoURL + { + get + { + string str = (string)null; + if (this._updateCollection != null) + { + FirmwareUpdatePackage firmwarePackage = this._updateCollection.FirmwarePackage; + if (firmwarePackage != null) + str = firmwarePackage.MoreInfoURL; + } + return str; + } + } + + public int UpdateEstimatedTime + { + get => this._estimatedUpdateTime; + set + { + if (this._estimatedUpdateTime == value) + return; + this._estimatedUpdateTime = value; + this.FirePropertyChanged(nameof(UpdateEstimatedTime)); + } + } + + public string NewFirmwareDescription + { + get + { + string str = string.Empty; + if (this._updateCollection != null) + { + FirmwareUpdatePackage firmwarePackage = this._updateCollection.FirmwarePackage; + if (firmwarePackage != null) + str = firmwarePackage.Description; + } + return str; + } + } + + public bool GamesPackIsOnlyUpdateAvailable => this._updateCollection != null && this._updateCollection.FirmwarePackage == null && this._updateCollection.GamesPackage != null; + + public void CancelFirmwareUpdate() + { + Shell.IgnoreAppNavigationsArgs = false; + if (this._fCancelInProgress || !this.UpdateInProgress && !this.IsCheckingForUpdates) + return; + this._fCancelInProgress = true; + this._updater.Cancel(); + } + + public bool InstallFirmware + { + get => this._installFirmware; + set + { + if (this._installFirmware == value) + return; + this._installFirmware = value; + this.FirePropertyChanged(nameof(InstallFirmware)); + for (int index = 0; index < this._updateCollection.Count; ++index) + { + if (this._updateCollection.get_Item(index).Type == FirmwareUpdateType.Firmware) + this._updateCollection.set_Selected(index, this._installFirmware); + } + } + } + + public bool InstallGames + { + get => this._installGames; + set + { + if (this._installGames == value) + return; + this._installGames = value; + this.FirePropertyChanged(nameof(InstallGames)); + for (int index = 0; index < this._updateCollection.Count; ++index) + { + if (this._updateCollection.get_Item(index).Type == FirmwareUpdateType.Games) + this._updateCollection.set_Selected(index, this._installGames); + } + } + } + + private bool IsLegacyZuneDevice() => SyncControls.Instance.CurrentDeviceOverride.Class == DeviceClass.Classic; + + public bool IsOnBatteryPower + { + get + { + bool fOnBatteryPower; + return this._updater.CheckPowerRequirements(out fOnBatteryPower).IsError || fOnBatteryPower; + } + } + + public bool RequiresSyncBeforeUpdate + { + get => this._requiresSyncBeforeUpdate; + private set + { + if (this._requiresSyncBeforeUpdate == value) + return; + this._requiresSyncBeforeUpdate = value; + this.FirePropertyChanged(nameof(RequiresSyncBeforeUpdate)); + } + } + } +} diff --git a/ZuneUI/UIGasGauge.cs b/ZuneUI/UIGasGauge.cs new file mode 100644 index 0000000..0eeb566 --- /dev/null +++ b/ZuneUI/UIGasGauge.cs @@ -0,0 +1,191 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.UIGasGauge +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class UIGasGauge : ModelItem + { + private GasGauge _gauge; + private int _dividerCount; + private bool _hideGuestSpace; + + public UIGasGauge(IModelItemOwner owner, GasGauge gauge) + : base(owner) + { + this._gauge = gauge; + if (this._gauge != null) + { + this._gauge.CategorySpaceUsedUpdatedEvent += new CategorySpaceUsedUpdatedHandler(this.OnCategorySpaceUpdated); + this._gauge.ReservedSpaceUpdatedEvent += new ReservedSpaceUpdatedHandler(this.OnReservedSpaceUpdated); + } + if (!(owner is UIDevice uiDevice) && owner is SyncGroupList syncGroupList) + uiDevice = syncGroupList.Device; + if (uiDevice == null) + return; + int advertisedCapacity = uiDevice.AdvertisedCapacity; + while (advertisedCapacity > 8) + { + if (advertisedCapacity % 10 == 0) + advertisedCapacity /= 10; + else if (advertisedCapacity % 5 == 0) + advertisedCapacity /= 5; + else if (advertisedCapacity % 3 == 0) + advertisedCapacity /= 3; + else + advertisedCapacity /= 2; + } + this._dividerCount = advertisedCapacity; + } + + protected override void OnDispose(bool disposing) + { + if (disposing && this._gauge != null) + { + this._gauge.CategorySpaceUsedUpdatedEvent -= new CategorySpaceUsedUpdatedHandler(this.OnCategorySpaceUpdated); + this._gauge.ReservedSpaceUpdatedEvent -= new ReservedSpaceUpdatedHandler(this.OnReservedSpaceUpdated); + } + base.OnDispose(disposing); + } + + public long TotalSpace => this._gauge == null ? 0L : (long)this._gauge.Capacity; + + public long MusicSpace => this._gauge == null ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryMusic); + + public long VideoSpace => this._gauge == null ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryVideo); + + public long PhotoSpace => this._gauge == null ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryPhotos); + + public long PodcastSpace => this._gauge == null ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryPodcasts); + + public long FriendSpace => this._gauge == null ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryFriends); + + public long ChannelSpace => this._gauge == null ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryChannels); + + public long AudiobookSpace => this._gauge == null ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryAudiobooks); + + public long ApplicationSpace => this._gauge == null ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryApps); + + public long GuestSpace => this._gauge == null || this._hideGuestSpace ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryGuest); + + public long InboxSpace => this._gauge == null ? 0L : this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryInbox); + + public long ReservedSpace => this._gauge == null ? 0L : this._gauge.SpaceReserved; + + public long OtherSpace + { + get + { + long num1 = 0; + if (this._gauge != null) + { + long num2 = this.ReservedSpace - this.AudiobookSpace; + num1 = (num2 > this.InboxSpace ? num2 : this.InboxSpace) + this.GuestSpace; + } + return num1; + } + } + + public long FreeSpace + { + get + { + long num = 0; + if (this._gauge != null) + { + num = this._gauge.SpaceAvailable; + if (this._hideGuestSpace) + num += this._gauge.GetSpaceUsedByCategory(ESyncCategory.eSyncCategoryGuest); + } + return num; + } + } + + public long UsedSpace => this.TotalSpace - this.FreeSpace; + + public int DividerCount => this._dividerCount; + + public bool HideGuestSpace + { + get => this._hideGuestSpace; + set + { + if (this._hideGuestSpace == value) + return; + this._hideGuestSpace = value; + this.FirePropertyChanged(nameof(HideGuestSpace)); + this.FirePropertyChanged("GuestSpace"); + this.FirePropertyChanged("OtherSpace"); + this.FirePropertyChanged("UsedSpace"); + this.FirePropertyChanged("FreeSpace"); + } + } + + private void OnCategorySpaceUpdated( + GasGauge gasGauge, + ESyncCategory category, + long llNewSchemaSpace, + long llNewFreeSpace) + { + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this.FirePropertyChanged("UsedSpace"); + this.FirePropertyChanged("FreeSpace"); + this.FirePropertyChanged("OtherSpace"); + switch (category) + { + case ESyncCategory.eSyncCategoryMusic: + this.FirePropertyChanged("MusicSpace"); + break; + case ESyncCategory.eSyncCategoryVideo: + this.FirePropertyChanged("VideoSpace"); + break; + case ESyncCategory.eSyncCategoryPhotos: + this.FirePropertyChanged("PhotoSpace"); + break; + case ESyncCategory.eSyncCategoryPodcasts: + this.FirePropertyChanged("PodcastSpace"); + break; + case ESyncCategory.eSyncCategoryFriends: + this.FirePropertyChanged("FriendSpace"); + break; + case ESyncCategory.eSyncCategoryAudiobooks: + this.FirePropertyChanged("AudiobookSpace"); + break; + case ESyncCategory.eSyncCategoryChannels: + this.FirePropertyChanged("ChannelSpace"); + break; + case ESyncCategory.eSyncCategoryApps: + this.FirePropertyChanged("ApplicationSpace"); + break; + case ESyncCategory.eSyncCategoryGuest: + this.FirePropertyChanged("GuestSpace"); + break; + } + }, (object)null); + } + + private void OnReservedSpaceUpdated( + GasGauge gasGauge, + long llNewReservedSpace, + long llNewFreeSpace) + { + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + if (this.IsDisposed) + return; + this.FirePropertyChanged("ReservedSpace"); + this.FirePropertyChanged("UsedSpace"); + this.FirePropertyChanged("FreeSpace"); + this.FirePropertyChanged("OtherSpace"); + }, (object)null); + } + } +} diff --git a/ZuneUI/UpdateDialogInfo.cs b/ZuneUI/UpdateDialogInfo.cs new file mode 100644 index 0000000..347ec76 --- /dev/null +++ b/ZuneUI/UpdateDialogInfo.cs @@ -0,0 +1,36 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.UpdateDialogInfo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using UIXControls; + +namespace ZuneUI +{ + public class UpdateDialogInfo + { + internal static void Show(bool updateFound, bool fIsCritical, bool isUserInitiated) + { + if (updateFound) + { + EventHandler cancelCommand = (EventHandler)null; + string message = !fIsCritical ? Shell.LoadString(StringId.IDS_UPDATE_AVAILABLE) : Shell.LoadString(StringId.IDS_CRITICAL_UPDATE_AVAILABLE); + string cancelText = Shell.LoadString(StringId.IDS_UPDATE_INSTALL_LATER); + Command okCommand = new Command((IModelItemOwner)null, Shell.LoadString(StringId.IDS_UPDATE_INSTALL_NOW), (EventHandler)null); + okCommand.Invoked += (EventHandler)delegate + { + SoftwareUpdates.Instance.InstallUpdates(); + }; + if (!isUserInitiated) + cancelCommand = (EventHandler)((sender, e) => SQMLog.Log(SQMDataId.UserDeferredAutomaticUpdate, 1)); + MessageBox.Show((string)null, message, okCommand, cancelText, cancelCommand, true); + } + else + MessageBox.Show((string)null, Shell.LoadString(StringId.IDS_UPDATE_NOT_REQUIRED), (EventHandler)null); + } + } +} diff --git a/ZuneUI/UrlHelper.cs b/ZuneUI/UrlHelper.cs new file mode 100644 index 0000000..b212acb --- /dev/null +++ b/ZuneUI/UrlHelper.cs @@ -0,0 +1,338 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.UrlHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Util; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace ZuneUI +{ + public class UrlHelper + { + private static string _endPoint = (string)null; + private static Size[] _acceptableValues = new Size[25] + { + new Size(1920, 1080), + new Size(1280, 720), + new Size(854, 480), + new Size(853, 480), + new Size(480, 480), + new Size(420, 320), + new Size(320, 320), + new Size(258, 258), + new Size(258, 194), + new Size(240, 240), + new Size(234, 320), + new Size(172, 258), + new Size(160, 160), + new Size(160, 120), + new Size(107, 160), + new Size(100, 100), + new Size(72, 72), + new Size(64, 64), + new Size(64, 48), + new Size(60, 60), + new Size(52, 52), + new Size(50, 50), + new Size(44, 44), + new Size(43, 64), + new Size(40, 40) + }; + private static int[] _acceptableWidths = new int[22] + { + 1920, + 1280, + 854, + 853, + 480, + 420, + 320, + 258, + 240, + 234, + 172, + 160, + 107, + 100, + 72, + 64, + 60, + 52, + 50, + 44, + 43, + 40 + }; + private static int[] _acceptableHeights = new int[18] + { + 1080, + 720, + 480, + 320, + 258, + 240, + 194, + 160, + 120, + 100, + 72, + 64, + 60, + 52, + 50, + 48, + 44, + 40 + }; + + public static string GetReturnUrl() => Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_ZuneNet) + Shell.LoadString(StringId.IDS_RETURN_URL); + + public static string MakeUrlWithReturnParams(string urlPath) + { + string returnUrl = UrlHelper.GetReturnUrl(); + return UrlHelper.MakeUrl(urlPath, "ru", returnUrl, "aru", returnUrl); + } + + public static string MakeUrl(string urlPath) => UrlHelper.MakeUrlEx(urlPath, (string[])null); + + public static string MakeUrl(string urlPath, string paramName1, string paramValue1) => UrlHelper.MakeUrlEx(urlPath, paramName1, paramValue1); + + public static string MakeUrl( + string urlPath, + string paramName1, + string paramValue1, + string paramName2, + string paramValue2) + { + return UrlHelper.MakeUrlEx(urlPath, paramName1, paramValue1, paramName2, paramValue2); + } + + public static string MakeUrl( + string urlPath, + string paramName1, + string paramValue1, + string paramName2, + string paramValue2, + string paramName3, + string paramValue3) + { + return UrlHelper.MakeUrlEx(urlPath, paramName1, paramValue1, paramName2, paramValue2, paramName3, paramValue3); + } + + public static string MakeUrl( + string urlPath, + string paramName1, + string paramValue1, + string paramName2, + string paramValue2, + string paramName3, + string paramValue3, + string paramName4, + string paramValue4) + { + return UrlHelper.MakeUrlEx(urlPath, paramName1, paramValue1, paramName2, paramValue2, paramName3, paramValue3, paramName4, paramValue4); + } + + public static string MakeUrlEx(string urlPath, params string[] args) + { + StringBuilder args1 = new StringBuilder(256); + args1.Append(Uri.EscapeUriString(urlPath)); + if (args != null && args.Length > 0) + { + for (int index = 0; index + 1 < args.Length; index += 2) + UrlHelper.AppendParam(index == 0, args1, args[index], args[index + 1]); + } + return args1.ToString(); + } + + public static void AppendParam( + bool first, + StringBuilder args, + string paramName, + string paramValue) + { + if (first) + args.Append("?"); + else + args.Append('&'); + args.Append(paramName); + args.Append('='); + args.Append(Uri.EscapeDataString(paramValue)); + } + + public static string PrependHttpIfMissing(string url) + { + if (url.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) + return url; + StringBuilder stringBuilder = new StringBuilder("http://", url.Length + 7); + stringBuilder.Append(url); + return stringBuilder.ToString(); + } + + public static bool ValidUri(string url) + { + try + { + Uri uri = new Uri(url); + } + catch (Exception ex) + { + return false; + } + return true; + } + + public static string StripVersion(string url) + { + if (Regex.Match(url, "^/v[0-9]+\\.[0-9]+/").Success) + url = url.Substring(url.IndexOf("/", 1)); + return url; + } + + public static string StripLocale(string url) + { + if (Regex.Match(url, "^/[a-zA-Z]{2}-[a-zA-Z]{2}/").Success) + url = url.Substring(url.IndexOf("/", 1)); + return url; + } + + private static void FindMatchingHeight(ref int width, out int height) + { + int index = 0; + while (index < UrlHelper._acceptableWidths.Length - 1 && width <= UrlHelper._acceptableWidths[index + 1]) + ++index; + width = UrlHelper._acceptableWidths[index]; + height = 0; + foreach (Size acceptableValue in UrlHelper._acceptableValues) + { + if (acceptableValue.Width == width) + { + height = acceptableValue.Height; + break; + } + } + } + + private static void FindMatchingWidth(out int width, ref int height) + { + int index = 0; + while (index < UrlHelper._acceptableHeights.Length - 1 && height <= UrlHelper._acceptableHeights[index + 1]) + ++index; + height = UrlHelper._acceptableHeights[index]; + width = 0; + foreach (Size acceptableValue in UrlHelper._acceptableValues) + { + if (acceptableValue.Height == height) + { + width = acceptableValue.Width; + break; + } + } + } + + private static void CalculateImageUriSize(ref int width, ref int height) + { + if (width == 0) + { + if (height == 0) + { + width = ImageConstants.Default.Width; + height = ImageConstants.Default.Height; + } + else + UrlHelper.FindMatchingWidth(out width, ref height); + } + else if (height == 0) + { + UrlHelper.FindMatchingHeight(ref width, out height); + } + else + { + int index = 0; + while (index < UrlHelper._acceptableValues.Length - 1 && width <= UrlHelper._acceptableValues[index + 1].Width) + ++index; + width = UrlHelper._acceptableValues[index].Width; + while (index < UrlHelper._acceptableValues.Length - 1 && width == UrlHelper._acceptableValues[index + 1].Width && height <= UrlHelper._acceptableValues[index + 1].Height) + ++index; + height = UrlHelper._acceptableValues[index].Height; + } + } + + public static string MakeCatalogImageUri(Guid imageId) => UrlHelper.MakeCatalogImageUri(imageId, 0, 0); + + public static string MakeCatalogImageUri(Guid imageId, int width, int height) => UrlHelper.MakeCatalogImageUri(imageId, width, height, ImageIdType.ImageId, ImageRequested.PrimaryImage); + + public static string MakeCatalogImageUri( + Guid imageId, + int width, + int height, + ImageIdType imageIdType, + ImageRequested requestedImage) + { + return UrlHelper.MakeCatalogImageUri(imageId, width, height, imageIdType, requestedImage, false, false); + } + + public static string MakeCatalogImageUri( + Guid imageId, + int width, + int height, + ImageIdType imageIdType, + ImageRequested requestedImage, + bool forceImageResize, + bool ignoreZeroLengths) + { + if (UrlHelper._endPoint == null) + UrlHelper._endPoint = Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_ImageCatalog); + string empty = string.Empty; + string urlPath; + switch (imageIdType) + { + case ImageIdType.MovieId: + urlPath = string.Format("{0}/movie/{1}/{2}", (object)UrlHelper._endPoint, (object)imageId.ToString(), (object)requestedImage.ToString()); + break; + case ImageIdType.ArtistId: + urlPath = string.Format("{0}/music/artist/{1}/{2}", (object)UrlHelper._endPoint, (object)imageId.ToString(), (object)requestedImage.ToString()); + break; + case ImageIdType.MovieTrailerId: + urlPath = string.Format("{0}/movieTrailer/{1}/{2}", (object)UrlHelper._endPoint, (object)imageId.ToString(), (object)requestedImage.ToString()); + break; + case ImageIdType.ParentalRatingId: + urlPath = string.Format("{0}/apps/{1}/ratingImage", (object)Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_RootCatalog), (object)imageId.ToString()); + break; + default: + urlPath = string.Format("{0}/image/{1}", (object)UrlHelper._endPoint, (object)imageId.ToString()); + break; + } + List stringList = new List(); + if (forceImageResize) + stringList.AddRange((IEnumerable)new string[2] + { + "resize", + "true" + }); + int width1 = width; + int height1 = height; + if (width1 != ImageConstants.NowPlaying.Width && height1 != ImageConstants.NowPlaying.Height) + UrlHelper.CalculateImageUriSize(ref width1, ref height1); + if (width > 0 || !ignoreZeroLengths) + stringList.AddRange((IEnumerable)new string[2] + { + nameof (width), + width1.ToString() + }); + if (height > 0 || !ignoreZeroLengths) + stringList.AddRange((IEnumerable)new string[2] + { + nameof (height), + height1.ToString() + }); + return UrlHelper.MakeUrlEx(urlPath, stringList.ToArray()); + } + } +} diff --git a/ZuneUI/UserRelationship.cs b/ZuneUI/UserRelationship.cs new file mode 100644 index 0000000..44f6ca8 --- /dev/null +++ b/ZuneUI/UserRelationship.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.UserRelationship +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum UserRelationship + { + Unknown, + Self, + IsFriend, + IsNotFriend, + } +} diff --git a/ZuneUI/VideoAttachment.cs b/ZuneUI/VideoAttachment.cs new file mode 100644 index 0000000..1d09696 --- /dev/null +++ b/ZuneUI/VideoAttachment.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoAttachment +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; + +namespace ZuneUI +{ + public abstract class VideoAttachment : Attachment + { + public VideoAttachment(Guid id, string title, string subtitle, string imageUri) + : base(id, title, subtitle, imageUri) + { + } + + public override MediaType MediaType => MediaType.Video; + + public override void LogSend() => SQMLog.Log(SQMDataId.InboxMessageSendVideo, 1); + } +} diff --git a/ZuneUI/VideoCategory.cs b/ZuneUI/VideoCategory.cs new file mode 100644 index 0000000..242d77f --- /dev/null +++ b/ZuneUI/VideoCategory.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoCategory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum VideoCategory + { + TV = 5, + News = 6, + Music = 7, + Movies = 8, + Other = 10, // 0x0000000A + Personal = 128, // 0x00000080 + Shorts = 129, // 0x00000081 + } +} diff --git a/ZuneUI/VideoDefinition.cs b/ZuneUI/VideoDefinition.cs new file mode 100644 index 0000000..e0d1880 --- /dev/null +++ b/ZuneUI/VideoDefinition.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoDefinition +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum VideoDefinition + { + Unknown, + Low, + Standard480i, + Standard576i, + Enhanced480p, + Enhanced576p, + High720p, + High1080i, + High1080p, + } +} diff --git a/ZuneUI/VideoDefinitionHelper.cs b/ZuneUI/VideoDefinitionHelper.cs new file mode 100644 index 0000000..415e1ff --- /dev/null +++ b/ZuneUI/VideoDefinitionHelper.cs @@ -0,0 +1,13 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoDefinitionHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public static class VideoDefinitionHelper + { + public static bool IsHD(VideoDefinition def) => def == VideoDefinition.High1080p || def == VideoDefinition.High1080i || def == VideoDefinition.High720p; + } +} diff --git a/ZuneUI/VideoDescriptions.cs b/ZuneUI/VideoDescriptions.cs new file mode 100644 index 0000000..ab87971 --- /dev/null +++ b/ZuneUI/VideoDescriptions.cs @@ -0,0 +1,100 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoDescriptions +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public static class VideoDescriptions + { + private static string _tvViewHeader = Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_TV); + private static string _musicViewHeader = (string)null; + private static string _movieViewHeader = (string)null; + private static string _otherViewHeader = (string)null; + private static string _personalViewHeader = (string)null; + private static string _seriesDescription = Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_TV_SERIES); + private static string _shortsDescription = Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_TV_SHORTS); + private static string _newsDescription = Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_TV_NEWS); + private static string _musicDescription = Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_MUSIC); + private static string _moviesDescription = Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_MOVIES); + private static string _otherDescription = Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_OTHER); + private static string _personalDescription = Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_PERSONAL); + private static VideoViewCategory _tvCategory = new VideoViewCategory(VideoDescriptions._tvViewHeader, VideoDescriptions._seriesDescription); + private static VideoViewCategory _shortsCategory = new VideoViewCategory(VideoDescriptions._tvViewHeader, VideoDescriptions._shortsDescription); + private static VideoViewCategory _newsCategory = new VideoViewCategory(VideoDescriptions._tvViewHeader, VideoDescriptions._newsDescription); + private static VideoViewCategory _musicCategory = new VideoViewCategory(VideoDescriptions._musicViewHeader, VideoDescriptions._musicDescription); + private static VideoViewCategory _moviesCategory = new VideoViewCategory(VideoDescriptions._movieViewHeader, VideoDescriptions._moviesDescription); + private static VideoViewCategory _otherCategory = new VideoViewCategory(VideoDescriptions._otherViewHeader, VideoDescriptions._otherDescription); + private static VideoViewCategory _personalCategory = new VideoViewCategory(VideoDescriptions._personalViewHeader, VideoDescriptions._personalDescription); + private static GroupedList _groupedCategories; + + public static int GetCategoryId(VideoCategory category) => (int)category; + + public static VideoCategory GetCategory(int id) => (VideoCategory)id; + + public static string GetDescription(int categoryId) => VideoDescriptions.GetDescription((VideoCategory)categoryId); + + public static string GetDescription(VideoCategory category) + { + switch (category) + { + case VideoCategory.TV: + return VideoDescriptions._seriesDescription; + case VideoCategory.News: + return VideoDescriptions._newsDescription; + case VideoCategory.Music: + return VideoDescriptions._musicDescription; + case VideoCategory.Movies: + return VideoDescriptions._moviesDescription; + case VideoCategory.Personal: + return VideoDescriptions._personalDescription; + case VideoCategory.Shorts: + return VideoDescriptions._shortsDescription; + default: + return VideoDescriptions._otherDescription; + } + } + + public static VideoCategory GetCategory(string description) + { + if (description == VideoDescriptions._seriesDescription) + return VideoCategory.TV; + if (description == VideoDescriptions._shortsDescription) + return VideoCategory.Shorts; + if (description == VideoDescriptions._newsDescription) + return VideoCategory.News; + if (description == VideoDescriptions._musicDescription) + return VideoCategory.Music; + if (description == VideoDescriptions._moviesDescription) + return VideoCategory.Movies; + return description == VideoDescriptions._personalDescription ? VideoCategory.Personal : VideoCategory.Other; + } + + public static GroupedList Categories + { + get + { + if (VideoDescriptions._groupedCategories == null) + { + VideoDescriptions._groupedCategories = new GroupedList(); + VideoDescriptions._groupedCategories.Comparer = (IComparer)new VideoViewCategoryComparer(); + VideoDescriptions._groupedCategories.Source = (IList)new VideoViewCategory[7] + { + VideoDescriptions._tvCategory, + VideoDescriptions._shortsCategory, + VideoDescriptions._newsCategory, + VideoDescriptions._musicCategory, + VideoDescriptions._moviesCategory, + VideoDescriptions._otherCategory, + VideoDescriptions._personalCategory + }; + } + return VideoDescriptions._groupedCategories; + } + } + } +} diff --git a/ZuneUI/VideoDetails.cs b/ZuneUI/VideoDetails.cs new file mode 100644 index 0000000..71a85ac --- /dev/null +++ b/ZuneUI/VideoDetails.cs @@ -0,0 +1,161 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoDetails +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class VideoDetails + { + private static int[] ColumnIndexes = new int[15] + { + 344, + 151, + 32, + 177, + 181, + 317, + 138, + 443, + 442, + 175, + 176, + 68, + 49, + 149, + 451 + }; + private static string[] DataProperties = new string[15] + { + "Title", + "Duration", + "Bitrate", + "FileType", + "FolderName", + "FilePath", + "ArtistName", + "Width", + "Height", + "FileName", + "FileSize", + "Copyright", + "CategoryId", + "DrmState", + "ZuneMediaId" + }; + private static string _actorFormat = ZuneUI.Shell.LoadString(StringId.IDS_ACTORS_SEPARATION_FORMAT); + private static string _directorFormat = ZuneUI.Shell.LoadString(StringId.IDS_DIRECTORS_SEPARATION_FORMAT); + private static string _daysExpirationFormat = ZuneUI.Shell.LoadString(StringId.IDS_VIDEO_EXPIRATION_DAYS); + private static string _hoursExpirationFormat = ZuneUI.Shell.LoadString(StringId.IDS_VIDEO_EXPIRATION_HOURS); + private static string _deviceRentalFormat = ZuneUI.Shell.LoadString(StringId.IDS_VIDEO_DEVICE_RENTAL_FORMAT); + + public static string ActorListToString(IList artists) => VideoDetails.ContributingArtistListToString(artists, VideoDetails._actorFormat); + + public static string DirectorListToString(IList directors) => VideoDetails.ContributingArtistListToString(directors, VideoDetails._directorFormat); + + private static string ContributingArtistListToString(IList artists, string format) + { + string str = ""; + if (artists != null) + { + foreach (string artist in (IEnumerable)artists) + str = str.Length != 0 ? string.Format(format, (object)str, (object)artist) : artist; + } + return str; + } + + public static IList DeviceRentalStatusList(Guid zuneMediaId) + { + IList list = (IList)new List(); + foreach (UIDevice uiDevice in SingletonModelItem.Instance) + { + if (ZuneApplication.Service.InCompleteCollection(zuneMediaId, Microsoft.Zune.Service.EContentType.Video, uiDevice.EndpointId)) + list.Add((object)string.Format(VideoDetails._deviceRentalFormat, (object)uiDevice.Name.ToUpper())); + } + return list; + } + + public static string PCExpirationToString( + int drmState, + string fileName, + int fileType, + Guid zuneMediaId) + { + string str = ""; + switch (drmState) + { + case 20: + str = ZuneUI.Shell.LoadString(StringId.IDS_VIDEO_EXPIRED); + break; + case 26: + if (!string.IsNullOrEmpty(fileName)) + { + DRMInfo drmInfo = fileType != 43 ? ZuneApplication.Service.GetFileDRMInfo(fileName) : ZuneApplication.Service.GetMediaDRMInfo(zuneMediaId, Microsoft.Zune.Service.EContentType.Video); + if (drmInfo != null) + { + if (drmInfo.ValidLicense && drmInfo.HasExpiryDate) + { + DateTime localTime = DateTime.UtcNow.ToLocalTime(); + if (drmInfo.ExpiryDate.CompareTo(localTime) > 0) + { + TimeSpan timeSpan = drmInfo.ExpiryDate.Subtract(localTime); + str = timeSpan.TotalHours < 49.0 ? (timeSpan.TotalHours < 2.0 ? (timeSpan.TotalHours < 1.0 ? ZuneUI.Shell.LoadString(StringId.IDS_VIDEO_EXPIRATION_MINUTES) : ZuneUI.Shell.LoadString(StringId.IDS_VIDEO_EXPIRATION_ONEHOUR)) : string.Format(VideoDetails._hoursExpirationFormat, (object)(int)timeSpan.TotalHours)) : string.Format(VideoDetails._daysExpirationFormat, (object)timeSpan.Days); + break; + } + str = ZuneUI.Shell.LoadString(StringId.IDS_VIDEO_EXPIRED); + break; + } + if (drmInfo.LicenseExpired) + { + str = ZuneUI.Shell.LoadString(StringId.IDS_VIDEO_EXPIRED); + break; + } + break; + } + break; + } + break; + } + return str; + } + + public static void Populate(object dataContainer, int libraryId) + { + DataProviderObject dataProviderObject = (DataProviderObject)dataContainer; + object[] fieldValues = new object[15] + { + (object) string.Empty, + (object) TimeSpan.Zero, + (object) 0, + (object) 0, + (object) string.Empty, + (object) string.Empty, + (object) string.Empty, + (object) 0, + (object) 0, + (object) string.Empty, + (object) 0L, + (object) string.Empty, + (object) 0, + (object) 0, + (object) Guid.Empty + }; + ZuneLibrary.GetFieldValues(libraryId, EListType.eVideoList, VideoDetails.ColumnIndexes.Length, VideoDetails.ColumnIndexes, fieldValues, PlaylistManager.Instance.QueryContext); + for (int index = 0; index < VideoDetails.ColumnIndexes.Length; ++index) + { + if (VideoDetails.ColumnIndexes[index] == 177) + dataProviderObject.SetProperty("MediaType", (object)MediaDescriptions.Map((MediaType)fieldValues[index])); + dataProviderObject.SetProperty(VideoDetails.DataProperties[index], fieldValues[index]); + } + } + } +} diff --git a/ZuneUI/VideoDrmStateComparer.cs b/ZuneUI/VideoDrmStateComparer.cs new file mode 100644 index 0000000..55f02d4 --- /dev/null +++ b/ZuneUI/VideoDrmStateComparer.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoDrmStateComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class VideoDrmStateComparer : IComparer + { + public int Compare(object x, object y) + { + DataProviderObject dataProviderObject1 = x as DataProviderObject; + DataProviderObject dataProviderObject2 = y as DataProviderObject; + if (dataProviderObject1 == null || dataProviderObject2 == null) + return 1; + int num1 = (int)dataProviderObject1.GetProperty("DrmState"); + int num2 = (int)dataProviderObject2.GetProperty("DrmState"); + if (num1 == 20 || num1 == 23) + num1 = 26; + if (num2 == 20 || num2 == 23) + num2 = 26; + return num1.CompareTo(num2); + } + } +} diff --git a/ZuneUI/VideoLibraryPage.cs b/ZuneUI/VideoLibraryPage.cs new file mode 100644 index 0000000..49658b2 --- /dev/null +++ b/ZuneUI/VideoLibraryPage.cs @@ -0,0 +1,209 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoLibraryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class VideoLibraryPage : LibraryPage + { + private VideosPanel _videosPanel; + private bool _hasSelectedVideo; + private object _selectedVideo; + private IList _selectedVideoIds; + private DataProviderQueryStatus _queryStatus; + + public VideoLibraryPage() + : this(false, VideoLibraryView.Invalid) + { + } + + public VideoLibraryPage(bool showDevice, VideoLibraryView desiredView) + : base(showDevice, MediaType.Video) + { + this.UI = VideoLibraryPage.LibraryTemplate; + this.UIPath = "Collection\\Videos\\Default"; + if (showDevice) + { + this.PivotPreference = Shell.MainFrame.Device.Videos; + Deviceland.InitDevicePage((ZunePage)this); + } + else + this.PivotPreference = Shell.MainFrame.Collection.Videos; + this.IsRootPage = true; + if (!this.ShowDeviceContents) + { + this.Views = (Choice)new NotifyChoice((IModelItemOwner)this); + this.Views.Options = (IList)new VideoLibraryPage.ViewCommand[6] + { + new VideoLibraryPage.ViewCommand((IModelItemOwner) this.Views, Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_ALL_PIVOT), VideoLibraryView.All), + new VideoLibraryPage.ViewCommand((IModelItemOwner) this.Views, Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_TV_PIVOT), VideoLibraryView.TV), + new VideoLibraryPage.ViewCommand((IModelItemOwner) this.Views, Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_MUSIC_PIVOT), VideoLibraryView.Music), + new VideoLibraryPage.ViewCommand((IModelItemOwner) this.Views, Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_MOVIES_PIVOT), VideoLibraryView.Movies), + new VideoLibraryPage.ViewCommand((IModelItemOwner) this.Views, Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_OTHER_PIVOT), VideoLibraryView.Other), + new VideoLibraryPage.ViewCommand((IModelItemOwner) this.Views, Shell.LoadString(StringId.IDS_COLLECTION_VIDEO_PERSONAL_PIVOT), VideoLibraryView.Personal) + }; + int num = -1; + if (desiredView != VideoLibraryView.Invalid) + { + for (int index = 0; index < this.Views.Options.Count; ++index) + { + if (desiredView == ((VideoLibraryPage.ViewCommand)this.Views.Options[index]).View) + { + num = index; + break; + } + } + } + if (num == -1) + num = ClientConfiguration.Shell.VideoCollectionView; + this.Views.ChosenChanged += new EventHandler(this.ViewChanged); + if (num >= 0 && num < this.Views.Options.Count) + this.Views.ChosenIndex = num; + } + this._videosPanel = new VideosPanel(this); + this.ShowPlaylistIcon = false; + this.TransportControlStyle = TransportControlStyle.Video; + this.PlaybackContext = PlaybackContext.LibraryVideo; + } + + private void ViewChanged(object sender, EventArgs e) + { + ClientConfiguration.Shell.VideoCollectionView = this.Views.ChosenIndex; + this.FirePropertyChanged("View"); + this.SelectedVideo = (object)null; + this.SelectedVideoIds = (IList)null; + } + + public VideoLibraryView View + { + get => this.ShowDeviceContents ? VideoLibraryView.All : ((VideoLibraryPage.ViewCommand)this.Views.ChosenValue).View; + private set + { + if (this.ShowDeviceContents) + return; + foreach (VideoLibraryPage.ViewCommand option in (IEnumerable)this.Views.Options) + { + if (option.View == value) + { + this.Views.ChosenValue = (object)option; + break; + } + } + } + } + + public bool HasSelectedVideo + { + get => this._hasSelectedVideo; + set + { + if (this._hasSelectedVideo == value) + return; + this._hasSelectedVideo = value; + this.FirePropertyChanged(nameof(HasSelectedVideo)); + } + } + + public object SelectedVideo + { + get => this._selectedVideo; + set + { + if (this._selectedVideo == value) + return; + this._selectedVideo = value; + this.FirePropertyChanged(nameof(SelectedVideo)); + } + } + + public IList SelectedVideoIds + { + get => this._selectedVideoIds; + set + { + if (this._selectedVideoIds == value) + return; + this._selectedVideoIds = value; + this.FirePropertyChanged(nameof(SelectedVideoIds)); + this.FirePropertyChanged("SelectedVideosCount"); + } + } + + public DataProviderQueryStatus QueryStatus + { + get => this._queryStatus; + set + { + if (this._queryStatus == value) + return; + this._queryStatus = value; + this.FirePropertyChanged(nameof(QueryStatus)); + } + } + + public int SelectedVideosCount => this._selectedVideoIds == null ? 0 : this._selectedVideoIds.Count; + + protected override void OnNavigatedToWorker() + { + if (this.NavigationArguments != null) + { + if (this.NavigationArguments.Contains((object)"ViewOverrideId")) + this.View = (VideoLibraryView)this.NavigationArguments[(object)"ViewOverrideId"]; + this._selectedVideoIds = (IList)null; + if (this.NavigationArguments.Contains((object)"VideoLibraryId")) + this._selectedVideoIds = (IList)new int[1] + { + (int) this.NavigationArguments[(object) "VideoLibraryId"] + }; + this.NavigationArguments = (IDictionary)null; + } + base.OnNavigatedToWorker(); + } + + public VideosPanel VideosPanel => this._videosPanel; + + protected override void OnNavigatedAwayWorker(IPage destination) + { + base.OnNavigatedAwayWorker(destination); + this.SelectedVideo = (object)null; + } + + public override IPageState SaveAndRelease() + { + this._videosPanel.Release(); + return base.SaveAndRelease(); + } + + public static void FindInCollection(int videoId) => ZuneShell.DefaultInstance.Execute("Collection\\Videos\\Default", (IDictionary)new Hashtable() + { + { + (object) "VideoLibraryId", + (object) videoId + }, + { + (object) "ViewOverrideId", + (object) VideoLibraryView.All + } + }); + + private static string LibraryTemplate => "res://ZuneShellResources!VideoLibrary.uix#VideoLibrary"; + + private class ViewCommand : Command + { + private VideoLibraryView _view; + + public ViewCommand(IModelItemOwner owner, string description, VideoLibraryView view) + : base(owner, description, (EventHandler)null) + => this._view = view; + + public VideoLibraryView View => this._view; + } + } +} diff --git a/ZuneUI/VideoLibraryView.cs b/ZuneUI/VideoLibraryView.cs new file mode 100644 index 0000000..24f4f21 --- /dev/null +++ b/ZuneUI/VideoLibraryView.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoLibraryView +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum VideoLibraryView + { + Invalid = -2, // 0xFFFFFFFE + All = -1, // 0xFFFFFFFF + TV = 5, + Music = 7, + Movies = 8, + Other = 10, // 0x0000000A + Personal = 128, // 0x00000080 + } +} diff --git a/ZuneUI/VideoNavigationCommandHandler.cs b/ZuneUI/VideoNavigationCommandHandler.cs new file mode 100644 index 0000000..597212e --- /dev/null +++ b/ZuneUI/VideoNavigationCommandHandler.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoNavigationCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class VideoNavigationCommandHandler : DeviceAwareNavigationHandler + { + private VideoLibraryView _view = VideoLibraryView.Invalid; + + protected override ZunePage GetPage(IDictionary args) => (ZunePage)new VideoLibraryPage(this.ShowDeviceContents, this._view); + + public VideoLibraryView View + { + get => this._view; + set => this._view = value; + } + } +} diff --git a/ZuneUI/VideoPlaybackTrack.cs b/ZuneUI/VideoPlaybackTrack.cs new file mode 100644 index 0000000..0aba5b2 --- /dev/null +++ b/ZuneUI/VideoPlaybackTrack.cs @@ -0,0 +1,106 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoPlaybackTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using ZuneXml; + +namespace ZuneUI +{ + [Serializable] + public class VideoPlaybackTrack : PlaybackTrack + { + private Guid _zuneMediaId; + private Guid _zuneMediaInstanceId; + private string _title; + private string _artist; + private string _uri; + private bool _isDownloading; + private bool _fallbackToPreview; + private bool _forcePreview; + private bool _ignoreCollection; + private bool _isStreaming; + private VideoDefinitionEnum _videoDefinition; + + public VideoPlaybackTrack( + Guid zuneMediaId, + string title, + string artist, + string uri, + bool isDownloading, + bool isStreaming, + bool ignoreCollection, + bool fallbackToPreview, + bool forcePreview, + VideoDefinitionEnum videoDefinition) + { + this._title = title; + this._zuneMediaId = zuneMediaId; + this._artist = artist; + this._uri = uri; + this._isDownloading = isDownloading; + this._isStreaming = isStreaming; + this._ignoreCollection = ignoreCollection; + this._fallbackToPreview = fallbackToPreview; + this._forcePreview = forcePreview; + this._videoDefinition = videoDefinition; + } + + public override Guid ZuneMediaId => this._zuneMediaId; + + public override HRESULT GetURI(out string uri) + { + HRESULT hresult = HRESULT._S_OK; + string uriOut = (string)null; + if (!ZuneApplication.Service.InCompleteCollection(this._zuneMediaId, EContentType.Video) && !string.IsNullOrEmpty(this._uri)) + { + uriOut = this._uri; + } + else + { + EContentUriFlags eContentUriFlags = EContentUriFlags.None; + if (this.IgnoreCollection) + eContentUriFlags |= EContentUriFlags.IgnoreCollection; + if (this.FallbackToPreview) + eContentUriFlags |= EContentUriFlags.FallbackToPreview; + if (this.ForcePreview) + eContentUriFlags |= EContentUriFlags.ForcePreview; + hresult = ZuneApplication.Service.GetContentUri(this._zuneMediaId, EContentType.Video, eContentUriFlags, out uriOut, out this._zuneMediaInstanceId); + } + if (!string.IsNullOrEmpty(uriOut) && uriOut.Contains(".ism/manifest")) + this._isStreaming = true; + uri = uriOut; + return hresult; + } + + public Guid Id => this._zuneMediaId; + + public override Guid ZuneMediaInstanceId => this._zuneMediaInstanceId; + + public override string Title => this._title; + + public string Artist => this._artist; + + public override TimeSpan Duration => TimeSpan.Zero; + + public override bool IsVideo => true; + + public override MediaType MediaType => MediaType.Video; + + public bool IsDownloading => this._isDownloading; + + public bool FallbackToPreview => this._fallbackToPreview; + + public bool ForcePreview => this._forcePreview; + + public bool IgnoreCollection => this._ignoreCollection; + + public override bool IsStreaming => this._isStreaming; + + public override bool IsHD => this._videoDefinition == VideoDefinitionEnum.HD; + } +} diff --git a/ZuneUI/VideoSeasonComparer.cs b/ZuneUI/VideoSeasonComparer.cs new file mode 100644 index 0000000..edb2d8c --- /dev/null +++ b/ZuneUI/VideoSeasonComparer.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoSeasonComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class VideoSeasonComparer : IComparer + { + public int Compare(object x, object y) + { + DataProviderObject dataProviderObject1 = x as DataProviderObject; + DataProviderObject dataProviderObject2 = y as DataProviderObject; + if (dataProviderObject1 == null || dataProviderObject2 == null) + return 1; + int property1 = (int)dataProviderObject1.GetProperty("CategoryId"); + int property2 = (int)dataProviderObject2.GetProperty("CategoryId"); + int num1 = property1.CompareTo(property2); + if (num1 != 0) + return num1; + if (property1 != 5) + return 0; + int num2 = string.Compare((string)dataProviderObject1.GetProperty("SeriesTitle"), (string)dataProviderObject2.GetProperty("SeriesTitle")); + return num2 != 0 ? num2 : ((int)dataProviderObject1.GetProperty("SeasonNumber")).CompareTo((int)dataProviderObject2.GetProperty("SeasonNumber")); + } + } +} diff --git a/ZuneUI/VideoViewCategory.cs b/ZuneUI/VideoViewCategory.cs new file mode 100644 index 0000000..f94c619 --- /dev/null +++ b/ZuneUI/VideoViewCategory.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoViewCategory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class VideoViewCategory + { + private string _view; + private string _category; + + public VideoViewCategory(string view, string category) + { + this._view = view; + this._category = category; + } + + public string View => this._view; + + public string Category => this._category; + } +} diff --git a/ZuneUI/VideoViewCategoryComparer.cs b/ZuneUI/VideoViewCategoryComparer.cs new file mode 100644 index 0000000..353e71f --- /dev/null +++ b/ZuneUI/VideoViewCategoryComparer.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideoViewCategoryComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public class VideoViewCategoryComparer : IComparer + { + public int Compare(object x, object y) + { + VideoViewCategory videoViewCategory1 = x as VideoViewCategory; + VideoViewCategory videoViewCategory2 = y as VideoViewCategory; + if (videoViewCategory1 != null && videoViewCategory2 != null) + { + string view1 = videoViewCategory1.View; + string view2 = videoViewCategory2.View; + if (view1 != null && view2 != null) + return view1.CompareTo(view2); + } + return 1; + } + } +} diff --git a/ZuneUI/VideosPanel.cs b/ZuneUI/VideosPanel.cs new file mode 100644 index 0000000..2978356 --- /dev/null +++ b/ZuneUI/VideosPanel.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.VideosPanel +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneUI +{ + public class VideosPanel : ListPanel + { + internal VideosPanel(VideoLibraryPage library) + : base((IModelItemOwner)library) + { + } + + protected VideoLibraryPage LibraryPage => base.LibraryPage as VideoLibraryPage; + + public override IList SelectedLibraryIds + { + get => this.LibraryPage.SelectedVideoIds; + set => this.LibraryPage.SelectedVideoIds = value; + } + } +} diff --git a/ZuneUI/WebHelpCommand.cs b/ZuneUI/WebHelpCommand.cs new file mode 100644 index 0000000..7eddba8 --- /dev/null +++ b/ZuneUI/WebHelpCommand.cs @@ -0,0 +1,46 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WebHelpCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Runtime.InteropServices; + +namespace ZuneUI +{ + public class WebHelpCommand : Command + { + private const int SW_SHOWNORMAL = 1; + private string _url; + + public string Url + { + get => this._url; + set + { + if (!(this._url != value)) + return; + this._url = value; + this.FirePropertyChanged(nameof(Url)); + } + } + + protected override void OnInvoked() + { + if (this._url != null) + WebHelpCommand.ShellExecute(IntPtr.Zero, "open", this._url, (string)null, (string)null, 1); + base.OnInvoked(); + } + + [DllImport("shell32.dll")] + private static extern IntPtr ShellExecute( + IntPtr hwnd, + string lpOperation, + string lpFile, + string lpParameters, + string lpDirectory, + int nShowCmd); + } +} diff --git a/ZuneUI/WebHostNavigationResult.cs b/ZuneUI/WebHostNavigationResult.cs new file mode 100644 index 0000000..6ca6505 --- /dev/null +++ b/ZuneUI/WebHostNavigationResult.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WebHostNavigationResult +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum WebHostNavigationResult + { + IntermediateUrl, + SuccessUrl, + FailureUrl, + } +} diff --git a/ZuneUI/WebUrlCommandHandler.cs b/ZuneUI/WebUrlCommandHandler.cs new file mode 100644 index 0000000..e9ba814 --- /dev/null +++ b/ZuneUI/WebUrlCommandHandler.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WebUrlCommandHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Collections; + +namespace ZuneUI +{ + public class WebUrlCommandHandler : ICommandHandler + { + public void Execute(string command, IDictionary commandArgs) + { + EPassportPolicyId ePassportPolicy = EPassportPolicyId.None; + if (commandArgs != null && commandArgs.Contains((object)"PassportPolicyId")) + ePassportPolicy = (EPassportPolicyId)commandArgs[(object)"PassportPolicyId"]; + else if (SignIn.Instance.SignedIn) + { + Uri uri = new Uri(command, UriKind.Absolute); + if (uri.Host.EndsWith("zune.net", StringComparison.OrdinalIgnoreCase)) + { + if (uri.Scheme == "http") + ePassportPolicy = EPassportPolicyId.MBI; + else if (uri.Scheme == "https") + ePassportPolicy = EPassportPolicyId.MBI_SSL; + } + } + ZuneApplication.Service.LaunchBrowserForExternalUrl(command, ePassportPolicy); + } + } +} diff --git a/ZuneUI/Win32InternetConnection.cs b/ZuneUI/Win32InternetConnection.cs new file mode 100644 index 0000000..4fde669 --- /dev/null +++ b/ZuneUI/Win32InternetConnection.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Win32InternetConnection +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.InteropServices; + +namespace ZuneUI +{ + internal class Win32InternetConnection + { + [DllImport("wininet.dll", SetLastError = true)] + private static extern bool InternetGetConnectedState( + out Win32InternetConnection.InternetGetConnectedStateFlags Description, + int ReservedValue); + + public static bool IsConnected => Win32InternetConnection.InternetGetConnectedState(out Win32InternetConnection.InternetGetConnectedStateFlags _, 0); + + [Flags] + private enum InternetGetConnectedStateFlags + { + INTERNET_CONNECTION_MODEM = 1, + INTERNET_CONNECTION_LAN = 2, + INTERNET_CONNECTION_PROXY = 4, + INTERNET_CONNECTION_RAS_INSTALLED = 16, // 0x00000010 + INTERNET_CONNECTION_OFFLINE = 32, // 0x00000020 + INTERNET_CONNECTION_CONFIGURED = 64, // 0x00000040 + } + } +} diff --git a/ZuneUI/Win32MessageBox.cs b/ZuneUI/Win32MessageBox.cs new file mode 100644 index 0000000..6ce7f6b --- /dev/null +++ b/ZuneUI/Win32MessageBox.cs @@ -0,0 +1,39 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Win32MessageBox +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Runtime.InteropServices; +using System.Threading; + +namespace ZuneUI +{ + public static class Win32MessageBox + { + public static void Show( + string text, + string caption, + Win32MessageBoxType type, + DeferredInvokeHandler callback) + { + IntPtr winHandle = Application.Window.Handle; + new Thread((ParameterizedThreadStart)(args => + { + int num = Win32MessageBox.MessageBox(winHandle, text, caption, type); + if (callback == null) + return; + Application.DeferredInvoke(callback, (object)num); + })).Start(); + } + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern int MessageBox( + IntPtr hWnd, + string text, + string caption, + Win32MessageBoxType type); + } +} diff --git a/ZuneUI/Win32MessageBoxReturnValue.cs b/ZuneUI/Win32MessageBoxReturnValue.cs new file mode 100644 index 0000000..7929dfd --- /dev/null +++ b/ZuneUI/Win32MessageBoxReturnValue.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Win32MessageBoxReturnValue +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum Win32MessageBoxReturnValue + { + OK = 1, + CANCEL = 2, + ABORT = 3, + RETRY = 4, + IGNORE = 5, + YES = 6, + NO = 7, + } +} diff --git a/ZuneUI/Win32MessageBoxType.cs b/ZuneUI/Win32MessageBoxType.cs new file mode 100644 index 0000000..e99b502 --- /dev/null +++ b/ZuneUI/Win32MessageBoxType.cs @@ -0,0 +1,44 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Win32MessageBoxType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum Win32MessageBoxType + { + MB_APPLMODAL = 0, + MB_OK = 0, + MB_OKCANCEL = 1, + MB_ABORTRETRYIGNORE = 2, + MB_YESNOCANCEL = 3, + MB_YESNO = 4, + MB_RETRYCANCEL = 5, + MB_CANCELTRYCONTINUE = 6, + MB_TYPEMASK = 15, // 0x0000000F + MB_ICONERROR = 16, // 0x00000010 + MB_ICONHAND = 16, // 0x00000010 + MB_ICONSTOP = 16, // 0x00000010 + MB_ICONQUESTION = 32, // 0x00000020 + MB_ICONEXCLAMATION = 48, // 0x00000030 + MB_ICONWARNING = 48, // 0x00000030 + MB_ICONASTERISK = 64, // 0x00000040 + MB_ICONINFORMATION = 64, // 0x00000040 + MB_USERICON = 128, // 0x00000080 + MB_ICONMASK = 240, // 0x000000F0 + MB_DEFMASK = 3840, // 0x00000F00 + MB_SYSTEMMODAL = 4096, // 0x00001000 + MB_TASKMODAL = 8192, // 0x00002000 + MB_MODEMASK = 12288, // 0x00003000 + MB_HELP = 16384, // 0x00004000 + MB_NOFOCUS = 32768, // 0x00008000 + MB_MISCMASK = 49152, // 0x0000C000 + MB_SETFOREGROUND = 65536, // 0x00010000 + MB_DEFAULT_DESKTOP_ONLY = 131072, // 0x00020000 + MB_TOPMOST = 262144, // 0x00040000 + MB_RIGHT = 524288, // 0x00080000 + MB_RTLREADING = 1048576, // 0x00100000 + MB_SERVICE_NOTIFICATION = 2097152, // 0x00200000 + } +} diff --git a/ZuneUI/Win32Window.cs b/ZuneUI/Win32Window.cs new file mode 100644 index 0000000..6da0708 --- /dev/null +++ b/ZuneUI/Win32Window.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Win32Window +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Runtime.InteropServices; + +namespace ZuneUI +{ + public static class Win32Window + { + public static void Close(IntPtr hWnd) => Win32Window.PostMessage(hWnd, 16, 0, false); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern bool PostMessage(IntPtr hWnd, int msg, int wParam, bool lParam); + } +} diff --git a/ZuneUI/Win7LibrariesUsage.cs b/ZuneUI/Win7LibrariesUsage.cs new file mode 100644 index 0000000..2f8a95c --- /dev/null +++ b/ZuneUI/Win7LibrariesUsage.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Win7LibrariesUsage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal enum Win7LibrariesUsage + { + DoNotIntegrate = -1, // 0xFFFFFFFF + BeginIntegration = 0, + Integrated = 1, + } +} diff --git a/ZuneUI/WindowSnapSimulator.cs b/ZuneUI/WindowSnapSimulator.cs new file mode 100644 index 0000000..25e3c5d --- /dev/null +++ b/ZuneUI/WindowSnapSimulator.cs @@ -0,0 +1,582 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WindowSnapSimulator +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace ZuneUI +{ + public class WindowSnapSimulator : SingletonModelItem + { + private const float c_hotspotPercentage = 0.015f; + private Window _window; + private bool _isInitialized; + private List _monitors; + private WindowSnapSimulator.IHotspot _currentHotspot; + private bool _isSnapping; + + public void Phase3Init() => this.Initialize(); + + private void Initialize() + { + if (this.IsInitialized) + return; + this.InitializeMonitors(); + this._window = Application.Window; + this._window.PropertyChanged += new PropertyChangedEventHandler(this.OnWindowPropertyChanged); + Win7ShellManager.Instance.OnMonitorChange += new MonitorChangeHandler(this.OnMonitorChangeDetected); + if (OSVersion.IsWin7()) + Win7ShellManager.Instance.OnWindowPositionKeyPress += new WindowPositionKeyPressHandler(this.OnWin7KeypressDetected); + Shell defaultInstance = (Shell)ZuneShell.DefaultInstance; + if (defaultInstance.NormalWindowSize == null) + defaultInstance.NormalWindowSize = new Size(this._window.ClientSize.Width, this._window.ClientSize.Height); + if (defaultInstance.NormalWindowPosition == null) + defaultInstance.NormalWindowPosition = new Point(this._window.Position.X, this._window.Position.Y); + this.IsInitialized = true; + this.UpdateIsSnapping(); + } + + private void InitializeMonitors() + { + this._monitors = new List(); + foreach (MonitorSize detectMonitor in new MonitorDetector().DetectMonitors()) + { + WindowSnapSimulator.Monitor monitor = new WindowSnapSimulator.Monitor(detectMonitor); + int width = Math.Max((monitor.Right - monitor.Left + 1) / 2, Shell.MinimumWindowWidth); + int height = Math.Max(monitor.Bottom - monitor.Top + 1, Shell.MinimumWindowHeight); + monitor.LeftSnap.Position = new WindowPosition(monitor.Left, monitor.Top); + monitor.LeftSnap.Size = new WindowSize(width, height); + monitor.RightSnap.Position = new WindowPosition(monitor.Right - width, monitor.Top); + monitor.RightSnap.Size = new WindowSize(width, height); + this._monitors.Add(monitor); + } + this._monitors.Sort(); + foreach (WindowSnapSimulator.Monitor monitor in this._monitors) + monitor.InitializeHotspots(this._monitors, 0.015f); + } + + public bool IsSnapping + { + get => this._isSnapping; + private set + { + if (this._isSnapping == value) + return; + this._isSnapping = value; + this.FirePropertyChanged(nameof(IsSnapping)); + } + } + + private bool IsInitialized + { + get => this._isInitialized; + set => this._isInitialized = value; + } + + public void ShiftUp() + { + if (!this.IsInitialized || this._window.WindowState != WindowState.Normal) + return; + if (this.IsSnapping) + this.Unsnap(this.GetWindowMonitor()); + this._window.WindowState = WindowState.Maximized; + } + + public void ShiftDown() + { + if (!this.IsInitialized) + return; + switch (this._window.WindowState) + { + case WindowState.Normal: + if (this.IsSnapping) + { + this.Unsnap(); + break; + } + this._window.WindowState = WindowState.Minimized; + break; + case WindowState.Maximized: + this._window.WindowState = WindowState.Normal; + break; + } + } + + public void ShiftLeft() + { + if (!this.IsInitialized) + return; + if (this._window.WindowState == WindowState.Maximized) + this._window.WindowState = WindowState.Normal; + WindowSnapSimulator.Monitor windowMonitor = this.GetWindowMonitor(); + switch (this.GetWindowSnappedness(windowMonitor)) + { + case WindowSnapSimulator.WindowSnappedness.Unsnapped: + this.Snap(windowMonitor.LeftSnap); + break; + case WindowSnapSimulator.WindowSnappedness.Left: + this.Snap(this.FindPreviousMonitor(windowMonitor).RightSnap); + break; + case WindowSnapSimulator.WindowSnappedness.Right: + this.Unsnap(windowMonitor); + break; + } + } + + public void ShiftRight() + { + if (!this.IsInitialized) + return; + if (this._window.WindowState == WindowState.Maximized) + this._window.WindowState = WindowState.Normal; + WindowSnapSimulator.Monitor windowMonitor = this.GetWindowMonitor(); + switch (this.GetWindowSnappedness(windowMonitor)) + { + case WindowSnapSimulator.WindowSnappedness.Unsnapped: + this.Snap(windowMonitor.RightSnap); + break; + case WindowSnapSimulator.WindowSnappedness.Left: + this.Unsnap(windowMonitor); + break; + case WindowSnapSimulator.WindowSnappedness.Right: + this.Snap(this.FindNextMonitor(windowMonitor).LeftSnap); + break; + } + } + + public void ShiftMonitorLeft() + { + if (!this.IsInitialized) + return; + WindowSnapSimulator.Monitor windowMonitor = this.GetWindowMonitor(); + WindowSnapSimulator.WindowSnappedness windowSnappedness = this.GetWindowSnappedness(windowMonitor); + WindowSnapSimulator.Monitor destinationMonitor = (WindowSnapSimulator.Monitor)null; + if (!OSVersion.IsWin7()) + destinationMonitor = this.FindPreviousMonitor(windowMonitor); + switch (windowSnappedness) + { + case WindowSnapSimulator.WindowSnappedness.Unsnapped: + if (OSVersion.IsWin7()) + break; + this.MoveWindowToMonitor(windowMonitor, this._window.Position, destinationMonitor); + break; + case WindowSnapSimulator.WindowSnappedness.Left: + if (OSVersion.IsWin7()) + { + this.Snap(windowMonitor.LeftSnap); + break; + } + this.Snap(destinationMonitor.LeftSnap); + break; + case WindowSnapSimulator.WindowSnappedness.Right: + if (OSVersion.IsWin7()) + { + this.Snap(windowMonitor.RightSnap); + break; + } + this.Snap(destinationMonitor.RightSnap); + break; + } + } + + public void ShiftMonitorRight() + { + if (!this.IsInitialized) + return; + WindowSnapSimulator.Monitor windowMonitor = this.GetWindowMonitor(); + WindowSnapSimulator.WindowSnappedness windowSnappedness = this.GetWindowSnappedness(windowMonitor); + WindowSnapSimulator.Monitor destinationMonitor = (WindowSnapSimulator.Monitor)null; + if (!OSVersion.IsWin7()) + destinationMonitor = this.FindNextMonitor(windowMonitor); + switch (windowSnappedness) + { + case WindowSnapSimulator.WindowSnappedness.Unsnapped: + if (OSVersion.IsWin7()) + break; + this.MoveWindowToMonitor(windowMonitor, this._window.Position, destinationMonitor); + break; + case WindowSnapSimulator.WindowSnappedness.Left: + if (OSVersion.IsWin7()) + { + this.Snap(windowMonitor.LeftSnap); + break; + } + this.Snap(destinationMonitor.LeftSnap); + break; + case WindowSnapSimulator.WindowSnappedness.Right: + if (OSVersion.IsWin7()) + { + this.Snap(windowMonitor.RightSnap); + break; + } + this.Snap(destinationMonitor.RightSnap); + break; + } + } + + public void Unsnap() + { + if (!this.IsSnapping || !this.IsInitialized) + return; + this.Unsnap(this.GetWindowMonitor()); + } + + public void DragBegun() + { + if (this.IsInitialized) + { + int x = 0; + int y = 0; + MousePosition.GetCursorScreenPosition(out x, out y); + this._currentHotspot = this.GetWindowMonitor(x, y).GetHotspotForCursor(x, y); + } + else + this._currentHotspot = (WindowSnapSimulator.IHotspot)null; + } + + public bool ReactToDrag() + { + WindowSnapSimulator.IHotspot hotspot = (WindowSnapSimulator.IHotspot)null; + if (this.IsInitialized) + { + int x = 0; + int y = 0; + MousePosition.GetCursorScreenPosition(out x, out y); + hotspot = this.GetWindowMonitor(x, y).GetHotspotForCursor(x, y); + if (hotspot != this._currentHotspot) + { + if (this.IsSnapping) + this.Unsnap(); + if (this._window.WindowState == WindowState.Maximized) + this._window.WindowState = WindowState.Normal; + this._currentHotspot = hotspot; + hotspot?.Snap(); + } + } + return hotspot != null; + } + + public void DragEnded() => this._currentHotspot = (WindowSnapSimulator.IHotspot)null; + + public void SetWindowPosition(int left, int top, int width, int height) + { + this.Initialize(); + WindowSnapSimulator.Monitor windowMonitor = this.GetWindowMonitor(left + width / 2, top + height / 2); + if (windowMonitor != null) + { + if (width > windowMonitor.Right - windowMonitor.Left) + width = windowMonitor.Right - windowMonitor.Left; + if (height > windowMonitor.Bottom - windowMonitor.Top) + height = windowMonitor.Bottom - windowMonitor.Top; + if (left < windowMonitor.Left) + left = windowMonitor.Left; + else if (left + width > windowMonitor.Right) + left = windowMonitor.Right - width; + if (top < windowMonitor.Top) + top = windowMonitor.Top; + else if (top + height > windowMonitor.Bottom) + top = windowMonitor.Bottom - height; + } + this._window.Position = new WindowPosition(left, top); + this._window.ClientSize = new WindowSize(width, height); + } + + private void Snap(WindowSnapSimulator.WindowPlacement placement) + { + if (!this.IsInitialized) + return; + this._window.Position = placement.Position; + this._window.ClientSize = placement.Size; + } + + private void Unsnap(WindowSnapSimulator.Monitor monitor) + { + if (!this.IsSnapping || !this.IsInitialized) + return; + Shell defaultInstance = (Shell)ZuneShell.DefaultInstance; + WindowPosition windowPosition = new WindowPosition(defaultInstance.NormalWindowPosition.X, defaultInstance.NormalWindowPosition.Y); + WindowSize size = new WindowSize(defaultInstance.NormalWindowSize.Width, defaultInstance.NormalWindowSize.Height); + WindowSnapSimulator.Monitor windowMonitor = this.GetWindowMonitor(windowPosition, size); + if (monitor == windowMonitor) + this._window.Position = windowPosition; + else + this.MoveWindowToMonitor(windowMonitor, windowPosition, monitor); + this._window.ClientSize = size; + } + + private void MoveWindowToMonitor( + WindowSnapSimulator.Monitor currentMonitor, + WindowPosition currentPosition, + WindowSnapSimulator.Monitor destinationMonitor) + { + int num1 = destinationMonitor.Left - currentMonitor.Left; + int num2 = destinationMonitor.Top - currentMonitor.Top; + this._window.Position = new WindowPosition(currentPosition.X + num1, currentPosition.Y + num2); + } + + private WindowSnapSimulator.Monitor FindNextMonitor( + WindowSnapSimulator.Monitor monitor) + { + int index = this._monitors.IndexOf(monitor) + 1; + if (index >= this._monitors.Count) + index = 0; + return this._monitors[index]; + } + + private WindowSnapSimulator.Monitor FindPreviousMonitor( + WindowSnapSimulator.Monitor monitor) + { + int index = this._monitors.IndexOf(monitor) - 1; + if (index < 0) + index = this._monitors.Count - 1; + return this._monitors[index]; + } + + private WindowSnapSimulator.WindowSnappedness GetWindowSnappedness( + WindowSnapSimulator.Monitor monitor) + { + WindowSnapSimulator.WindowSnappedness windowSnappedness = WindowSnapSimulator.WindowSnappedness.Ineligible; + if (this.IsInitialized && this._window.WindowState != WindowState.Maximized && this._window.WindowState != WindowState.Minimized) + windowSnappedness = !(this._window.Position == monitor.LeftSnap.Position) || !(this._window.ClientSize == monitor.LeftSnap.Size) ? (!(this._window.Position == monitor.RightSnap.Position) || !(this._window.ClientSize == monitor.RightSnap.Size) ? WindowSnapSimulator.WindowSnappedness.Unsnapped : WindowSnapSimulator.WindowSnappedness.Right) : WindowSnapSimulator.WindowSnappedness.Left; + return windowSnappedness; + } + + private WindowSnapSimulator.Monitor GetWindowMonitor() => this.GetWindowMonitor(this._window.Position, this._window.ClientSize); + + private WindowSnapSimulator.Monitor GetWindowMonitor( + WindowSnapSimulator.WindowPlacement placement) + { + return this.GetWindowMonitor(placement.Position, placement.Size); + } + + private WindowSnapSimulator.Monitor GetWindowMonitor( + WindowPosition position, + WindowSize size) + { + return this.GetWindowMonitor(position.X + size.Width / 2, position.Y + size.Height / 2); + } + + private WindowSnapSimulator.Monitor GetWindowMonitor(int x, int y) + { + WindowSnapSimulator.Monitor monitor1 = (WindowSnapSimulator.Monitor)null; + if (this.IsInitialized) + { + if (this._monitors.Count > 1) + { + int num1 = int.MaxValue; + foreach (WindowSnapSimulator.Monitor monitor2 in this._monitors) + { + int num2 = 0; + int num3 = 0; + if (x < monitor2.Left) + num2 = monitor2.Left - x; + else if (x > monitor2.Right) + num2 = x - monitor2.Right; + if (y < monitor2.Top) + num3 = monitor2.Top - y; + else if (y > monitor2.Bottom) + num3 = y - monitor2.Bottom; + int num4 = num2 + num3; + if (num4 < num1) + { + monitor1 = monitor2; + num1 = num4; + } + } + } + else + monitor1 = this._monitors[0]; + } + return monitor1; + } + + private void UpdateIsSnapping() + { + bool flag = false; + if (this._window.WindowState == WindowState.Normal) + { + switch (this.GetWindowSnappedness(this.GetWindowMonitor())) + { + case WindowSnapSimulator.WindowSnappedness.Left: + case WindowSnapSimulator.WindowSnappedness.Right: + flag = true; + break; + } + } + this.IsSnapping = flag; + } + + private void OnWindowPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (!(args.PropertyName == "Position") && !(args.PropertyName == "ClientSize") && !(args.PropertyName == "WindowState")) + return; + this.UpdateIsSnapping(); + } + + private void OnWin7KeypressDetected(WindowPositionKeys key) => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + switch (key) + { + case WindowPositionKeys.eWindowPositionKeyLeft: + this.ShiftLeft(); + break; + case WindowPositionKeys.eWindowPositionKeyRight: + this.ShiftRight(); + break; + case WindowPositionKeys.eWindowPositionKeyDown: + if (this._window.WindowState != WindowState.Maximized) + break; + this.ShiftDown(); + break; + case WindowPositionKeys.eWindowPositionKeyShiftLeft: + this.ShiftMonitorLeft(); + break; + case WindowPositionKeys.eWindowPositionKeyShiftRight: + this.ShiftMonitorRight(); + break; + } + }, (object)null); + + private void OnMonitorChangeDetected() => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.Unsnap(); + this.InitializeMonitors(); + }, (object)null); + + private enum WindowSnappedness + { + Unsnapped, + Left, + Right, + Ineligible, + } + + private class WindowPlacement + { + private WindowPosition _position; + private WindowSize _size; + + public WindowPosition Position + { + get => this._position; + set => this._position = value; + } + + public WindowSize Size + { + get => this._size; + set => this._size = value; + } + } + + private class Monitor : IComparable + { + private MonitorSize _dimensions; + private WindowSnapSimulator.WindowPlacement _leftSnap; + private WindowSnapSimulator.WindowPlacement _rightSnap; + private int _hotspotSize; + private WindowSnapSimulator.IHotspot _topHotspot; + private WindowSnapSimulator.IHotspot _leftHotspot; + private WindowSnapSimulator.IHotspot _rightHotspot; + + public Monitor(MonitorSize dimensions) + { + this._dimensions = dimensions; + this.LeftSnap = new WindowSnapSimulator.WindowPlacement(); + this.RightSnap = new WindowSnapSimulator.WindowPlacement(); + } + + public int Left => this._dimensions.WorkArea.Left; + + public int Right => this._dimensions.WorkArea.Right; + + public int Top => this._dimensions.WorkArea.Top; + + public int Bottom => this._dimensions.WorkArea.Bottom; + + public WindowSnapSimulator.WindowPlacement LeftSnap + { + get => this._leftSnap; + private set => this._leftSnap = value; + } + + public WindowSnapSimulator.WindowPlacement RightSnap + { + get => this._rightSnap; + private set => this._rightSnap = value; + } + + public void InitializeHotspots( + List monitorList, + float hotspotSizePercentage) + { + this._hotspotSize = (int)((double)((this.Right - this.Left + 1 + (this.Bottom - this.Top + 1)) / 2) * (double)hotspotSizePercentage); + bool flag1 = true; + bool flag2 = true; + bool flag3 = true; + foreach (WindowSnapSimulator.Monitor monitor in monitorList) + { + RECT totalArea = monitor._dimensions.TotalArea; + if (totalArea.Top + 1 == this.Top) + flag1 = false; + if (totalArea.Right + 1 == this.Left) + flag2 = false; + if (totalArea.Left - 1 == this.Right) + flag3 = false; + } + if (flag1) + this._topHotspot = (WindowSnapSimulator.IHotspot)new WindowSnapSimulator.MaximizeHotspot(); + if (flag2) + this._leftHotspot = (WindowSnapSimulator.IHotspot)new WindowSnapSimulator.PlacementHotspot(this.LeftSnap); + if (!flag3) + return; + this._rightHotspot = (WindowSnapSimulator.IHotspot)new WindowSnapSimulator.PlacementHotspot(this.RightSnap); + } + + public WindowSnapSimulator.IHotspot GetHotspotForCursor( + int cursorX, + int cursorY) + { + WindowSnapSimulator.IHotspot hotspot = (WindowSnapSimulator.IHotspot)null; + if (cursorY <= this.Top + this._hotspotSize && this._topHotspot != null) + hotspot = this._topHotspot; + else if (cursorX <= this.Left + this._hotspotSize) + hotspot = this._leftHotspot; + else if (cursorX >= this.Right - this._hotspotSize) + hotspot = this._rightHotspot; + return hotspot; + } + + public int CompareTo(WindowSnapSimulator.Monitor other) + { + int num = this.Top.CompareTo(other.Top); + return num == 0 ? this.Left.CompareTo(other.Left) : num; + } + } + + private interface IHotspot + { + void Snap(); + } + + private class MaximizeHotspot : WindowSnapSimulator.IHotspot + { + public void Snap() => SingletonModelItem.Instance.ShiftUp(); + } + + private class PlacementHotspot : WindowSnapSimulator.IHotspot + { + private WindowSnapSimulator.WindowPlacement _placement; + + public PlacementHotspot(WindowSnapSimulator.WindowPlacement placement) => this._placement = placement; + + public void Snap() => SingletonModelItem.Instance.Snap(this._placement); + } + } +} diff --git a/ZuneUI/WirelessNetworkTypeCommand.cs b/ZuneUI/WirelessNetworkTypeCommand.cs new file mode 100644 index 0000000..2d3ff91 --- /dev/null +++ b/ZuneUI/WirelessNetworkTypeCommand.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessNetworkTypeCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; + +namespace ZuneUI +{ + public class WirelessNetworkTypeCommand : Command + { + private WlanAuthCipherPair _networkType; + + public WirelessNetworkTypeCommand( + IModelItemOwner owner, + string description, + EventHandler handler, + WlanAuthCipherPair pair) + : base(owner, description, handler) + { + this._networkType = pair; + } + + public WlanAuthCipherPair NetworkType => this._networkType; + } +} diff --git a/ZuneUI/WirelessStateResults.cs b/ZuneUI/WirelessStateResults.cs new file mode 100644 index 0000000..ecf1fd5 --- /dev/null +++ b/ZuneUI/WirelessStateResults.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessStateResults +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public enum WirelessStateResults + { + Success, + Error, + Finished, + NotAvailable, + Canceled, + } +} diff --git a/ZuneUI/WirelessStates.cs b/ZuneUI/WirelessStates.cs new file mode 100644 index 0000000..8a6dce3 --- /dev/null +++ b/ZuneUI/WirelessStates.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessStates +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + internal enum WirelessStates + { + CommitProfileToDevice, + TestDeviceProfile, + GetDeviceProfiles, + SniffNetworks, + GetComputerProfiles, + AssociateWlanDevice, + UnassociateWlanDevice, + UnassociateNetwork, + } +} diff --git a/ZuneUI/WirelessSync.cs b/ZuneUI/WirelessSync.cs new file mode 100644 index 0000000..a4970c5 --- /dev/null +++ b/ZuneUI/WirelessSync.cs @@ -0,0 +1,527 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessSync +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; +using UIXControls; + +namespace ZuneUI +{ + public class WirelessSync : ModelItem + { + private const int NS_E_INVALID_TRANSCODE_CACHE_SIZE = -1072876833; + private const uint NS_E_WLAN_PROFILE_START = 3222082080; + private const uint NS_E_WLAN_PROFILE_END = 3222082085; + private static WirelessSync _singletonInstance; + private Choice _existingNetworkChoice; + private Choice wirelessNetworkTypesChoice; + private AOSetProfile wirelessSetProfileHelper = new AOSetProfile(); + private AOGetNetworkList wirelessGetNetworkListHelper = new AOGetNetworkList(); + private AOGetConnectedNetwork wirelessGetConnectedNetworkHelper = new AOGetConnectedNetwork(); + private AOClearWirelessSettings wirelessClearHelper = new AOClearWirelessSettings(); + private AOGetDeviceProfile wirelessDeviceProfileHelper = new AOGetDeviceProfile(); + private string wirelessDeviceErrorDescription; + private string wirelessDeviceErrorCaption; + private HRESULT wirelessDeviceErrorCode = HRESULT._S_OK; + private bool wirelessDeviceCanceled; + private Category wirelessBlockedPage; + private WlanProfile wirelessDeviceProfile; + private WlanProfile wirelessConnectedProfile; + private WlanProfile wirelessProfileToSave; + private ArrayListDataSet wirelessNetworksList; + private HRESULT wirelessGetConnectedProfileResult = HRESULT._S_OK; + private HRESULT _profileSavedResult = HRESULT._E_PENDING; + private static readonly WirelessType[] wirelessRadioGroupItems = new WirelessType[11] + { + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.Open, WirelessCiphers.None), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_NO_ENCRYPTION), true, true, true), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.Open, WirelessCiphers.WEP), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WEP_OPEN), true, false, true), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.Open, WirelessCiphers.WEP40), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WEP_OPEN), false, false, true), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.Open, WirelessCiphers.WEP104), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WEP_OPEN), false, false, true), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.Shared, WirelessCiphers.WEP), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WEP_SHARED), true, false, false), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.Shared, WirelessCiphers.WEP40), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WEP_SHARED), false, false, true), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.Shared, WirelessCiphers.WEP104), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WEP_SHARED), false, false, true), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.WPAPSK, WirelessCiphers.AES), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WPA_AES), true, false, true), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.WPAPSK, WirelessCiphers.TKIP), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WPA_TKIP), true, false, false), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.WPA2PSK, WirelessCiphers.AES), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WPA2_AES), true, false, true), + new WirelessType(new WlanAuthCipherPair(WirelessAuthenticationTypes.WPA2PSK, WirelessCiphers.TKIP), Shell.LoadString(StringId.IDS_WIRELESS_NETWORK_WPA2_TKIP), true, false, false) + }; + + public static WirelessSync Instance + { + get + { + if (WirelessSync._singletonInstance == null) + WirelessSync._singletonInstance = new WirelessSync(); + return WirelessSync._singletonInstance; + } + set + { + if (WirelessSync._singletonInstance == value) + return; + WirelessSync._singletonInstance = value; + } + } + + private UIDevice ActiveDevice => SyncControls.Instance.CurrentDeviceOverride; + + private WirelessSync() + : base((IModelItemOwner)ZuneShell.DefaultInstance.Management.DeviceManagement) + { + } + + public Choice ExistingNetworkChoice + { + get + { + if (this._existingNetworkChoice == null) + { + this._existingNetworkChoice = new Choice((IModelItemOwner)this); + this._existingNetworkChoice.Options = (IList)new Command[2] + { + new Command((IModelItemOwner) this, Shell.LoadString(StringId.IDS_WIRELESS_USE_CONNECTED_YES), (EventHandler) null), + new Command((IModelItemOwner) this, Shell.LoadString(StringId.IDS_WIRELESS_USE_CONNECTED_NO), (EventHandler) null) + }; + this._existingNetworkChoice.ChosenChanged += (EventHandler)((sender, args) => this.FirePropertyChanged(nameof(ExistingNetworkChoice))); + } + return this._existingNetworkChoice; + } + } + + public WlanProfile WirelessDeviceProfile + { + get + { + if (this.wirelessDeviceProfile == null) + { + this.wirelessDeviceProfile = new WlanProfile(); + this.wirelessDeviceProfile.SSID = string.Empty; + this.wirelessDeviceProfile.Key = string.Empty; + this.wirelessDeviceProfile.Auth = WirelessAuthenticationTypes.Open; + this.wirelessDeviceProfile.Cipher = WirelessCiphers.None; + } + return this.wirelessDeviceProfile; + } + private set + { + this.wirelessDeviceProfile = value; + this.FirePropertyChanged(nameof(WirelessDeviceProfile)); + } + } + + public string GetWirelessDeviceNetworkType() + { + WlanProfile wirelessDeviceProfile = this.WirelessDeviceProfile; + string str = Shell.LoadString(StringId.IDS_TYPE_UNKNOWN); + foreach (WirelessType wirelessRadioGroupItem in WirelessSync.wirelessRadioGroupItems) + { + if (wirelessDeviceProfile.Auth == wirelessRadioGroupItem.Type.Auth && wirelessDeviceProfile.Cipher == wirelessRadioGroupItem.Type.Cipher) + str = wirelessRadioGroupItem.Description; + } + return str; + } + + public int GetNetworkTypeIndex(WirelessAuthenticationTypes auth, WirelessCiphers cipher) + { + int num = 0; + if (this.wirelessNetworkTypesChoice != null && this.wirelessNetworkTypesChoice.Options != null) + { + for (int index = 0; index < this.wirelessNetworkTypesChoice.Options.Count; ++index) + { + WirelessNetworkTypeCommand option = this.wirelessNetworkTypesChoice.Options[index] as WirelessNetworkTypeCommand; + WlanAuthCipherPair wlanAuthCipherPair = (WlanAuthCipherPair)null; + if (option != null) + wlanAuthCipherPair = option.NetworkType; + if (wlanAuthCipherPair != null && wlanAuthCipherPair.Auth == auth && (wlanAuthCipherPair.Cipher == cipher || this.IsWEP(wlanAuthCipherPair.Cipher) && this.IsWEP(cipher))) + { + num = index; + break; + } + } + } + return num; + } + + public WirelessStateResults RequestWirelessNetworksList() + { + this.wirelessDeviceErrorDescription = (string)null; + this.wirelessDeviceErrorCaption = Shell.LoadString(StringId.IDS_WIRELESS_SNIFF_FAILED); + this.wirelessDeviceErrorCode = HRESULT._S_OK; + WirelessStateResults result = this.wirelessGetNetworkListHelper.StartOperation(this.ActiveDevice, new AsyncOperation.AOComplete(this.GetNetworkListDone)); + this.WirelessHandleDeviceBusy(result); + return result; + } + + public ArrayListDataSet WirelessNetworksList + { + get + { + if (this.wirelessNetworksList == null) + this.wirelessNetworksList = new ArrayListDataSet(); + return this.wirelessNetworksList; + } + private set + { + if (value == this.wirelessNetworksList) + return; + this.wirelessNetworksList = value; + this.FirePropertyChanged(nameof(WirelessNetworksList)); + } + } + + public void GetNetworkListDone(bool success) + { + if (this.WirelessUnblockPage()) + return; + WlanProfileList networkList = this.wirelessGetNetworkListHelper.NetworkList; + ArrayListDataSet arrayListDataSet = new ArrayListDataSet(); + if (success && networkList != null) + { + foreach (WlanProfile profile in (List)networkList) + arrayListDataSet.Add((object)new WlanCommand(profile)); + } + if (!success) + { + if (string.IsNullOrEmpty(this.wirelessDeviceErrorDescription)) + this.wirelessDeviceErrorDescription = this.wirelessGetNetworkListHelper.Error; + if (this.wirelessDeviceErrorCode == HRESULT._S_OK) + this.wirelessDeviceErrorCode = this.wirelessGetNetworkListHelper.Hr; + } + this.WirelessNetworksList = arrayListDataSet; + } + + public bool SetConnectedNetwork() => this.SetWirelessSettings(this.wirelessConnectedProfile); + + public WirelessStateResults SetWirelessSettings() + { + WirelessStateResults result = WirelessStateResults.Error; + WlanProfile wirelessProfileToSave = this.wirelessProfileToSave; + this.wirelessDeviceErrorDescription = (string)null; + this.wirelessDeviceErrorCaption = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_POST_SETUP_FAILED); + this.wirelessDeviceErrorCode = HRESULT._S_OK; + this.wirelessDeviceCanceled = false; + if (wirelessProfileToSave != null) + { + result = this.wirelessSetProfileHelper.StartOperation(this.ActiveDevice, new AsyncOperation.AOComplete(this.SetProfileDone), wirelessProfileToSave); + this.WirelessHandleDeviceBusy(result); + } + if (result != WirelessStateResults.Success) + this.wirelessDeviceErrorDescription = wirelessProfileToSave == null ? Shell.LoadString(StringId.IDS_WIRELESS_SYNC_SETUP_FAILED_GENERIC) : string.Format(Shell.LoadString(StringId.IDS_WIRELESS_SYNC_SETUP_FAILED), (object)wirelessProfileToSave.SSID); + return result; + } + + public bool SetWirelessSettings(object selected) + { + if (selected is WlanCommand wlanCommand) + return this.SetWirelessSettings(wlanCommand.Profile); + this.wirelessDeviceErrorDescription = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_SETUP_FAILED_GENERIC); + return false; + } + + public WlanCommand CreateWlanCommand(string name, object networkType, string key) + { + WlanProfile wlanProfile = this.CreateWlanProfile(name, networkType, key); + return wlanProfile != null ? new WlanCommand(wlanProfile) : (WlanCommand)null; + } + + public void ClearWirelessOnDevice() => this.RequestClearWirelessOnDevice(new AsyncOperation.AOComplete(this.ClearWirelessOnDeviceDone), true); + + public void ClearWirelessOnDeviceDone(bool success) + { + if (this.WirelessUnblockPage() || success) + return; + if (string.IsNullOrEmpty(this.wirelessDeviceErrorDescription)) + this.wirelessDeviceErrorDescription = this.wirelessClearHelper.Error; + if (!(this.wirelessDeviceErrorCode == HRESULT._S_OK)) + return; + this.wirelessDeviceErrorCode = this.wirelessClearHelper.Hr; + } + + public void ClearWirelessOnDeviceForForget() + { + if (this.ActiveDevice.IsConnectedToClient && !this.ActiveDevice.IsGuest) + { + this.RequestClearWirelessOnDevice(new AsyncOperation.AOComplete(this.ClearWirelessOnDeviceForForgetDone), true); + } + else + { + string uuid = (string)null; + HRESULT hresult = this.ActiveDevice.GetDisconnectedWiFiUUID(ref uuid); + if (hresult.IsError) + this.ClearWirelessOnDeviceForForgetDone(hresult.IsSuccess); + else if (!string.IsNullOrEmpty(uuid)) + { + hresult = this.ActiveDevice.UnassociateWiFiUUID(uuid); + this.ClearWirelessOnDeviceForForgetDone(hresult.IsSuccess); + } + else + this.ClearWirelessOnDeviceForForgetDone(true); + } + } + + public void ClearWirelessOnDeviceForForgetDone(bool success) + { + if (success) + SyncControls.Instance.DeleteCurrentDeviceWorker(); + else + MessageBox.Show(Shell.LoadString(StringId.IDS_WIRELESS_CLEAR_UUID_FAILED_TITLE), Shell.LoadString(StringId.IDS_WIRELESS_CLEAR_UUID_FAILED), (EventHandler)null); + this.WirelessUnblockPage(); + } + + private void RequestClearWirelessOnDevice( + AsyncOperation.AOComplete completeFunc, + bool fIgnoreErrors) + { + this.wirelessDeviceErrorDescription = (string)null; + this.wirelessDeviceErrorCaption = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_PRE_SETUP_FAILED); + this.wirelessDeviceErrorCode = HRESULT._S_OK; + WirelessStateResults wirelessStateResults; + do + { + wirelessStateResults = this.wirelessClearHelper.StartOperation(this.ActiveDevice, completeFunc, fIgnoreErrors); + if (wirelessStateResults == WirelessStateResults.NotAvailable) + Thread.Sleep(200); + } + while (wirelessStateResults == WirelessStateResults.NotAvailable); + } + + public void SetProfileDone(bool success) + { + if (this.WirelessUnblockPage()) + return; + if (success) + this.WirelessDeviceProfile = this.wirelessProfileToSave; + this._profileSavedResult = HRESULT._E_UNEXPECTED; + if (success && this.wirelessSetProfileHelper.WlanTestSucceeded) + { + this.ProfileSavedResult = HRESULT._S_OK; + } + else + { + if (string.IsNullOrEmpty(this.wirelessDeviceErrorDescription)) + this.wirelessDeviceErrorDescription = this.wirelessSetProfileHelper.Error; + if (this.wirelessDeviceErrorCode == HRESULT._S_OK) + this.wirelessDeviceErrorCode = this.wirelessSetProfileHelper.Hr; + this.wirelessDeviceCanceled = this.wirelessSetProfileHelper.Canceled; + this.ProfileSavedResult = this.wirelessSetProfileHelper.Hr; + } + } + + public HRESULT ProfileSavedResult + { + get => this._profileSavedResult; + set + { + if (!(this._profileSavedResult != value)) + return; + this._profileSavedResult = value; + this.FirePropertyChanged(nameof(ProfileSavedResult)); + } + } + + public string WirelessDeviceErrorDescription => this.wirelessDeviceErrorDescription; + + public bool WirelessDeviceShowError => this.wirelessDeviceErrorCode != HRESULT._S_OK; + + public bool WirelessDeviceShowErrorNow => (uint)this.wirelessDeviceErrorCode.Int >= 3222082080U && (uint)this.wirelessDeviceErrorCode.Int <= 3222082085U; + + public void WirelessDeviceShowErrorDialog() + { + if (!this.WirelessDeviceShowError) + return; + if (string.IsNullOrEmpty(this.wirelessDeviceErrorCaption)) + Shell.ShowErrorDialog(this.wirelessDeviceErrorCode.Int, StringId.IDS_WIRELESS_SYNC_GENERIC_SETUP_FAILED); + else + ErrorDialogInfo.Show(this.wirelessDeviceErrorCode.Int, this.wirelessDeviceErrorCaption); + } + + public bool WirelessDeviceCanceled => this.wirelessDeviceCanceled; + + public void CancelSetWirelessSettings() => this.wirelessSetProfileHelper.Cancel(); + + public Choice WirelessNetworkTypes + { + get + { + WlanAuthCipherPairList list = new WlanAuthCipherPairList(); + IList networkTypeCommandList = (IList)new List(); + if (this.ActiveDevice.IsConnectedToClient) + this.ActiveDevice.GetWiFiAuthorizationCipherList(ref list); + foreach (WirelessType wirelessRadioGroupItem in WirelessSync.wirelessRadioGroupItems) + { + if (wirelessRadioGroupItem.DisplayType && (wirelessRadioGroupItem.AlwaysSupported || this.DeviceSupportsType(list, wirelessRadioGroupItem.Type))) + { + WirelessNetworkTypeCommand networkTypeCommand = new WirelessNetworkTypeCommand((IModelItemOwner)this, wirelessRadioGroupItem.Description, (EventHandler)null, wirelessRadioGroupItem.Type); + networkTypeCommandList.Add(networkTypeCommand); + } + } + this.wirelessNetworkTypesChoice = new Choice((IModelItemOwner)this); + this.wirelessNetworkTypesChoice.Options = (IList)networkTypeCommandList; + return this.wirelessNetworkTypesChoice; + } + } + + public WirelessStateResults RequestDeviceWirelessProfile() + { + this.wirelessDeviceErrorDescription = (string)null; + this.wirelessDeviceErrorCaption = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_WLAN_UUID_FAILED); + this.wirelessDeviceErrorCode = HRESULT._S_OK; + WirelessStateResults result = this.wirelessDeviceProfileHelper.StartOperation(this.ActiveDevice, new AsyncOperation.AOComplete(this.GetDeviceWirelessProfileDone)); + this.WirelessHandleDeviceBusy(result); + return result; + } + + public void GetDeviceWirelessProfileDone(bool success) + { + if (this.WirelessUnblockPage()) + return; + if (success) + { + this.WirelessDeviceProfile = this.wirelessDeviceProfileHelper.DeviceProfile; + } + else + { + this.WirelessDeviceProfile = (WlanProfile)null; + if (string.IsNullOrEmpty(this.wirelessDeviceErrorDescription)) + this.wirelessDeviceErrorDescription = this.wirelessDeviceProfileHelper.Error; + if (!(this.wirelessDeviceErrorCode == HRESULT._S_OK)) + return; + this.wirelessDeviceErrorCode = this.wirelessDeviceProfileHelper.Hr; + } + } + + public WirelessStateResults RequestConnectedWirelessNetwork() + { + this.wirelessDeviceErrorDescription = (string)null; + this.wirelessDeviceErrorCaption = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_PRE_SETUP_FAILED); + this.wirelessDeviceErrorCode = HRESULT._S_OK; + this.wirelessGetConnectedProfileResult = HRESULT._S_OK; + WirelessStateResults result = this.wirelessGetConnectedNetworkHelper.StartOperation(this.ActiveDevice, new AsyncOperation.AOComplete(this.GetConnectedNetworkDone)); + this.WirelessHandleDeviceBusy(result); + return result; + } + + public string ConnectedWirelessNetwork => this.wirelessConnectedProfile != null ? this.wirelessConnectedProfile.SSID : (string)null; + + public void GetConnectedNetworkDone(bool success) + { + if (this.WirelessUnblockPage()) + return; + WlanProfile connectedNetwork = this.wirelessGetConnectedNetworkHelper.ConnectedNetwork; + if (success) + { + this.wirelessConnectedProfile = connectedNetwork; + } + else + { + this.wirelessGetConnectedProfileResult = this.wirelessGetConnectedNetworkHelper.Hr; + this.wirelessConnectedProfile = (WlanProfile)null; + if (string.IsNullOrEmpty(this.wirelessDeviceErrorDescription)) + this.wirelessDeviceErrorDescription = this.wirelessGetConnectedNetworkHelper.Error; + if (this.wirelessDeviceErrorCode == HRESULT._S_OK) + this.wirelessDeviceErrorCode = this.wirelessGetConnectedNetworkHelper.Hr; + } + this.FirePropertyChanged("ConnectedWirelessNetwork"); + } + + public bool WirelessGetConnectedProfileFailed => this.wirelessGetConnectedProfileResult != HRESULT._S_OK; + + public string WirelessGetConnectedProfileResult => this.wirelessGetConnectedProfileResult.Int.ToString("X"); + + private bool SetWirelessSettings(WlanProfile profile) + { + if (profile == null) + return false; + this.wirelessProfileToSave = profile; + return true; + } + + private WlanProfile CreateWlanProfile(string name, object networkType, string key) + { + WlanAuthCipherPairList list = new WlanAuthCipherPairList(); + WirelessNetworkTypeCommand networkTypeCommand = networkType as WirelessNetworkTypeCommand; + bool flag = false; + if (string.IsNullOrEmpty(name) || networkTypeCommand == null || (networkTypeCommand.NetworkType == null || this.ActiveDevice == null)) + { + this.wirelessDeviceErrorDescription = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_SETUP_FAILED_GENERIC); + return (WlanProfile)null; + } + HRESULT authorizationCipherList = this.ActiveDevice.GetWiFiAuthorizationCipherList(ref list); + if (authorizationCipherList.IsSuccess) + { + foreach (WlanAuthCipherPair wlanAuthCipherPair in (List)list) + { + if (wlanAuthCipherPair.Auth == networkTypeCommand.NetworkType.Auth && wlanAuthCipherPair.Cipher == networkTypeCommand.NetworkType.Cipher) + { + flag = true; + break; + } + } + } + if (!flag) + { + this.wirelessDeviceErrorDescription = string.Format(Shell.LoadString(StringId.IDS_WIRELESS_ERROR_UNSUPPORTED_AUTH), (object)name); + this.wirelessDeviceErrorCode = authorizationCipherList; + return (WlanProfile)null; + } + if (string.IsNullOrEmpty(name)) + { + this.wirelessDeviceErrorDescription = Shell.LoadString(StringId.IDS_WIRELESS_ERROR_INVALID_NAME); + return (WlanProfile)null; + } + return new WlanProfile() + { + SSID = name, + Auth = networkTypeCommand.NetworkType.Auth, + Cipher = networkTypeCommand.NetworkType.Cipher, + Key = key + }; + } + + private bool IsWEP(WirelessCiphers cipher) => cipher == WirelessCiphers.WEP || cipher == WirelessCiphers.WEP40 || cipher == WirelessCiphers.WEP104; + + private bool IsWPA(WirelessAuthenticationTypes auth) => auth == WirelessAuthenticationTypes.WPA2PSK || auth == WirelessAuthenticationTypes.WPAPSK; + + private bool DeviceSupportsType( + WlanAuthCipherPairList supportedList, + WlanAuthCipherPair displayType) + { + foreach (WlanAuthCipherPair supported in (List)supportedList) + { + if (displayType.Cipher == WirelessCiphers.WEP) + { + if (supported.Auth == displayType.Auth && this.IsWEP(supported.Cipher)) + return true; + } + else if (supported.Auth == displayType.Auth && supported.Cipher == displayType.Cipher) + return true; + } + return false; + } + + public string SavingProfileName => this.wirelessSetProfileHelper.AttemptingName; + + private void WirelessHandleDeviceBusy(WirelessStateResults result) + { + if (result != WirelessStateResults.NotAvailable) + return; + this.wirelessBlockedPage = ZuneShell.DefaultInstance.Management.CurrentCategoryPage.CurrentCategory; + Management.NavigateToCategory(SettingCategories.WirelessSetupDeviceBusy); + } + + private bool WirelessUnblockPage() + { + if (this.wirelessBlockedPage == null) + return false; + Management.NavigateToCategory(this.wirelessBlockedPage); + this.wirelessBlockedPage = (Category)null; + return true; + } + } +} diff --git a/ZuneUI/WirelessSyncChooseNetworkPage.cs b/ZuneUI/WirelessSyncChooseNetworkPage.cs new file mode 100644 index 0000000..17a3daa --- /dev/null +++ b/ZuneUI/WirelessSyncChooseNetworkPage.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessSyncChooseNetworkPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class WirelessSyncChooseNetworkPage : WizardPage + { + internal WirelessSyncChooseNetworkPage(WirelessSyncWizard wizard) + : base((Wizard)wizard) + => this.Description = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_START_CONFIG); + + public override bool IsEnabled => WirelessSync.Instance.ExistingNetworkChoice.ChosenIndex == 1; + + public override string UI => "res://ZuneShellResources!WirelessSync.uix#WirelessSyncChooseNetworkPage"; + } +} diff --git a/ZuneUI/WirelessSyncErrorPage.cs b/ZuneUI/WirelessSyncErrorPage.cs new file mode 100644 index 0000000..5f559da --- /dev/null +++ b/ZuneUI/WirelessSyncErrorPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessSyncErrorPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class WirelessSyncErrorPage : WizardErrorPage + { + internal WirelessSyncErrorPage(WirelessSyncWizard wizard) + : base((Wizard)wizard) + => this.Description = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_GENERIC_ERROR); + + public override string UI => "res://ZuneShellResources!WirelessSync.uix#WirelessSyncErrorPage"; + } +} diff --git a/ZuneUI/WirelessSyncSummaryPage.cs b/ZuneUI/WirelessSyncSummaryPage.cs new file mode 100644 index 0000000..65e8b0d --- /dev/null +++ b/ZuneUI/WirelessSyncSummaryPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessSyncSummaryPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class WirelessSyncSummaryPage : WizardPage + { + internal WirelessSyncSummaryPage(WirelessSyncWizard wizard) + : base((Wizard)wizard) + => this.Description = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_START_CONFIG); + + public override string UI => "res://ZuneShellResources!WirelessSync.uix#WirelessSyncSummaryPage"; + } +} diff --git a/ZuneUI/WirelessSyncUseExistingPage.cs b/ZuneUI/WirelessSyncUseExistingPage.cs new file mode 100644 index 0000000..b4c9e97 --- /dev/null +++ b/ZuneUI/WirelessSyncUseExistingPage.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessSyncUseExistingPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class WirelessSyncUseExistingPage : WizardPage + { + internal WirelessSyncUseExistingPage(WirelessSyncWizard wizard) + : base((Wizard)wizard) + => this.Description = Shell.LoadString(StringId.IDS_WIRELESS_SYNC_START_CONFIG); + + public override string UI => "res://ZuneShellResources!WirelessSync.uix#WirelessSyncUseExistingPage"; + } +} diff --git a/ZuneUI/WirelessSyncWizard.cs b/ZuneUI/WirelessSyncWizard.cs new file mode 100644 index 0000000..654de60 --- /dev/null +++ b/ZuneUI/WirelessSyncWizard.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessSyncWizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class WirelessSyncWizard : Wizard + { + private string _progressText; + + public WirelessSyncWizard() + { + this.AddPage((WizardPage)new WirelessSyncUseExistingPage(this)); + this.AddPage((WizardPage)new WirelessSyncChooseNetworkPage(this)); + this.AddPage((WizardPage)new WirelessSyncSummaryPage(this)); + this.AddPage((WizardPage)new WirelessSyncErrorPage(this)); + } + + public string ProgressText + { + get => this._progressText; + set + { + if (!(this._progressText != value)) + return; + this._progressText = value; + this.FirePropertyChanged(nameof(ProgressText)); + } + } + } +} diff --git a/ZuneUI/WirelessType.cs b/ZuneUI/WirelessType.cs new file mode 100644 index 0000000..14e6997 --- /dev/null +++ b/ZuneUI/WirelessType.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + internal class WirelessType + { + private WlanAuthCipherPair _type; + private string _description; + private bool _newGroup; + private bool _alwaysSupported; + private bool _displayType; + + public WirelessType( + WlanAuthCipherPair type, + string description, + bool displayType, + bool alwaysSupported, + bool newGroup) + { + this._type = type; + this._description = description; + this._alwaysSupported = alwaysSupported; + this._newGroup = newGroup; + this._displayType = displayType; + } + + public bool NewGroup => this._newGroup; + + public bool AlwaysSupported => this._alwaysSupported; + + public WlanAuthCipherPair Type => this._type; + + public string Description => this._description; + + public bool DisplayType => this._displayType; + } +} diff --git a/ZuneUI/WirelessTypeGrid.cs b/ZuneUI/WirelessTypeGrid.cs new file mode 100644 index 0000000..9100f02 --- /dev/null +++ b/ZuneUI/WirelessTypeGrid.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WirelessTypeGrid +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; +using System; +using System.Collections.Generic; + +namespace ZuneUI +{ + internal class WirelessTypeGrid + { + private int _iColumn; + private int _cColumns; + private List _items = new List(); + + public WirelessTypeGrid(int columns) => this._cColumns = columns; + + public void NewRow() + { + if (this._iColumn > 0) + { + while (this._iColumn < this._cColumns) + this.AddItem(new WirelessNetworkTypeCommand((IModelItemOwner)null, (string)null, (EventHandler)null, (WlanAuthCipherPair)null)); + } + this._iColumn = 0; + } + + public bool AddItem(WirelessNetworkTypeCommand item) + { + if (this._iColumn >= this._cColumns) + return false; + this._items.Add(item); + ++this._iColumn; + return true; + } + + public List NetworkList => this._items; + } +} diff --git a/ZuneUI/Wizard.cs b/ZuneUI/Wizard.cs new file mode 100644 index 0000000..0c3d19a --- /dev/null +++ b/ZuneUI/Wizard.cs @@ -0,0 +1,397 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.Wizard +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; + +namespace ZuneUI +{ + public abstract class Wizard : ModelItem + { + private List _pages; + private int _currentPageIndex; + private EventHandler _cancelCommandHandler; + private HRESULT _error; + private bool _errorPageIsEnabled; + protected BreadcrumbFactory _breadcrumbFactory; + private bool _finished; + private IDictionary _settings; + + public event WizardStateChangeHandler StateChanged; + + protected Wizard() + { + this._settings = (IDictionary)null; + this._pages = new List(); + this._currentPageIndex = -1; + this._error = HRESULT._S_OK; + this._finished = false; + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + foreach (ModelItem page in this._pages) + page.Dispose(); + if (this._settings != null) + { + foreach (object obj in (IEnumerable)this._settings.Values) + { + if (obj is IDisposable) + ((IDisposable)obj).Dispose(); + } + } + } + base.OnDispose(disposing); + } + + protected void AddPage(WizardPage page) + { + this._pages.Add(page); + if (this._currentPageIndex == -1 && page.IsEnabled) + { + this._currentPageIndex = this._pages.Count - 1; + this.CurrentPage.Activate(); + } + this.FirePropertyChanged("Pages"); + } + + protected void AddPage(WizardPage page, string breadcrumbTitle) + { + if (!string.IsNullOrEmpty(breadcrumbTitle) && page.IsEnabled) + { + page.BreadcrumbTitle = breadcrumbTitle; + if (this._breadcrumbFactory == null) + this._breadcrumbFactory = new BreadcrumbFactory(); + this._breadcrumbFactory.AddCrumb(new Breadcrumb(page)); + } + this.AddPage(page); + } + + public IList Breadcrumbs => this._breadcrumbFactory == null ? (IList)null : this._breadcrumbFactory.Breadcrumbs; + + public void MarkBreadcrumbsComplete() + { + if (this.Breadcrumbs == null) + return; + foreach (Breadcrumb breadcrumb in (IEnumerable)this.Breadcrumbs) + breadcrumb.Complete = true; + } + + public virtual bool IsValid + { + get + { + foreach (WizardPage page in this._pages) + { + if (page.IsEnabled && !page.IsValid) + return false; + } + return true; + } + } + + public bool ShowNavigation => this.CurrentPage != null && this.CurrentPage.ShowNavigation; + + public bool ShowClose => this.CurrentPage != null && this.CurrentPage.ShowClose; + + public bool CanAdvancePageIndex => this.GetNextEnabledPageIndex() != -1; + + public virtual void NotifyStateChanged() + { + if (this.StateChanged != null) + this.StateChanged(); + this.FirePropertyChanged("CanAdvancePageIndex"); + } + + public virtual bool CanMoveNext => this.CurrentPage.IsValid && this.CanAdvancePageIndex; + + public virtual bool CanStart => true; + + public void Start() + { + if (!this.CanStart || !this.OnStart() || this.CurrentPageIndex >= 0) + return; + this.CurrentPageIndex = this.GetNextEnabledPageIndex(-1); + } + + protected virtual bool OnStart() => true; + + public virtual bool MoveNext() + { + bool flag = false; + WizardPage currentPage1 = this.CurrentPage; + if (!this.CanMoveNext) + throw new ApplicationException("cannot move next in this state"); + if (this.CurrentPage == null || this.CurrentPage.OnMovingNext()) + { + this.CurrentPageIndex = this.GetNextEnabledPageIndex(); + flag = true; + } + WizardPage currentPage2 = this.CurrentPage; + if (this._breadcrumbFactory != null) + this._breadcrumbFactory.UpdateState(currentPage1, currentPage2, true); + return flag; + } + + public IList Pages => (IList)this._pages.AsReadOnly(); + + public HRESULT Error + { + get => this._error; + private set + { + if (!(this._error != value)) + return; + this._error = value; + this.FirePropertyChanged(nameof(Error)); + } + } + + public void ShowErrorPage(int hr) => this.ShowErrorPage(new HRESULT(hr)); + + public void ShowErrorPage(HRESULT hr) + { + this.SetError(hr, (object)null); + this.ErrorPageIsEnabled = true; + this.MoveNext(); + } + + public bool ErrorPageIsEnabled + { + get => this._errorPageIsEnabled; + protected set + { + if (this._errorPageIsEnabled == value) + return; + this._errorPageIsEnabled = value; + this.FirePropertyChanged(nameof(ErrorPageIsEnabled)); + } + } + + private int GetNextEnabledPageIndex() => this.GetNextEnabledPageIndex(this.CurrentPageIndex); + + private int GetNextEnabledPageIndex(int startIndex) + { + int index = startIndex; + while (++index < this._pages.Count) + { + if (this._pages[index].IsEnabled) + return index; + } + return -1; + } + + public virtual bool CanMoveBack => this.GetPrevEnabledPageIndex() != -1; + + public virtual bool MoveBack() + { + bool flag = false; + WizardPage currentPage1 = this.CurrentPage; + if (!this.CanMoveBack) + throw new ApplicationException("cannot move back in this state"); + if (this.CurrentPage == null || this.CurrentPage.OnMovingBack()) + { + this.CurrentPageIndex = this.GetPrevEnabledPageIndex(); + flag = true; + } + WizardPage currentPage2 = this.CurrentPage; + if (this._breadcrumbFactory != null) + this._breadcrumbFactory.UpdateState(currentPage1, currentPage2, false); + return flag; + } + + private int GetPrevEnabledPageIndex() + { + int currentPageIndex = this.CurrentPageIndex; + while (--currentPageIndex >= 0) + { + if (this._pages[currentPageIndex].IsEnabled) + return currentPageIndex; + } + return -1; + } + + public virtual bool CanCommitChanges => this.IsValid && !this.CanAdvancePageIndex; + + public bool CommitChanges() + { + if (!this.CanCommitChanges) + return false; + foreach (WizardPage page in this._pages) + { + if (!page.CommitChanges()) + { + this.CurrentPageIndex = this._pages.IndexOf(page); + return false; + } + } + if (!this.OnCommitChanges()) + return false; + if (this._settings != null) + { + foreach (ProxySettingDelegate key in (IEnumerable)this._settings.Keys) + key(this._settings[key]); + this.ClearSettings(); + } + return true; + } + + public bool AsyncCommitChanges() => this.CanCommitChanges && ThreadPool.QueueUserWorkItem(new WaitCallback(this.AsyncCommitChangesPrivate), (object)this._currentPageIndex); + + private void AsyncCommitChangesPrivate(object state) + { + int currentPageIndex = this._currentPageIndex; + int num = -1; + foreach (WizardPage page in this._pages) + { + if (!page.CommitChanges()) + { + num = this._pages.IndexOf(page); + break; + } + } + if (!this.OnCommitChanges()) + num = currentPageIndex; + Application.DeferredInvoke(new DeferredInvokeHandler(this.OnAsyncCommitCompletedPrivate), (object)num); + } + + private void OnAsyncCommitCompletedPrivate(object args) + { + int num = (int)args; + bool success = num < 0; + if (success) + { + if (this._settings != null) + { + foreach (ProxySettingDelegate key in (IEnumerable)this._settings.Keys) + key(this._settings[key]); + this.ClearSettings(); + } + } + else if (this.CurrentPageIndex == num) + this.CurrentPage.Activate(); + else + this.CurrentPageIndex = num; + this.OnAsyncCommitCompleted(success); + } + + protected virtual void OnAsyncCommitCompleted(bool success) + { + } + + protected virtual bool OnCommitChanges() => true; + + protected virtual void OnSetError(HRESULT hr, object state) + { + } + + public virtual bool CanCancel => !this.HasPages || this.CurrentPage == null || this.CurrentPage.CanCancel; + + public EventHandler CancelCommandHandler + { + get + { + if (this._cancelCommandHandler == null) + this._cancelCommandHandler = new EventHandler(this.CancelInvokedHandler); + return this._cancelCommandHandler; + } + } + + public virtual void Cancel() + { + if (!this.CanCancel) + throw new ApplicationException("cannot cancel in this state"); + this.CancelSettings(); + } + + public bool HasPages => this._pages.Count > 0; + + public WizardPage CurrentPage => this._pages.Count != 0 && this._currentPageIndex >= 0 ? this._pages[this._currentPageIndex] : (WizardPage)null; + + public int CurrentPageIndex + { + get => this._currentPageIndex; + set + { + if (this._currentPageIndex == value) + return; + if (this.CurrentPage != null) + this.CurrentPage.Deactivate(); + this._currentPageIndex = value; + if (this._currentPageIndex == -1) + return; + this.CurrentPage.Activate(); + this.FirePropertyChanged(nameof(CurrentPageIndex)); + this.FirePropertyChanged("CanAdvancePageIndex"); + this.FirePropertyChanged("CurrentPage"); + this.FirePropertyChanged("CanMoveBack"); + this.FirePropertyChanged("CanMoveNext"); + this.FirePropertyChanged("CanCommitChanges"); + } + } + + public bool HasEntries => this._settings != null && this._settings.Count > 0; + + public virtual void RecordSetting(ProxySettingDelegate proxy, object data) + { + if (this._settings == null) + this._settings = (IDictionary)new Dictionary(); + this._settings[proxy] = data; + } + + public virtual void CancelSettings() => this.ClearSettings(); + + public void ResetError() => this.SetError(HRESULT._S_OK, (object)null); + + public void SetError(HRESULT hr, object state) + { + if (Application.IsApplicationThread) + { + this.Error = hr; + this.OnSetError(hr, state); + } + else + Application.DeferredInvoke(new DeferredInvokeHandler(this.AsyncSetError), (object)new object[2] + { + (object) hr, + state + }); + } + + private void AsyncSetError(object args) + { + object[] objArray = (object[])args; + this.SetError((HRESULT)objArray[0], objArray[1]); + } + + private void ClearSettings() + { + if (this._settings == null) + return; + this._settings.Clear(); + this._settings = (IDictionary)null; + } + + private void CancelInvokedHandler(object sender, EventArgs args) => this.Cancel(); + + public bool Finished + { + get => this._finished; + set + { + if (this._finished == value) + return; + this._finished = value; + this.FirePropertyChanged(nameof(Finished)); + } + } + } +} diff --git a/ZuneUI/WizardErrorPage.cs b/ZuneUI/WizardErrorPage.cs new file mode 100644 index 0000000..d939778 --- /dev/null +++ b/ZuneUI/WizardErrorPage.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardErrorPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class WizardErrorPage : WizardPage + { + internal WizardErrorPage(Wizard wizard) + : base(wizard) + => this.Description = Shell.LoadString(StringId.IDS_GENERIC_ERROR); + + public override bool IsEnabled => this._owner.ErrorPageIsEnabled; + + public override bool ShowClose => true; + + public override string UI => "res://ZuneShellResources!Wizard.uix#WizardErrorPage"; + } +} diff --git a/ZuneUI/WizardExperience.cs b/ZuneUI/WizardExperience.cs new file mode 100644 index 0000000..233bb88 --- /dev/null +++ b/ZuneUI/WizardExperience.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardExperience +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System.Collections; + +namespace ZuneUI +{ + public class WizardExperience : Experience + { + private CategoryPageNode _fue; + private CategoryPageNode _wirelessSetup; + + public WizardExperience(Frame frameOwner) + : base(frameOwner) + { + } + + public override IList NodesList => (IList)null; + + public CategoryPageNode FUE + { + get + { + if (this._fue == null) + this._fue = new CategoryPageNode((Experience)this, StringId.IDS_SETTINGS_PIVOT, (IList)new Category[3] + { + SettingCategories.Collection, + SettingCategories.Filetype, + SettingCategories.Privacy + }, SQMDataId.Invalid, false, false); + return this._fue; + } + } + + public CategoryPageNode WirelessSetup + { + get + { + if (this._wirelessSetup == null) + this._wirelessSetup = new CategoryPageNode((Experience)this, StringId.IDS_SET_UP_YOUR_ZUNE, (IList)new Category[1] + { + SettingCategories.WirelessSetup + }, SQMDataId.Invalid, true, false); + return this._wirelessSetup; + } + } + } +} diff --git a/ZuneUI/WizardHelper.cs b/ZuneUI/WizardHelper.cs new file mode 100644 index 0000000..837b9cc --- /dev/null +++ b/ZuneUI/WizardHelper.cs @@ -0,0 +1,65 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using UIXControls; + +namespace ZuneUI +{ + public class WizardHelper : DialogHelper, IWizardNavigation + { + private Wizard _wizard; + private Command _backCommand; + private Command _nextCommand; + private Command _finishCommand; + + public WizardHelper() + : this((EventHandler)null) + { + } + + public WizardHelper(EventHandler cancelCommandHandler) + { + this._backCommand = new Command((IModelItemOwner)this); + this._backCommand.Description = Shell.LoadString(StringId.IDS_BACK_BUTTON); + this._nextCommand = new Command((IModelItemOwner)this); + this._nextCommand.Description = Shell.LoadString(StringId.IDS_NEXT_BUTTON); + this._finishCommand = new Command((IModelItemOwner)this); + this._finishCommand.Description = Shell.LoadString(StringId.IDS_FINISH_BUTTON); + if (cancelCommandHandler == null) + return; + this.Cancel.Invoked += cancelCommandHandler; + } + + public Wizard Wizard + { + get => this._wizard; + set + { + if (this._wizard == value) + return; + if (this._wizard != null && this._wizard.CancelCommandHandler != null) + this.Cancel.Invoked -= this._wizard.CancelCommandHandler; + this._wizard = value; + this.FirePropertyChanged(nameof(Wizard)); + if (this._wizard.CancelCommandHandler == null) + return; + this.Cancel.Invoked += this._wizard.CancelCommandHandler; + } + } + + public static void Show(EventHandler cancelCommandHandler) => new WizardHelper(cancelCommandHandler).Show(); + + public Command Back => this._backCommand; + + public Command Next => this._nextCommand; + + public Command Finish => this._finishCommand; + + Command IWizardNavigation.Cancel => this.Cancel; + } +} diff --git a/ZuneUI/WizardNode.cs b/ZuneUI/WizardNode.cs new file mode 100644 index 0000000..f060a8e --- /dev/null +++ b/ZuneUI/WizardNode.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardNode +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class WizardNode : Node + { + private Wizard _wizard; + + public WizardNode(Experience owner, Wizard wizard, SQMDataId sqmDataID) + : base(owner, (string)null, sqmDataID) + => this._wizard = wizard; + + protected override void Execute(Shell shell) + { + WizardZunePage wizardZunePage = new WizardZunePage((Node)this, this._wizard); + shell.NavigateToPage((ZunePage)wizardZunePage); + } + } +} diff --git a/ZuneUI/WizardPage.cs b/ZuneUI/WizardPage.cs new file mode 100644 index 0000000..cfb3a04 --- /dev/null +++ b/ZuneUI/WizardPage.cs @@ -0,0 +1,169 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneUI +{ + public abstract class WizardPage : ModelItem + { + protected Wizard _owner; + private string _breadcrumbTitle; + private string _detailDescription; + private string _loadStatus; + protected bool _showValidationState; + private string _statusMessage; + private bool _showStatusMessageIcon; + private bool _enableVerticalScrolling; + private bool _canNavigateInto; + + protected WizardPage(Wizard owner) + { + this._canNavigateInto = true; + this._showStatusMessageIcon = true; + this._owner = owner; + } + + public abstract string UI { get; } + + internal virtual void Activate() + { + } + + internal virtual void Deactivate() => this.ShowValidationState = false; + + public virtual bool IsEnabled => !this._owner.ErrorPageIsEnabled; + + public virtual bool IsValid => true; + + public virtual bool ShowNavigation => true; + + public virtual bool ShowClose => false; + + public virtual bool CanCancel => true; + + public string BreadcrumbTitle + { + get => this._breadcrumbTitle; + set + { + if (!(this._breadcrumbTitle != value)) + return; + this._breadcrumbTitle = value; + this.FirePropertyChanged(nameof(BreadcrumbTitle)); + } + } + + public string DetailDescription + { + get => this._detailDescription; + set + { + if (!(this._detailDescription != value)) + return; + this._detailDescription = value; + this.FirePropertyChanged(nameof(DetailDescription)); + } + } + + public string LoadStatus + { + get => this._loadStatus; + set + { + if (!(this._loadStatus != value)) + return; + this._loadStatus = value; + this.FirePropertyChanged(nameof(LoadStatus)); + } + } + + public bool ShowValidationState + { + get => this._showValidationState; + private set + { + if (this._showValidationState == value) + return; + this._showValidationState = value; + this.FirePropertyChanged(nameof(ShowValidationState)); + } + } + + public string StatusMessage + { + get => this._statusMessage; + set + { + if (!(this._statusMessage != value)) + return; + this._statusMessage = value; + this.FirePropertyChanged(nameof(StatusMessage)); + } + } + + public virtual bool ShowPrivacyStatement => false; + + public bool CanShowStatusMessageIcon + { + get => this._showStatusMessageIcon; + set + { + if (this._showStatusMessageIcon == value) + return; + this._showStatusMessageIcon = value; + this.FirePropertyChanged(nameof(CanShowStatusMessageIcon)); + } + } + + public bool CanNavigateInto + { + get => this._canNavigateInto; + set + { + if (this._canNavigateInto == value) + return; + this._canNavigateInto = value; + this.FirePropertyChanged(nameof(CanNavigateInto)); + } + } + + public bool EnableVerticalScrolling + { + get => this._enableVerticalScrolling; + set + { + if (this._enableVerticalScrolling == value) + return; + this._enableVerticalScrolling = value; + this.FirePropertyChanged(nameof(EnableVerticalScrolling)); + } + } + + public void ShowValidation() + { + this.ShowValidationState = true; + this.FirePropertyChanged("ShowValidationState"); + } + + public virtual void RefreshValidationState() => this.ShowValidation(); + + public void ShowGenericErrorStatus() + { + if (!string.IsNullOrEmpty(this.StatusMessage) || this.IsValid) + return; + this.StatusMessage = Shell.LoadString(StringId.IDS_WIZARD_GENERIC_ERROR); + } + + public bool CommitChanges() => this.OnCommitChanges(); + + protected virtual bool OnCommitChanges() => true; + + internal virtual bool OnMovingNext() => true; + + internal virtual bool OnMovingBack() => true; + } +} diff --git a/ZuneUI/WizardPropertyEditor.cs b/ZuneUI/WizardPropertyEditor.cs new file mode 100644 index 0000000..79b5227 --- /dev/null +++ b/ZuneUI/WizardPropertyEditor.cs @@ -0,0 +1,30 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneUI +{ + public abstract class WizardPropertyEditor : MetadataEditMedia + { + private WizardPropertyEditorPage _page; + + protected WizardPropertyEditor() => this._source = WizardPropertySource.Instance; + + public abstract PropertyDescriptor[] PropertyDescriptors { get; } + + public WizardPropertyEditorPage Page => this._page; + + internal void Initialize(WizardPropertyEditorPage page) + { + this._page = page; + this.Initialize((IList)new object[1] + { + (object) page + }, this.PropertyDescriptors); + } + } +} diff --git a/ZuneUI/WizardPropertyEditorPage.cs b/ZuneUI/WizardPropertyEditorPage.cs new file mode 100644 index 0000000..0e279d1 --- /dev/null +++ b/ZuneUI/WizardPropertyEditorPage.cs @@ -0,0 +1,118 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardPropertyEditorPage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections.Generic; + +namespace ZuneUI +{ + public abstract class WizardPropertyEditorPage : WizardPage + { + private Dictionary _committedValues; + private WizardPropertyEditor _wizardPropertyEditor; + + protected WizardPropertyEditorPage(Wizard owner) + : base(owner) + { + } + + public WizardPropertyEditor WizardPropertyEditor => this._wizardPropertyEditor; + + public override bool IsValid => this._wizardPropertyEditor == null || this._wizardPropertyEditor.IsValid(); + + protected void Initialize(WizardPropertyEditor wizardPropertyEditor) + { + this._wizardPropertyEditor = wizardPropertyEditor; + this._committedValues = new Dictionary(); + if (this._wizardPropertyEditor == null) + return; + foreach (PropertyDescriptor propertyDescriptor in this._wizardPropertyEditor.PropertyDescriptors) + this.AddProperty(propertyDescriptor); + this._wizardPropertyEditor.Initialize(this); + } + + private void AddProperty(PropertyDescriptor property) + { + if (this._committedValues.ContainsKey(property)) + return; + this._committedValues.Add(property, property.DefaultValue); + } + + public object GetCommittedValue(PropertyDescriptor property) => this._committedValues.ContainsKey(property) ? this._committedValues[property] : (object)null; + + public void SetCommittedValue(PropertyDescriptor property, object value) + { + if (this._committedValues.ContainsKey(property)) + this._committedValues[property] = value; + else + this._committedValues.Add(property, value); + this.SetUncommittedValue(property, value); + } + + internal void SetPropertyState(PropertyDescriptor property, object state) + { + if (this._wizardPropertyEditor == null) + return; + this._wizardPropertyEditor.SetPropertyState(property, state); + } + + public override void RefreshValidationState() + { + if (this._wizardPropertyEditor != null) + this._wizardPropertyEditor.ResetExternalErrors(); + base.RefreshValidationState(); + } + + protected object GetUncommittedValue(PropertyDescriptor property) + { + object obj = (object)null; + if (this._wizardPropertyEditor != null) + obj = this._wizardPropertyEditor.GetPropertyData(property); + return obj; + } + + protected void SetUncommittedValue(PropertyDescriptor property, object value) + { + if (this._wizardPropertyEditor == null) + return; + this._wizardPropertyEditor.SetPropertyData(property, value); + } + + protected bool SetExternalError(PropertyDescriptor descriptor, HRESULT hr) + { + bool flag = false; + MetadataEditProperty metadataEditProperty = (MetadataEditProperty)null; + if (this._wizardPropertyEditor != null) + metadataEditProperty = this._wizardPropertyEditor.GetProperty(descriptor); + if (metadataEditProperty != null) + { + flag = true; + metadataEditProperty.ExternalError = hr; + } + return flag; + } + + protected bool SetExternalError(string propertyName, HRESULT hr) + { + bool flag = false; + MetadataEditProperty metadataEditProperty = (MetadataEditProperty)null; + if (this._wizardPropertyEditor != null) + metadataEditProperty = this._wizardPropertyEditor.GetProperty(propertyName); + if (metadataEditProperty != null) + { + flag = true; + metadataEditProperty.ExternalError = hr; + } + return flag; + } + + internal override bool OnMovingNext() + { + if (this._wizardPropertyEditor != null && this._wizardPropertyEditor.IsValid()) + this._wizardPropertyEditor.Commit(); + return base.OnMovingNext(); + } + } +} diff --git a/ZuneUI/WizardPropertySource.cs b/ZuneUI/WizardPropertySource.cs new file mode 100644 index 0000000..18c9e5d --- /dev/null +++ b/ZuneUI/WizardPropertySource.cs @@ -0,0 +1,36 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardPropertySource +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class WizardPropertySource : PropertySource + { + private static PropertySource _instance; + + private WizardPropertySource() + { + } + + public static PropertySource Instance + { + get + { + if (WizardPropertySource._instance == null) + WizardPropertySource._instance = (PropertySource)new WizardPropertySource(); + return WizardPropertySource._instance; + } + } + + public override object Get(object model, PropertyDescriptor property) => !(model is WizardPropertyEditorPage propertyEditorPage) ? (object)null : propertyEditorPage.GetCommittedValue(property); + + public override void Set(object model, PropertyDescriptor property, object value) + { + if (!(model is WizardPropertyEditorPage propertyEditorPage)) + return; + propertyEditorPage.SetCommittedValue(property, value); + } + } +} diff --git a/ZuneUI/WizardStateChangeHandler.cs b/ZuneUI/WizardStateChangeHandler.cs new file mode 100644 index 0000000..4fdd4e4 --- /dev/null +++ b/ZuneUI/WizardStateChangeHandler.cs @@ -0,0 +1,10 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardStateChangeHandler +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public delegate void WizardStateChangeHandler(); +} diff --git a/ZuneUI/WizardZunePage.cs b/ZuneUI/WizardZunePage.cs new file mode 100644 index 0000000..8c408c7 --- /dev/null +++ b/ZuneUI/WizardZunePage.cs @@ -0,0 +1,104 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WizardZunePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneUI +{ + public class WizardZunePage : ZunePage, IWizardNavigation + { + private Wizard _wizard; + private Command _backCommand; + private Command _nextCommand; + private Command _finishCommand; + private Command _cancelCommand; + + internal WizardZunePage(Node node, Wizard wizard) + { + this._wizard = wizard; + this.UI = "res://ZuneShellResources!WizardControls.uix#WizardZunePage"; + this.BackgroundUI = "res://ZuneShellResources!WizardControls.uix#WizardBackground"; + this.TransportControlStyle = TransportControlStyle.None; + this.PivotPreference = node; + this.ShowCDIcon = false; + this.ShowDeviceIcon = false; + this.ShowPlaylistIcon = false; + this.ShowSettings = false; + this.ShowSearch = false; + this.ShowNowPlayingBackgroundOnIdle = false; + this.CanEnterCompactMode = false; + this.NotificationAreaVisible = false; + this.TransportControlsVisible = false; + this.Cancel.Invoked += new EventHandler(this.OnCancelInvoked); + this.Finish.Invoked += new EventHandler(this.OnFinishInvoked); + } + + public Wizard Wizard => this._wizard; + + public Command Back + { + get + { + if (this._backCommand == null) + { + this._backCommand = new Command((IModelItemOwner)this); + this._backCommand.Description = Shell.LoadString(StringId.IDS_BACK_BUTTON); + } + return this._backCommand; + } + } + + public Command Next + { + get + { + if (this._nextCommand == null) + { + this._nextCommand = new Command((IModelItemOwner)this); + this._nextCommand.Description = Shell.LoadString(StringId.IDS_NEXT_BUTTON); + } + return this._nextCommand; + } + } + + public Command Finish + { + get + { + if (this._finishCommand == null) + { + this._finishCommand = new Command((IModelItemOwner)this); + this._finishCommand.Description = Shell.LoadString(StringId.IDS_FINISH_BUTTON); + } + return this._finishCommand; + } + } + + public Command Cancel + { + get + { + if (this._cancelCommand == null) + { + this._cancelCommand = new Command((IModelItemOwner)this); + this._cancelCommand.Description = Shell.LoadString(StringId.IDS_CANCEL_BUTTON); + } + return this._cancelCommand; + } + } + + public override bool HandleBack() => false; + + public override IPageState SaveAndRelease() => (IPageState)null; + + private void LeaveWizard() => ZuneShell.DefaultInstance.NavigateBack(); + + private void OnCancelInvoked(object sender, EventArgs e) => this.LeaveWizard(); + + private void OnFinishInvoked(object sender, EventArgs e) => this.LeaveWizard(); + } +} diff --git a/ZuneUI/WlanCommand.cs b/ZuneUI/WlanCommand.cs new file mode 100644 index 0000000..3a15b50 --- /dev/null +++ b/ZuneUI/WlanCommand.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WlanCommand +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using MicrosoftZuneLibrary; + +namespace ZuneUI +{ + public class WlanCommand : Command + { + private WlanProfile _profile; + + public WlanCommand(WlanProfile profile) + { + this._profile = profile; + this.Description = profile.SSID; + } + + public WlanProfile Profile => this._profile; + + public bool NeedsKey => this.Profile != null && this.Profile.Cipher != WirelessCiphers.None && (!this.Profile.Encrypted && string.IsNullOrEmpty(this.Profile.Key) || this.Profile.Encrypted && (this.Profile.EncryptedKey == null || this.Profile.EncryptedKey.Length == 0)); + + public override string ToString() => this.Description; + } +} diff --git a/ZuneUI/WlanSignalStrenghComparer.cs b/ZuneUI/WlanSignalStrenghComparer.cs new file mode 100644 index 0000000..c7abeee --- /dev/null +++ b/ZuneUI/WlanSignalStrenghComparer.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.WlanSignalStrenghComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using MicrosoftZuneLibrary; +using System.Collections.Generic; + +namespace ZuneUI +{ + internal class WlanSignalStrenghComparer : IComparer + { + public int Compare(WlanProfile x, WlanProfile y) => x != null && y != null ? (int)y.SignalQuality - (int)x.SignalQuality : 0; + } +} diff --git a/ZuneUI/XmlHelper.cs b/ZuneUI/XmlHelper.cs new file mode 100644 index 0000000..2ccdc9d --- /dev/null +++ b/ZuneUI/XmlHelper.cs @@ -0,0 +1,38 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.XmlHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Security; +using System.Text.RegularExpressions; + +namespace ZuneUI +{ + public static class XmlHelper + { + private static Regex _xmlRegex = new Regex("<[^<>]+>", RegexOptions.IgnoreCase); + + public static string Escape(string text) => SecurityElement.Escape(text); + + public static string Unescape(string text) + { + if (text != null) + { + text = text.Replace(""", "\""); + text = text.Replace("'", "'"); + text = text.Replace("&", "&"); + text = text.Replace("<", "<"); + text = text.Replace(">", ">"); + } + return text; + } + + public static string Strip(string text) + { + if (text != null) + text = XmlHelper._xmlRegex.Replace(text, string.Empty); + return text; + } + } +} diff --git a/ZuneUI/YearPropertyDescriptor.cs b/ZuneUI/YearPropertyDescriptor.cs new file mode 100644 index 0000000..95baae4 --- /dev/null +++ b/ZuneUI/YearPropertyDescriptor.cs @@ -0,0 +1,36 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.YearPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneUI +{ + public class YearPropertyDescriptor : PropertyDescriptor + { + public YearPropertyDescriptor( + string name, + string multiValueString, + string unknownString, + int maxTextLength) + : base(name, multiValueString, unknownString, maxTextLength) + { + } + + public override string ConvertToString(object value) => value != null ? StringFormatHelper.FormatYear((DateTime)value, this.UnknownString) : (string)null; + + public override object ConvertFromString(string value) + { + DateTime dateTime; + return StringParserHelper.TryParseDate(value, out dateTime) ? (object)dateTime : (object)null; + } + + public override bool IsValidInternal(string value) + { + int result; + return int.TryParse(value, out result) && result > 0 && result <= 9999 && (result <= 99 || result >= 1800); + } + } +} diff --git a/ZuneUI/ZuneDotNet.cs b/ZuneUI/ZuneDotNet.cs new file mode 100644 index 0000000..a3488c5 --- /dev/null +++ b/ZuneUI/ZuneDotNet.cs @@ -0,0 +1,38 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ZuneDotNet +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneUI +{ + public static class ZuneDotNet + { + public static string GetViewTrackUri(string trackId) => ZuneDotNet.GetViewUri(trackId, "track"); + + public static void ViewTrack(Guid trackId) => ZuneShell.DefaultInstance.Execute(ZuneDotNet.GetViewTrackUri(trackId.ToString()), (IDictionary)null); + + public static string GetViewAlbumUri(string albumId) => ZuneDotNet.GetViewUri(albumId, "album"); + + public static void ViewAlbum(Guid albumId) => ZuneShell.DefaultInstance.Execute(ZuneDotNet.GetViewAlbumUri(albumId.ToString()), (IDictionary)null); + + public static string GetViewArtistUri(string artistId) => ZuneDotNet.GetViewUri(artistId, "artist"); + + public static void ViewArtist(Guid artistId) => ZuneShell.DefaultInstance.Execute(ZuneDotNet.GetViewArtistUri(artistId.ToString()), (IDictionary)null); + + public static string GetViewPodcastSeriesUri(string podcastSeriesId) => ZuneDotNet.GetViewUri(podcastSeriesId, "podcastSeries"); + + public static void ViewPodcastSeries(Guid podcastSeriesId) => ZuneShell.DefaultInstance.Execute(ZuneDotNet.GetViewPodcastSeriesUri(podcastSeriesId.ToString()), (IDictionary)null); + + private static string GetViewUri(string id, string type) + { + string endPointUri = Microsoft.Zune.Service.Service.GetEndPointUri(Microsoft.Zune.Service.EServiceEndpointId.SEID_Lynx); + string str = FeatureEnablement.IsFeatureEnabled(Features.eSocial) ? "View" : "ViewUnsupportedMarket"; + return "Web\\" + UrlHelper.MakeUrlEx(endPointUri + "/redirect", nameof(type), type, nameof(id), id, "target", "web", "action", str); + } + } +} diff --git a/ZuneUI/ZunePage.cs b/ZuneUI/ZunePage.cs new file mode 100644 index 0000000..da1ca72 --- /dev/null +++ b/ZuneUI/ZunePage.cs @@ -0,0 +1,553 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ZunePage +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using System.Collections.Specialized; +using System.ComponentModel; + +namespace ZuneUI +{ + public class ZunePage : Page, IZunePage, IPage, INotifyPropertyChanged + { + private string _pageUI; + private string _pageUIPath; + private string _backgroundUI; + private string _bottomBarUI; + private string _overlayUI; + private Hashtable _overlayState; + private IDictionary _navigationArguments; + private string _navigationCommand; + private ICommandHandler _commandHandler; + private ComputerIconState _showComputerIcon; + private TransportControlStyle _transportStyle; + private PlaybackContext _playbackContext; + private Node _pivotPreference; + private Command _releaseCommand; + private Command _navigateAwayCommand; + private Command _navigateToCommand; + private object _temporaryPageState; + private BitVector32 _bits; + + public ZunePage() + { + this.SetBit(ZunePage.Bits.ShowDeviceIcon, true); + this.SetBit(ZunePage.Bits.ShowPlaylistIcon, true); + this.SetBit(ZunePage.Bits.ShowCDIcon, true); + this.SetBit(ZunePage.Bits.ShowBackArrow, true); + this.SetBit(ZunePage.Bits.NotificationAreaVisible, true); + this.SetBit(ZunePage.Bits.TransportControlsVisible, true); + this.SetBit(ZunePage.Bits.ShowLogo, true); + this.SetBit(ZunePage.Bits.ShowPivots, true); + this.SetBit(ZunePage.Bits.ShowSearch, true); + this.SetBit(ZunePage.Bits.ShowSettings, true); + this.SetBit(ZunePage.Bits.ShowAppBackground, true); + this.SetBit(ZunePage.Bits.TakeFocusOnNavigate, true); + this.SetBit(ZunePage.Bits.ShowNowPlayingBackgroundOnIdle, true); + this.SetBit(ZunePage.Bits.CanEnterCompactMode, true); + this.SetBit(ZunePage.Bits.NoStackPage, false); + this._showComputerIcon = ComputerIconState.Hide; + this._transportStyle = TransportControlStyle.Music; + this._playbackContext = PlaybackContext.None; + } + + public string UI + { + get => this._pageUI; + set + { + if (!(this._pageUI != value)) + return; + this._pageUI = value; + this.FirePropertyChanged(nameof(UI)); + } + } + + public string UIPath + { + get => this._pageUIPath; + set + { + if (!(this._pageUIPath != value)) + return; + this._pageUIPath = value; + this.FirePropertyChanged(nameof(UIPath)); + } + } + + public string BackgroundUI + { + get => this._backgroundUI; + set + { + if (!(this._backgroundUI != value)) + return; + this._backgroundUI = value; + this.FirePropertyChanged(nameof(BackgroundUI)); + } + } + + public string BottomBarUI + { + get => this._bottomBarUI; + set + { + if (!(this._bottomBarUI != value)) + return; + this._bottomBarUI = value; + this.FirePropertyChanged(nameof(BottomBarUI)); + } + } + + public string OverlayUI + { + get => this._overlayUI; + set + { + if (!(this._overlayUI != value)) + return; + this._overlayUI = value; + this.FirePropertyChanged(nameof(OverlayUI)); + } + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + { + this.UI = (string)null; + this.BackgroundUI = (string)null; + this.BottomBarUI = (string)null; + this.OverlayUI = (string)null; + } + base.OnDispose(disposing); + } + + public void SetOverlayState(string overlayKey, object state) + { + if (this._overlayState == null) + this._overlayState = new Hashtable(1); + this._overlayState[(object)overlayKey] = state; + } + + public object GetOverlayState(string overlayKey) => this._overlayState != null ? this._overlayState[(object)overlayKey] : (object)null; + + public IDictionary NavigationArguments + { + get => this._navigationArguments; + set => this._navigationArguments = value; + } + + public string NavigationCommand + { + get => this._navigationCommand; + set => this._navigationCommand = value; + } + + public ICommandHandler CommandHandler + { + get => this._commandHandler; + set => this._commandHandler = value; + } + + public bool ShowBackArrow + { + get => this.GetBit(ZunePage.Bits.ShowBackArrow); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShowBackArrow, value)) + return; + this.FirePropertyChanged(nameof(ShowBackArrow)); + } + } + + public bool ShowDeviceIcon + { + get => this.GetBit(ZunePage.Bits.ShowDeviceIcon); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShowDeviceIcon, value)) + return; + this.FirePropertyChanged(nameof(ShowDeviceIcon)); + } + } + + public bool ShowPlaylistIcon + { + get => this.GetBit(ZunePage.Bits.ShowPlaylistIcon); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShowPlaylistIcon, value)) + return; + this.FirePropertyChanged(nameof(ShowPlaylistIcon)); + } + } + + public bool ShowCDIcon + { + get => this.GetBit(ZunePage.Bits.ShowCDIcon); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShowCDIcon, value)) + return; + this.FirePropertyChanged(nameof(ShowCDIcon)); + } + } + + public bool ShowNowPlayingX + { + get => this.GetBit(ZunePage.Bits.ShowNowPlayingX); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShowNowPlayingX, value)) + return; + this.FirePropertyChanged(nameof(ShowNowPlayingX)); + } + } + + public bool ShowNowPlayingBackgroundOnIdle + { + get => this.GetBit(ZunePage.Bits.ShowNowPlayingBackgroundOnIdle); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShowNowPlayingBackgroundOnIdle, value)) + return; + this.FirePropertyChanged(nameof(ShowNowPlayingBackgroundOnIdle)); + } + } + + public bool CanEnterCompactMode + { + get => this.GetBit(ZunePage.Bits.CanEnterCompactMode); + set + { + if (!this.ChangeBit(ZunePage.Bits.CanEnterCompactMode, value)) + return; + this.FirePropertyChanged(nameof(CanEnterCompactMode)); + } + } + + public bool NoStackPage + { + get => this.GetBit(ZunePage.Bits.NoStackPage); + set + { + if (!this.ChangeBit(ZunePage.Bits.NoStackPage, value)) + return; + this.FirePropertyChanged(nameof(NoStackPage)); + } + } + + public bool NotificationAreaVisible + { + get => this.GetBit(ZunePage.Bits.NotificationAreaVisible); + set + { + if (!this.ChangeBit(ZunePage.Bits.NotificationAreaVisible, value)) + return; + this.FirePropertyChanged(nameof(NotificationAreaVisible)); + } + } + + public bool TransportControlsVisible + { + get => this.GetBit(ZunePage.Bits.TransportControlsVisible); + set + { + if (!this.ChangeBit(ZunePage.Bits.TransportControlsVisible, value)) + return; + this.FirePropertyChanged(nameof(TransportControlsVisible)); + } + } + + public bool AutoHideToolbars + { + get => this.GetBit(ZunePage.Bits.AutoHideToolbars); + set + { + if (!this.ChangeBit(ZunePage.Bits.AutoHideToolbars, value)) + return; + this.FirePropertyChanged(nameof(AutoHideToolbars)); + } + } + + public bool ShowAppBackground + { + get => this.GetBit(ZunePage.Bits.ShowAppBackground); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShowAppBackground, value)) + return; + this.FirePropertyChanged(nameof(ShowAppBackground)); + } + } + + public ComputerIconState ShowComputerIcon + { + get => this._showComputerIcon; + set + { + if (this._showComputerIcon == value) + return; + this._showComputerIcon = value; + this.FirePropertyChanged(nameof(ShowComputerIcon)); + } + } + + public bool ShowingVideoPreview + { + get => this.GetBit(ZunePage.Bits.ShowingVideoPreview); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShowingVideoPreview, value)) + return; + this.FirePropertyChanged(nameof(ShowingVideoPreview)); + } + } + + public bool ShowLogo + { + get => this.GetBit(ZunePage.Bits.ShowLogo); + set => this.SetBit(ZunePage.Bits.ShowLogo, value); + } + + public bool ShowPivots + { + get => this.GetBit(ZunePage.Bits.ShowPivots); + set => this.ChangeBit(ZunePage.Bits.ShowPivots, value); + } + + public bool ShowSearch + { + get => this.GetBit(ZunePage.Bits.ShowSearch); + set => this.SetBit(ZunePage.Bits.ShowSearch, value); + } + + public bool ShowSettings + { + get => this.GetBit(ZunePage.Bits.ShowSettings); + set => this.SetBit(ZunePage.Bits.ShowSettings, value); + } + + public bool TakeFocusOnNavigate + { + get => this.GetBit(ZunePage.Bits.TakeFocusOnNavigate); + set => this.SetBit(ZunePage.Bits.TakeFocusOnNavigate, value); + } + + public TransportControlStyle TransportControlStyle + { + get => this._transportStyle; + set + { + if (this._transportStyle == value) + return; + this._transportStyle = value; + this.FirePropertyChanged(nameof(TransportControlStyle)); + } + } + + public PlaybackContext PlaybackContext + { + get => this._playbackContext; + set + { + if (this._playbackContext == value) + return; + this._playbackContext = value; + this.FirePropertyChanged(nameof(PlaybackContext)); + } + } + + public Node PivotPreference + { + get => this._pivotPreference; + set => this._pivotPreference = value; + } + + public bool IsRootPage + { + get => this.GetBit(ZunePage.Bits.IsRootPage); + set => this.SetBit(ZunePage.Bits.IsRootPage, value); + } + + public object TemporaryPageState + { + get => this._temporaryPageState; + set + { + if (this._temporaryPageState == value) + return; + this._temporaryPageState = value; + this.FirePropertyChanged(nameof(TemporaryPageState)); + } + } + + public virtual void InvokeSettings() => Shell.SettingsFrame.Settings.Invoke(); + + public bool ShouldHandleBack + { + get => this.GetBit(ZunePage.Bits.ShouldHandleBack); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShouldHandleBack, value)) + return; + this.FirePropertyChanged(nameof(ShouldHandleBack)); + } + } + + public bool ShouldHandleEscape + { + get => this.GetBit(ZunePage.Bits.ShouldHandleEscape); + set + { + if (!this.ChangeBit(ZunePage.Bits.ShouldHandleEscape, value)) + return; + this.FirePropertyChanged(nameof(ShouldHandleEscape)); + } + } + + public event EventHandler BackHandled; + + public event EventHandler EscapeHandled; + + public virtual bool HandleBack() + { + if (!this.ShouldHandleBack) + return false; + if (this.BackHandled != null) + this.BackHandled((object)this, EventArgs.Empty); + this.FirePropertyChanged("BackHandled"); + return true; + } + + public virtual bool HandleEscape() + { + if (!this.ShouldHandleEscape) + return false; + if (this.EscapeHandled != null) + this.EscapeHandled((object)this, EventArgs.Empty); + this.FirePropertyChanged("EscapeHandled"); + return true; + } + + public virtual bool CanNavigateForwardTo(IZunePage destination) => true; + + public event EventHandler Refresh; + + public void RefreshPage() + { + if (this.Refresh != null) + this.Refresh((object)this, EventArgs.Empty); + this.FirePropertyChanged("Refresh"); + } + + public override void Release() + { + if (this._releaseCommand != null) + this._releaseCommand.Invoke(); + base.Release(); + } + + protected override void OnNavigatedToWorker() + { + if (this._navigateToCommand != null) + this._navigateToCommand.Invoke(); + base.OnNavigatedToWorker(); + Telemetry.Instance.ReportNavigation(this._pageUIPath, this._navigationArguments); + } + + protected override void OnNavigatedAwayWorker(IPage destination) + { + if (this._navigateAwayCommand != null) + this._navigateAwayCommand.Invoke(); + this.TemporaryPageState = (object)null; + base.OnNavigatedAwayWorker(destination); + } + + public override IPageState SaveAndRelease() + { + if (!this.NoStackPage) + return base.SaveAndRelease(); + this.Release(); + return (IPageState)null; + } + + public Command ReleaseCommand + { + get => this._releaseCommand; + set + { + if (this._releaseCommand == value) + return; + this._releaseCommand = value; + this.FirePropertyChanged(nameof(ReleaseCommand)); + } + } + + public Command NavigateToCommand + { + get => this._navigateToCommand; + set + { + if (this._navigateToCommand == value) + return; + this._navigateToCommand = value; + this.FirePropertyChanged(nameof(NavigateToCommand)); + } + } + + public Command NavigateAway + { + get => this._navigateAwayCommand; + set + { + if (this._navigateAwayCommand == value) + return; + this._navigateAwayCommand = value; + this.FirePropertyChanged("NavigateAwayCommand"); + } + } + + private bool GetBit(ZunePage.Bits lookupBit) => this._bits[(int)lookupBit]; + + private void SetBit(ZunePage.Bits changeBit, bool value) => this._bits[(int)changeBit] = value; + + private bool ChangeBit(ZunePage.Bits bit, bool value) + { + if (this._bits[(int)bit] == value) + return false; + this._bits[(int)bit] = value; + return true; + } + + private enum Bits : uint + { + ShowBackArrow = 1, + ShowDeviceIcon = 2, + ShowPlaylistIcon = 4, + ShowCDIcon = 8, + ShowNowPlayingX = 16, // 0x00000010 + NotificationAreaVisible = 32, // 0x00000020 + AutoHideToolbars = 64, // 0x00000040 + ShowAppBackground = 128, // 0x00000080 + IsRootPage = 256, // 0x00000100 + ShouldHandleBack = 512, // 0x00000200 + ShowLogo = 1024, // 0x00000400 + ShowPivots = 2048, // 0x00000800 + ShowSearch = 4096, // 0x00001000 + ShowSettings = 8192, // 0x00002000 + TakeFocusOnNavigate = 16384, // 0x00004000 + ShowingVideoPreview = 32768, // 0x00008000 + ShowNowPlayingBackgroundOnIdle = 65536, // 0x00010000 + ShouldHandleEscape = 131072, // 0x00020000 + CanEnterCompactMode = 262144, // 0x00040000 + NoStackPage = 524288, // 0x00080000 + TransportControlsVisible = 1048576, // 0x00100000 + } + } +} diff --git a/ZuneUI/ZuneShell.cs b/ZuneUI/ZuneShell.cs new file mode 100644 index 0000000..cc3b446 --- /dev/null +++ b/ZuneUI/ZuneShell.cs @@ -0,0 +1,190 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ZuneShell +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.ComponentModel; + +namespace ZuneUI +{ + public class ZuneShell : ModelItem + { + public Category DeferredNavigateCategory; + public Node DeferredNavigateNode; + private static ZuneShell s_defaultInstance; + private PageStack _pageStack; + private Command _navigateBackCommand; + private ICommandHandler _commandHandler; + private Management _management; + private int _navigationsToPagePending; + private bool _navigationLocked; + private object thisLock = new object(); + + public ZuneShell() + { + this._pageStack = new PageStack((IModelItemOwner)this); + this._pageStack.PropertyChanged += new PropertyChangedEventHandler(this.OnPageStackPropertyChanged); + this._navigateBackCommand = new Command((IModelItemOwner)this, Shell.LoadString(StringId.IDS_NAVIGATE_BACK), new EventHandler(this.OnClickNavigateBack)); + this._pageStack.MaximumStackSize = 1024U; + this._pageStack.NavigateToPage((IPage)new StartupPage()); + ZuneShell.DefaultInstance = this; + } + + protected override void OnDispose(bool disposing) + { + if (disposing) + this.DisposeManagement(); + base.OnDispose(disposing); + if (!disposing || ZuneShell.DefaultInstance != this) + return; + ZuneShell.DefaultInstance = (ZuneShell)null; + } + + public Command NavigateBackCommand => this._navigateBackCommand; + + private void OnPageStackPropertyChanged(object sender, PropertyChangedEventArgs args) + { + string propertyName = args.PropertyName; + if (!(propertyName == "CurrentPage") && !(propertyName == "CanNavigateBack") && (!(propertyName == "LastNavigationDirection") && !(propertyName == "MaximumStackSize"))) + return; + this.FirePropertyChanged(propertyName); + if (!(propertyName == "CurrentPage") && !(propertyName == "CanNavigateBack")) + return; + this._navigateBackCommand.Available = this.CanNavigateBack && (this.CurrentPage.ShowBackArrow || this.CurrentPage.ShowComputerIcon != ComputerIconState.Hide || this.CurrentPage.ShowNowPlayingX); + } + + private void OnClickNavigateBack(object sender, EventArgs args) + { + SQMLog.Log(SQMDataId.BackClicks, 1); + this.NavigateBack(); + } + + public int MaximumStackSize + { + get => (int)this._pageStack.MaximumStackSize; + set => this._pageStack.MaximumStackSize = value >= 0 ? (uint)value : throw new ArgumentOutOfRangeException(nameof(value)); + } + + public ZunePage CurrentPage => (ZunePage)this._pageStack.CurrentPage; + + public bool CanNavigateBack => this._pageStack.CanNavigateBack; + + public bool NavigationLocked + { + get => this._navigationLocked; + set + { + if (this._navigationLocked == value) + return; + this._navigationLocked = value; + this.FirePropertyChanged(nameof(NavigationLocked)); + } + } + + public bool BlockedByNavigationLock + { + get => true; + set => this.FirePropertyChanged(nameof(BlockedByNavigationLock)); + } + + public NavigationDirection LastNavigationDirection => this._pageStack.LastNavigationDirection; + + public ICommandHandler CommandHandler + { + get => this._commandHandler; + set + { + if (this._commandHandler == value) + return; + this._commandHandler = value; + this.FirePropertyChanged(nameof(CommandHandler)); + } + } + + public static ZuneShell DefaultInstance + { + get => ZuneShell.s_defaultInstance; + private set => ZuneShell.s_defaultInstance = ZuneShell.s_defaultInstance == null || value == null ? value : throw new InvalidOperationException("Should only have one static shell instance."); + } + + public bool NavigationsPending => this._navigationsToPagePending > 0; + + public void NavigateToPage(ZunePage page) + { + lock (this.thisLock) + ++this._navigationsToPagePending; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredNavigateToPage), (object)page); + } + + private void DeferredNavigateToPage(object args) + { + ZunePage zunePage = (ZunePage)args; + if (this.CurrentPage == null || this.CurrentPage.CanNavigateForwardTo((IZunePage)zunePage)) + this._pageStack.NavigateToPage((IPage)zunePage); + else + zunePage.Release(); + lock (this.thisLock) + --this._navigationsToPagePending; + } + + public void NavigateBack() => this.NavigateBack(false); + + public void NavigateBack(bool bypassPage) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredNavigateBack), (object)bypassPage); + + private void DeferredNavigateBack(object args) + { + if (!(bool)args && this.CurrentPage != null && this.CurrentPage.HandleBack()) + return; + this._pageStack.NavigateBack(); + } + + public void Execute(string command, IDictionary commandArguments) + { + if (this._commandHandler == null) + throw new InvalidOperationException("No CommandHandler has been registered. Unable to resolve shell command: " + command); + this._commandHandler.Execute(command, commandArguments); + } + + public void LaunchHelp() => this.Execute(InternetConnection.Instance.IsConnected ? "Web\\" + CultureHelper.GetHelpUrl() : "Help\\" + Shell.LoadString(StringId.IDS_ZUNECLIENT_LOCALE) + "\\help.htm", (IDictionary)null); + + public Management Management + { + get + { + if (this._management == null && ZuneShell.DefaultInstance != null) + this._management = new Management(); + return this._management; + } + } + + public void DisposeManagement() + { + if (this._management == null) + return; + this._management.Dispose(); + this._management = (Management)null; + } + + public static MediaType MapStringToMediaType(string typeName) => (MediaType)LibraryDataProvider.NameToMediaType(typeName); + + public static MediaType MapIntToMediaType(int mediaType) => (MediaType)mediaType; + + public static int MapMediaTypeToInt(MediaType mediaType) => (int)mediaType; + + public static EMediaTypes MapMediaTypeToEMediaTypes(MediaType mediaType) => (EMediaTypes)mediaType; + + public static MediaType GetMediaTypeFromMedia(object media) + { + EMediaTypes mediaType = EMediaTypes.eMediaTypeInvalid; + if (media is IDatabaseMedia) + ((IDatabaseMedia)media).GetMediaIdAndType(out int _, out mediaType); + return (MediaType)mediaType; + } + } +} diff --git a/ZuneUI/ZuneTagHelper.cs b/ZuneUI/ZuneTagHelper.cs new file mode 100644 index 0000000..0a7809d --- /dev/null +++ b/ZuneUI/ZuneTagHelper.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ZuneTagHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text.RegularExpressions; + +namespace ZuneUI +{ + public static class ZuneTagHelper + { + private static int s_maxLength = 15; + private static Regex s_zuneTagRegex = new Regex("^[A-Z]( ?[A-Z0-9]){0,14}$", RegexOptions.IgnoreCase); + + public static bool IsValid(string zuneTag) => !string.IsNullOrEmpty(zuneTag) && ZuneTagHelper.s_zuneTagRegex.IsMatch(zuneTag); + + public static int MaxLength => ZuneTagHelper.s_maxLength; + } +} diff --git a/ZuneUI/ZuneTagPropertyDescriptor.cs b/ZuneUI/ZuneTagPropertyDescriptor.cs new file mode 100644 index 0000000..2a695a2 --- /dev/null +++ b/ZuneUI/ZuneTagPropertyDescriptor.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ZuneTagPropertyDescriptor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ZuneTagPropertyDescriptor : PropertyDescriptor + { + public ZuneTagPropertyDescriptor(string name, string multiValueString, string unknownString) + : base(name, multiValueString, unknownString, ZuneTagHelper.MaxLength, true) + { + } + + public override bool IsValidInternal(string value) => ZuneTagHelper.IsValid(value); + } +} diff --git a/ZuneUI/ZuneTagPropertyEditor.cs b/ZuneUI/ZuneTagPropertyEditor.cs new file mode 100644 index 0000000..3914ec4 --- /dev/null +++ b/ZuneUI/ZuneTagPropertyEditor.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ZuneTagPropertyEditor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneUI +{ + public class ZuneTagPropertyEditor : WizardPropertyEditor + { + private static PropertyDescriptor[] s_dataProviderProperties; + public static PropertyDescriptor s_ZuneTag = (PropertyDescriptor)new ZuneTagPropertyDescriptor(nameof(ZuneTag), string.Empty, string.Empty); + + public override PropertyDescriptor[] PropertyDescriptors + { + get + { + if (ZuneTagPropertyEditor.s_dataProviderProperties == null) + ZuneTagPropertyEditor.s_dataProviderProperties = new PropertyDescriptor[1] + { + ZuneTagPropertyEditor.s_ZuneTag + }; + return ZuneTagPropertyEditor.s_dataProviderProperties; + } + } + + public static PropertyDescriptor ZuneTag => ZuneTagPropertyEditor.s_ZuneTag; + } +} diff --git a/ZuneUI/ZuneTagStep.cs b/ZuneUI/ZuneTagStep.cs new file mode 100644 index 0000000..2095e2d --- /dev/null +++ b/ZuneUI/ZuneTagStep.cs @@ -0,0 +1,116 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ZuneTagStep +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneUI +{ + public class ZuneTagStep : AccountManagementStep + { + private IList _tagSuggestions; + private Dictionary _errorMappings; + + public ZuneTagStep(Wizard owner, AccountManagementWizardState state, bool parentAccount) + : base(owner, state, parentAccount) + { + this.Description = Shell.LoadString(StringId.IDS_ACCOUNT_CREATION_ZUNE_TAG_HEADER); + this.Initialize((WizardPropertyEditor)new ZuneTagPropertyEditor()); + } + + public override string UI => "res://ZuneShellResources!AccountInfo.uix#ZuneTagStep"; + + public IList TagSuggestions + { + get => this._tagSuggestions; + private set + { + if (this._tagSuggestions == value) + return; + this._tagSuggestions = value; + this.FirePropertyChanged(nameof(TagSuggestions)); + } + } + + public string EmailAddress => this.State != null ? this.State.GetEmailAddress() : string.Empty; + + public override bool IsEnabled + { + get + { + bool flag = base.IsEnabled; + if (flag) + flag = this.State.PassportPasswordStep.CanCreateAccount; + return flag; + } + } + + internal override Dictionary ErrorPropertyMappings + { + get + { + if (this._errorMappings == null) + { + this._errorMappings = new Dictionary(3); + this._errorMappings.Add(HRESULT._ZEST_E_ACCOUNT_ZUNETAG_OCCUPIED.Int, (PropertyDescriptor)null); + this._errorMappings.Add(HRESULT._ZEST_E_INVALID_ARG_ZUNETAG.Int, (PropertyDescriptor)null); + this._errorMappings.Add(HRESULT._ZEST_E_ZUNETAG_OFFENSIVE.Int, (PropertyDescriptor)null); + } + return this._errorMappings; + } + } + + protected override void OnActivate() + { + this.ServiceDeactivationRequestsDone = false; + base.OnActivate(); + } + + internal override bool OnMovingNext() + { + string uncommittedValue = this.GetUncommittedValue(ZuneTagPropertyEditor.ZuneTag) as string; + string committedValue = this.GetCommittedValue(ZuneTagPropertyEditor.ZuneTag) as string; + if (uncommittedValue == committedValue || this.TagSuggestions != null && this.TagSuggestions.Contains((object)uncommittedValue)) + { + this.TagSuggestions = (IList)null; + this.ServiceDeactivationRequestsDone = true; + } + if (this.ServiceDeactivationRequestsDone) + { + if (this.TagSuggestions == null || this.TagSuggestions.Count == 0) + return base.OnMovingNext(); + this.ServiceDeactivationRequestsDone = false; + return false; + } + ZuneTagStep.ServiceData serviceData; + serviceData.ZuneTag = uncommittedValue; + serviceData.CountryCode = this.State.BasicAccountInfoStep.SelectedCountry; + this.StartDeactivationRequests((object)serviceData); + return false; + } + + protected override void OnStartDeactivationRequests(object state) => this.EndDeactivationRequests((object)this.ValidateUniqueZuneTag((ZuneTagStep.ServiceData)state)); + + protected override void OnEndDeactivationRequests(object args) => this.TagSuggestions = args as IList; + + private IList ValidateUniqueZuneTag(ZuneTagStep.ServiceData serviceData) + { + ServiceError serviceError = (ServiceError)null; + IList suggestedNames = (IList)null; + HRESULT hr = this.State.AccountManagement.ReserveZuneTag(serviceData.ZuneTag, serviceData.CountryCode, out suggestedNames, out serviceError); + if (hr.IsError && hr != HRESULT._ZEST_E_ACCOUNT_ZUNETAG_OCCUPIED) + this.SetError(hr, serviceError); + return suggestedNames; + } + + private struct ServiceData + { + public string ZuneTag; + public string CountryCode; + } + } +} diff --git a/ZuneUI/ZuneWebHost.cs b/ZuneUI/ZuneWebHost.cs new file mode 100644 index 0000000..398091f --- /dev/null +++ b/ZuneUI/ZuneWebHost.cs @@ -0,0 +1,152 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneUI.ZuneWebHost +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; + +namespace ZuneUI +{ + public class ZuneWebHost : ModelItem + { + private static int s_partnerServiceUnknownError = HRESULT._ZEST_E_PARTNER_SERVICE_UNKNOWN_ERROR.Int; + private WebHostNavigationResult m_result; + private string m_currentUrl; + private string m_initialUrl; + private string m_successUrl; + private string m_failureUrl; + private long m_childHwnd; + private Microsoft.Zune.Util.ZuneWebHost m_host; + private NavErrorData m_navErrorData; + + public ZuneWebHost() => this.m_host = Microsoft.Zune.Util.ZuneWebHost.Instance; + + public bool Initialize(long hWndHost, int width, int height) + { + this.m_host.SetNavigationCompleteHandler((NavigationCompleteHandler)(data => Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.CurrentUrl = data; + if (!string.IsNullOrEmpty(this.SuccessUrl) && this.SuccessUrl.Length <= this.m_currentUrl.Length && string.Compare(this.SuccessUrl, this.m_currentUrl.Substring(0, this.SuccessUrl.Length), false) == 0) + { + this.ResponseToken = string.Empty; + this.NavResult = WebHostNavigationResult.SuccessUrl; + } + else + { + if (string.IsNullOrEmpty(this.FailureUrl) || this.FailureUrl.Length > this.m_currentUrl.Length || string.Compare(this.FailureUrl, this.m_currentUrl.Substring(0, this.FailureUrl.Length), false) != 0) + return; + this.NavResult = WebHostNavigationResult.FailureUrl; + } + }, (object)data))); + this.m_host.SetNavigationErrorHandler((NavigationErrorHandler)((errorUrl, errorCode) => + { + NavErrorData data = new NavErrorData(errorUrl, errorCode); + Application.DeferredInvoke((DeferredInvokeHandler)delegate + { + this.NavigationError = data; + }, (object)data); + })); + long num = this.m_host.Initialize(this.InitialUrl, hWndHost, width, height); + if (num == 0L) + { + this.NavigationError = new NavErrorData(this.InitialUrl, HRESULT._ZEST_E_PARTNER_SERVICE_UNKNOWN_ERROR.Int); + this.NavResult = WebHostNavigationResult.FailureUrl; + } + else + this.ChildHwnd = num; + return num != 0L; + } + + public bool SetSize(long hWndHost, int width, int height) => this.m_host.SetSize(hWndHost, width, height); + + public long ChildHwnd + { + get => this.m_childHwnd; + set + { + if (this.m_childHwnd == value) + return; + this.m_childHwnd = value; + this.FirePropertyChanged(nameof(ChildHwnd)); + } + } + + public string CurrentUrl + { + get => this.m_currentUrl; + set + { + if (string.Compare(value, this.m_currentUrl, false) == 0) + return; + this.m_currentUrl = value; + this.FirePropertyChanged(nameof(CurrentUrl)); + } + } + + public string ResponseToken { get; private set; } + + public NavErrorData NavigationError + { + get => this.m_navErrorData; + set + { + if (this.m_navErrorData != null && this.m_navErrorData.Equals(value)) + return; + this.m_navErrorData = value; + this.FirePropertyChanged(nameof(NavigationError)); + } + } + + public WebHostNavigationResult NavResult + { + get => this.m_result; + set + { + if (this.m_result == value) + return; + this.m_result = value; + this.FirePropertyChanged(nameof(NavResult)); + } + } + + public string InitialUrl + { + get => this.m_initialUrl; + set + { + if (string.Compare(value, this.m_initialUrl, false) == 0) + return; + this.m_initialUrl = value; + this.FirePropertyChanged(nameof(InitialUrl)); + } + } + + public string SuccessUrl + { + get => this.m_successUrl; + set + { + if (string.Compare(value, this.m_successUrl, false) == 0) + return; + this.m_successUrl = value; + this.FirePropertyChanged(nameof(SuccessUrl)); + } + } + + public string FailureUrl + { + get => this.m_failureUrl; + set + { + if (string.Compare(value, this.m_failureUrl, false) == 0) + return; + this.m_failureUrl = value; + this.FirePropertyChanged(nameof(FailureUrl)); + } + } + + public int PartnerServiceUnknownError => ZuneWebHost.s_partnerServiceUnknownError; + } +} diff --git a/ZuneXml/Album.cs b/ZuneXml/Album.cs new file mode 100644 index 0000000..7d58aca --- /dev/null +++ b/ZuneXml/Album.cs @@ -0,0 +1,144 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Album +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class Album : Media + { + private int _dbMediaId = -1; + + internal bool CanPurchaseMP3 => this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out Right _); + + internal bool CanPurchase + { + get + { + Right offer; + return this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer) || this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer); + } + } + + internal int PointsPrice + { + get + { + int num = -1; + Right offer; + if (this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer)) + num = offer.PointsPrice; + else if (this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer)) + num = offer.PointsPrice; + return num; + } + } + + internal bool InCollection + { + get + { + bool flag = false; + if (this.Id != Guid.Empty) + flag = ZuneApplication.Service.InVisibleCollection(this.Id, EContentType.MusicAlbum, out int _); + return flag; + } + } + + internal int LibraryId + { + get + { + int dbMediaId = -1; + if (this.Id != Guid.Empty) + { + ZuneApplication.Service.InVisibleCollection(this.Id, EContentType.MusicAlbum, out dbMediaId); + if (dbMediaId == -1) + dbMediaId = this._dbMediaId; + } + return dbMediaId; + } + set + { + if (this._dbMediaId == value) + return; + this._dbMediaId = value; + this.FirePropertyChanged(nameof(LibraryId)); + } + } + + internal static XmlDataProviderObject ConstructAlbumObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Album(owner, objectTypeCookie); + } + + internal Album(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal Genre PrimaryGenre => (Genre)base.GetProperty(nameof(PrimaryGenre)); + + internal DateTime ReleaseDate => (DateTime)base.GetProperty(nameof(ReleaseDate)); + + internal bool Explicit => (bool)base.GetProperty(nameof(Explicit)); + + internal bool Actionable => (bool)base.GetProperty(nameof(Actionable)); + + internal bool Premium => (bool)base.GetProperty(nameof(Premium)); + + internal string Label => (string)base.GetProperty(nameof(Label)); + + internal string ReviewLink => (string)base.GetProperty(nameof(ReviewLink)); + + internal IList Genres => (IList)base.GetProperty(nameof(Genres)); + + internal IList Tracks => (IList)base.GetProperty(nameof(Tracks)); + + internal IList MusicVideos => (IList)base.GetProperty(nameof(MusicVideos)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override string SortTitle => (string)base.GetProperty(nameof(SortTitle)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override MiniArtist PrimaryArtist => (MiniArtist)base.GetProperty(nameof(PrimaryArtist)); + + internal override Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + internal override double Popularity => (double)base.GetProperty(nameof(Popularity)); + + internal override MediaRights Rights => (MediaRights)base.GetProperty(nameof(Rights)); + + internal override IList Artists => (IList)base.GetProperty(nameof(Artists)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "PointsPrice": + return (object)this.PointsPrice; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "InCollection": + return (object)this.InCollection; + case "LibraryId": + return (object)this.LibraryId; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/App.cs b/ZuneXml/App.cs new file mode 100644 index 0000000..e0035f0 --- /dev/null +++ b/ZuneXml/App.cs @@ -0,0 +1,100 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.App +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class App : MiniMedia + { + internal double Price + { + get + { + Right right = this.SelectBestOfferRight(); + return right == null ? 0.0 : right.CurrencyPrice; + } + } + + internal string DisplayPrice => this.SelectBestOfferRight()?.DisplayPrice; + + internal string DisplayPriceFull => this.Rights.GetOfferRight(MediaRightsEnum.Purchase, ClientTypeEnum.WindowsPhone, PriceTypeEnum.Currency)?.DisplayPrice; + + internal string DisplayPriceTrial => this.Rights.GetOfferRight(MediaRightsEnum.PurchaseTrial, ClientTypeEnum.WindowsPhone, PriceTypeEnum.Currency)?.DisplayPrice; + + internal bool CanDownload => this.Rights.HasRights(MediaRightsEnum.Purchase, ClientTypeEnum.Zune) || this.Rights.HasRights(MediaRightsEnum.Download, ClientTypeEnum.Zune); + + internal bool CanPurchase => this.CanPurchaseFull || this.CanPurchaseTrial; + + internal bool CanPurchaseFull => this.Rights.HasOfferRights(MediaRightsEnum.Purchase, ClientTypeEnum.WindowsPhone, PriceTypeEnum.Currency); + + internal bool CanPurchaseTrial => this.Rights.HasOfferRights(MediaRightsEnum.PurchaseTrial, ClientTypeEnum.WindowsPhone, PriceTypeEnum.Currency); + + private Right SelectBestOfferRight() => this.Rights.GetOfferRight(MediaRightsEnum.Purchase, ClientTypeEnum.WindowsPhone, PriceTypeEnum.Currency) ?? this.Rights.GetOfferRight(MediaRightsEnum.PurchaseTrial, ClientTypeEnum.WindowsPhone, PriceTypeEnum.Currency); + + internal static XmlDataProviderObject ConstructAppObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new App(owner, objectTypeCookie); + } + + internal App(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string SortTitle => (string)base.GetProperty(nameof(SortTitle)); + + internal Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + internal DateTime ReleaseDate => (DateTime)base.GetProperty(nameof(ReleaseDate)); + + internal string GenreName => (string)base.GetProperty(nameof(GenreName)); + + internal string Version => (string)base.GetProperty(nameof(Version)); + + internal string Author => (string)base.GetProperty(nameof(Author)); + + internal string Publisher => (string)base.GetProperty(nameof(Publisher)); + + internal string ShortDescription => (string)base.GetProperty(nameof(ShortDescription)); + + internal float AverageRating => (float)base.GetProperty(nameof(AverageRating)); + + internal AppMediaRights Rights => (AppMediaRights)base.GetProperty(nameof(Rights)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Price": + return (object)this.Price; + case "DisplayPrice": + return (object)this.DisplayPrice; + case "DisplayPriceFull": + return (object)this.DisplayPriceFull; + case "DisplayPriceTrial": + return (object)this.DisplayPriceTrial; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFull": + return (object)this.CanPurchaseFull; + case "CanPurchaseTrial": + return (object)this.CanPurchaseTrial; + case "CanDownload": + return (object)this.CanDownload; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/AppCapabilities.cs b/ZuneXml/AppCapabilities.cs new file mode 100644 index 0000000..9a65f57 --- /dev/null +++ b/ZuneXml/AppCapabilities.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppCapabilities +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneXml +{ + internal class AppCapabilities : XmlDataProviderObject + { + internal static XmlDataProviderObject ConstructAppCapabilitiesObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new AppCapabilities(owner, objectTypeCookie); + } + + internal AppCapabilities(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal IList Items => (IList)this.GetProperty(nameof(Items)); + } +} diff --git a/ZuneXml/AppCapability.cs b/ZuneXml/AppCapability.cs new file mode 100644 index 0000000..6ee9731 --- /dev/null +++ b/ZuneXml/AppCapability.cs @@ -0,0 +1,73 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppCapability +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class AppCapability : XmlDataProviderObject + { + private DisclosureEnum _disclosureEnum = DisclosureEnum.Invalid; + + public bool NeedDisclosure => this.DisclosureEnum == DisclosureEnum.Disclose || this.DisclosureEnum == DisclosureEnum.DiscloseAndPrompt; + + public bool NeedPrompt => this.DisclosureEnum == DisclosureEnum.Prompt || this.DisclosureEnum == DisclosureEnum.DiscloseAndPrompt; + + internal DisclosureEnum DisclosureEnum + { + get => this._disclosureEnum; + set + { + if (this._disclosureEnum == value) + return; + this._disclosureEnum = value; + this.FirePropertyChanged(nameof(DisclosureEnum)); + } + } + + public override void SetProperty(string propertyName, object value) + { + switch (propertyName) + { + case "DisclosureType": + this.DisclosureEnum = SchemaHelper.ToDisclosureEnum((string)value); + break; + } + base.SetProperty(propertyName, value); + } + + internal static XmlDataProviderObject ConstructAppCapabilityObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new AppCapability(owner, objectTypeCookie); + } + + internal AppCapability(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string Id => (string)base.GetProperty(nameof(Id)); + + internal string Description => (string)base.GetProperty(nameof(Description)); + + internal string DisclosureType => (string)base.GetProperty(nameof(DisclosureType)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "NeedDisclosure": + return (object)this.NeedDisclosure; + case "NeedPrompt": + return (object)this.NeedPrompt; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/AppData.cs b/ZuneXml/AppData.cs new file mode 100644 index 0000000..1042285 --- /dev/null +++ b/ZuneXml/AppData.cs @@ -0,0 +1,66 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppData +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class AppData : App + { + internal static XmlDataProviderObject ConstructAppDataObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new AppData(owner, objectTypeCookie); + } + + internal AppData(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string Copyright => (string)base.GetProperty(nameof(Copyright)); + + internal string Description => (string)base.GetProperty(nameof(Description)); + + internal IList Screenshots => (IList)base.GetProperty(nameof(Screenshots)); + + internal IList Genres => (IList)base.GetProperty(nameof(Genres)); + + internal AppCapabilities Capabilities => (AppCapabilities)base.GetProperty(nameof(Capabilities)); + + internal Guid BackgroundImageId => (Guid)base.GetProperty(nameof(BackgroundImageId)); + + internal Guid RatingImageId => (Guid)base.GetProperty(nameof(RatingImageId)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Price": + return (object)this.Price; + case "DisplayPrice": + return (object)this.DisplayPrice; + case "DisplayPriceFull": + return (object)this.DisplayPriceFull; + case "DisplayPriceTrial": + return (object)this.DisplayPriceTrial; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFull": + return (object)this.CanPurchaseFull; + case "CanPurchaseTrial": + return (object)this.CanPurchaseTrial; + case "CanDownload": + return (object)this.CanDownload; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/AppDetailsQueryHelper.cs b/ZuneXml/AppDetailsQueryHelper.cs new file mode 100644 index 0000000..2b7855c --- /dev/null +++ b/ZuneXml/AppDetailsQueryHelper.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppDetailsQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text; + +namespace ZuneXml +{ + internal class AppDetailsQueryHelper : CatalogServiceQueryHelper + { + internal static AppDetailsQueryHelper ConstructAppDetailsQueryHelper( + ZuneServiceQuery query) + { + return new AppDetailsQueryHelper(query); + } + + internal AppDetailsQueryHelper(ZuneServiceQuery query) + : base(query) + { + } + + protected override void AppendStuffAfterRepresentation( + StringBuilder requestUri, + ref bool fFirst) + { + base.AppendStuffAfterRepresentation(requestUri, ref fFirst); + string property = (string)this.Query.GetProperty("Version"); + if (string.IsNullOrEmpty(property)) + return; + ZuneServiceQueryHelper.AppendParam(requestUri, "version", property, ref fFirst); + } + } +} diff --git a/ZuneXml/AppGenre.cs b/ZuneXml/AppGenre.cs new file mode 100644 index 0000000..8d53dd5 --- /dev/null +++ b/ZuneXml/AppGenre.cs @@ -0,0 +1,31 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppGenre +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class AppGenre : Category + { + internal static XmlDataProviderObject ConstructAppGenreObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new AppGenre(owner, objectTypeCookie); + } + + internal AppGenre(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal bool IsRoot => (bool)this.GetProperty(nameof(IsRoot)); + + internal override string Id => (string)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/AppGenresQueryHelper.cs b/ZuneXml/AppGenresQueryHelper.cs new file mode 100644 index 0000000..8cd5e1b --- /dev/null +++ b/ZuneXml/AppGenresQueryHelper.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppGenresQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneXml +{ + internal class AppGenresQueryHelper : CatalogServiceQueryHelper + { + internal static AppGenresQueryHelper ConstructAppGenresQueryHelper( + ZuneServiceQuery query) + { + return new AppGenresQueryHelper(query); + } + + internal AppGenresQueryHelper(ZuneServiceQuery query) + : base(query) + { + } + + internal override bool OnQueryFilterDataProviderObject(XmlDataProviderObject dataObject) + { + bool flag = false; + if (dataObject.GetProperty("Id") is string property && property.Equals("apps.games", StringComparison.OrdinalIgnoreCase)) + flag = true; + return flag; + } + } +} diff --git a/ZuneXml/AppMediaRights.cs b/ZuneXml/AppMediaRights.cs new file mode 100644 index 0000000..224f5e7 --- /dev/null +++ b/ZuneXml/AppMediaRights.cs @@ -0,0 +1,36 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppMediaRights +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class AppMediaRights : MediaRights + { + internal static XmlDataProviderObject ConstructAppMediaRightsObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new AppMediaRights(owner, objectTypeCookie); + } + + internal AppMediaRights(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Languages": + return (object)this.Languages; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/AppReleaseDateComparer.cs b/ZuneXml/AppReleaseDateComparer.cs new file mode 100644 index 0000000..b0c720a --- /dev/null +++ b/ZuneXml/AppReleaseDateComparer.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppReleaseDateComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneXml +{ + public class AppReleaseDateComparer : PropertyComparer + { + public AppReleaseDateComparer() + : base(new Converter(AppReleaseDateComparer.GetReleaseDate), true) + { + } + + private static DateTime GetReleaseDate(object o) => !(o is App app) ? DateTime.MinValue : app.ReleaseDate; + } +} diff --git a/ZuneXml/AppScreenshot.cs b/ZuneXml/AppScreenshot.cs new file mode 100644 index 0000000..5a6347b --- /dev/null +++ b/ZuneXml/AppScreenshot.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppScreenshot +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class AppScreenshot : Thumbnail + { + internal static XmlDataProviderObject ConstructAppScreenshotObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new AppScreenshot(owner, objectTypeCookie); + } + + internal AppScreenshot(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override Guid ImageId => (Guid)this.GetProperty(nameof(ImageId)); + + internal override string Id => (string)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + + internal override string SortTitle => (string)this.GetProperty(nameof(SortTitle)); + } +} diff --git a/ZuneXml/AppTitleComparer.cs b/ZuneXml/AppTitleComparer.cs new file mode 100644 index 0000000..4483f52 --- /dev/null +++ b/ZuneXml/AppTitleComparer.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AppTitleComparer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; + +namespace ZuneXml +{ + public class AppTitleComparer : PropertyComparer + { + public AppTitleComparer() + : base(new Converter(AppTitleComparer.GetSortTitle), false) + { + } + + private static string GetSortTitle(object o) => !(o is App app) ? (string)null : app.SortTitle; + } +} diff --git a/ZuneXml/Artist.cs b/ZuneXml/Artist.cs new file mode 100644 index 0000000..2fc14b2 --- /dev/null +++ b/ZuneXml/Artist.cs @@ -0,0 +1,55 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Artist +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class Artist : XmlDataProviderObject + { + internal static XmlDataProviderObject ConstructArtistObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Artist(owner, objectTypeCookie); + } + + internal Artist(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal Guid Id => (Guid)this.GetProperty(nameof(Id)); + + internal string Title => (string)this.GetProperty(nameof(Title)); + + internal string SortTitle => (string)this.GetProperty(nameof(SortTitle)); + + internal Guid ImageId => (Guid)this.GetProperty(nameof(ImageId)); + + internal double Popularity => (double)this.GetProperty(nameof(Popularity)); + + internal bool IsVariousArtist => (bool)this.GetProperty(nameof(IsVariousArtist)); + + internal string BiographyLink => (string)this.GetProperty(nameof(BiographyLink)); + + internal int PlayCount => (int)this.GetProperty(nameof(PlayCount)); + + internal Genre PrimaryGenre => (Genre)this.GetProperty(nameof(PrimaryGenre)); + + internal IList Genres => (IList)this.GetProperty(nameof(Genres)); + + internal IList Moods => (IList)this.GetProperty(nameof(Moods)); + + internal Guid AlbumImageId => (Guid)this.GetProperty(nameof(AlbumImageId)); + + internal Guid BackgroundImageId => (Guid)this.GetProperty(nameof(BackgroundImageId)); + + internal bool HasRadioChannel => (bool)this.GetProperty(nameof(HasRadioChannel)); + } +} diff --git a/ZuneXml/ArtistEvent.cs b/ZuneXml/ArtistEvent.cs new file mode 100644 index 0000000..1ac9fff --- /dev/null +++ b/ZuneXml/ArtistEvent.cs @@ -0,0 +1,40 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ArtistEvent +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class ArtistEvent : XmlDataProviderObject + { + internal static XmlDataProviderObject ConstructArtistEventObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ArtistEvent(owner, objectTypeCookie); + } + + internal ArtistEvent(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string Type => (string)this.GetProperty(nameof(Type)); + + internal string WebLinkUrl => (string)this.GetProperty(nameof(WebLinkUrl)); + + internal DateTime Date => (DateTime)this.GetProperty(nameof(Date)); + + internal string Venue => (string)this.GetProperty(nameof(Venue)); + + internal string City => (string)this.GetProperty(nameof(City)); + + internal string State => (string)this.GetProperty(nameof(State)); + + internal string Country => (string)this.GetProperty(nameof(Country)); + } +} diff --git a/ZuneXml/ArtistEventList.cs b/ZuneXml/ArtistEventList.cs new file mode 100644 index 0000000..44151b8 --- /dev/null +++ b/ZuneXml/ArtistEventList.cs @@ -0,0 +1,66 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ArtistEventList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneXml +{ + internal class ArtistEventList : ListResult + { + protected IList _concerts; + + internal IList Concerts + { + get + { + if (this._concerts == null) + this._concerts = this.FilterConcerts(); + return this._concerts; + } + } + + private IList FilterConcerts() + { + IList list = (IList)null; + if (this.Items != null && this.Items.Count > 0) + { + list = (IList)new ArrayList(this.Items.Count); + foreach (ArtistEvent artistEvent in (IEnumerable)this.Items) + { + if (artistEvent.Type == "Concert") + list.Add((object)artistEvent); + } + } + return list; + } + + internal static XmlDataProviderObject ConstructArtistEventListObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ArtistEventList(owner, objectTypeCookie); + } + + internal ArtistEventList(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override IList Items => (IList)base.GetProperty(nameof(Items)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Concerts": + return (object)this.Concerts; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/AudioEncodingEnum.cs b/ZuneXml/AudioEncodingEnum.cs new file mode 100644 index 0000000..e13b448 --- /dev/null +++ b/ZuneXml/AudioEncodingEnum.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.AudioEncodingEnum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal enum AudioEncodingEnum + { + None, + MP3, + WMA, + } +} diff --git a/ZuneXml/BadgeData.cs b/ZuneXml/BadgeData.cs new file mode 100644 index 0000000..d037f72 --- /dev/null +++ b/ZuneXml/BadgeData.cs @@ -0,0 +1,96 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.BadgeData +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class BadgeData : XmlDataProviderObject + { + internal int TypeId => (int)BadgeData.GetBadgeType(this); + + internal static BadgeType GetBadgeType(BadgeData badgeData) + { + BadgeType badgeType = BadgeType.Invalid; + switch (badgeData.Type) + { + case "ActiveAlbumListener_Bronze": + badgeType = BadgeType.BronzeAlbum; + break; + case "ActiveAlbumListener_Silver": + badgeType = BadgeType.SilverAlbum; + break; + case "ActiveAlbumListener_Gold": + badgeType = BadgeType.GoldAlbum; + break; + case "ActiveArtistListener_Bronze": + badgeType = BadgeType.BronzeArtist; + break; + case "ActiveArtistListener_Silver": + badgeType = BadgeType.SilverArtist; + break; + case "ActiveArtistListener_Gold": + badgeType = BadgeType.GoldArtist; + break; + case "ActiveForumsBadge_Bronze": + badgeType = BadgeType.BronzeForums; + break; + case "ActiveForumsBadge_Silver": + badgeType = BadgeType.SilverForums; + break; + case "ActiveForumsBadge_Gold": + badgeType = BadgeType.GoldForums; + break; + case "ActiveReviewBadge_Bronze": + badgeType = BadgeType.BronzeReview; + break; + case "ActiveReviewBadge_Silver": + badgeType = BadgeType.SilverReview; + break; + case "ActiveReviewBadge_Gold": + badgeType = BadgeType.GoldReview; + break; + } + return badgeType; + } + + internal static XmlDataProviderObject ConstructBadgeDataObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new BadgeData(owner, objectTypeCookie); + } + + internal BadgeData(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string Title => (string)base.GetProperty(nameof(Title)); + + internal string Image => (string)base.GetProperty(nameof(Image)); + + internal string Type => (string)base.GetProperty(nameof(Type)); + + internal Guid MediaId => (Guid)base.GetProperty(nameof(MediaId)); + + internal string MediaType => (string)base.GetProperty(nameof(MediaType)); + + internal string Description => (string)base.GetProperty(nameof(Description)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "TypeId": + return (object)this.TypeId; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/BadgeType.cs b/ZuneXml/BadgeType.cs new file mode 100644 index 0000000..26c6b2d --- /dev/null +++ b/ZuneXml/BadgeType.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.BadgeType +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + public enum BadgeType + { + Invalid = -1, // 0xFFFFFFFF + GoldArtist = 0, + SilverArtist = 1, + BronzeArtist = 2, + GoldAlbum = 3, + SilverAlbum = 4, + BronzeAlbum = 5, + GoldForums = 6, + SilverForums = 7, + BronzeForums = 8, + GoldReview = 9, + SilverReview = 10, // 0x0000000A + BronzeReview = 11, // 0x0000000B + } +} diff --git a/ZuneXml/CatalogPrefixSearchQueryHelper.cs b/ZuneXml/CatalogPrefixSearchQueryHelper.cs new file mode 100644 index 0000000..debbe7a --- /dev/null +++ b/ZuneXml/CatalogPrefixSearchQueryHelper.cs @@ -0,0 +1,73 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.CatalogPrefixSearchQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Util; +using System; +using System.Text; +using ZuneUI; + +namespace ZuneXml +{ + internal class CatalogPrefixSearchQueryHelper : CatalogServiceQueryHelper + { + internal static ZuneServiceQueryHelper ConstructPrefixSearchQueryHelper( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new CatalogPrefixSearchQueryHelper(query); + } + + internal CatalogPrefixSearchQueryHelper(ZuneServiceQuery query) + : base(query) + { + } + + internal override string GetResourceUri() + { + string property1 = (string)this.Query.GetProperty("Prefix"); + if (!Search.Instance.IsValidKeyword(property1)) + return (string)null; + string endPointUri = Microsoft.Zune.Service.Service.GetEndPointUri(this._endPoint); + StringBuilder stringBuilder = new StringBuilder(128); + stringBuilder.Append(endPointUri); + stringBuilder.Append("/?prefix="); + stringBuilder.Append(Uri.EscapeDataString(property1)); + if ((bool)this.Query.GetProperty("OnlyIncludeZuneRadioArtists")) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMusic)) + stringBuilder.Append("&includeZuneRadioArtists=true"); + } + else + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMusic)) + { + stringBuilder.Append("&includeTracks=true"); + stringBuilder.Append("&includeAlbums=true"); + stringBuilder.Append("&includeArtists=true"); + } + if (FeatureEnablement.IsFeatureEnabled(Features.eVideos)) + { + stringBuilder.Append("&includeMovies=true"); + stringBuilder.Append("&includeVideoShorts=true"); + } + if (FeatureEnablement.IsFeatureEnabled(Features.eTV)) + stringBuilder.Append("&includeTVSeries=true"); + if (FeatureEnablement.IsFeatureEnabled(Features.eMusicVideos)) + stringBuilder.Append("&includeMusicVideos=true"); + if (FeatureEnablement.IsFeatureEnabled(Features.ePodcasts)) + stringBuilder.Append("&includePodcasts=true"); + if (FeatureEnablement.IsFeatureEnabled(Features.eApps)) + stringBuilder.Append("&includeApplications=true"); + } + string property2 = (string)this.Query.GetProperty("ClientType"); + if (!string.IsNullOrEmpty(property2)) + { + stringBuilder.Append("&clientType="); + stringBuilder.Append(property2); + } + return stringBuilder.ToString(); + } + } +} diff --git a/ZuneXml/CatalogSearchQueryHelper.cs b/ZuneXml/CatalogSearchQueryHelper.cs new file mode 100644 index 0000000..bc22b17 --- /dev/null +++ b/ZuneXml/CatalogSearchQueryHelper.cs @@ -0,0 +1,61 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.CatalogSearchQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Shell; +using System; +using System.Text; + +namespace ZuneXml +{ + internal class CatalogSearchQueryHelper : CatalogServiceQueryHelper + { + internal static ZuneServiceQueryHelper ConstructSearchQueryHelper( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new CatalogSearchQueryHelper(query); + } + + internal CatalogSearchQueryHelper(ZuneServiceQuery query) + : base(query) + { + } + + internal override string GetResourceUri() + { + string property1 = (string)this.Query.GetProperty("ResourceType"); + string property2 = (string)this.Query.GetProperty("Keywords"); + if (string.IsNullOrEmpty(property1) || string.IsNullOrEmpty(property2)) + return (string)null; + string endPointUri = Microsoft.Zune.Service.Service.GetEndPointUri(this._endPoint); + StringBuilder stringBuilder = new StringBuilder(128); + stringBuilder.Append(endPointUri); + stringBuilder.Append("/"); + stringBuilder.Append(property1); + stringBuilder.Append("?q="); + stringBuilder.Append(Uri.EscapeDataString(property2)); + string property3 = (string)this.Query.GetProperty("ClientType"); + if (!string.IsNullOrEmpty(property3)) + { + stringBuilder.Append("&clientType="); + stringBuilder.Append(property3); + } + string property4 = (string)this.Query.GetProperty("Store"); + if (!string.IsNullOrEmpty(property4)) + { + stringBuilder.Append("&store="); + stringBuilder.Append(property4); + } + string timeTravel = ClientConfiguration.Service.TimeTravel; + if (!string.IsNullOrEmpty(timeTravel) && ZuneApplication.Service.IsSignedIn()) + { + stringBuilder.Append("&instant="); + stringBuilder.Append(Uri.EscapeDataString(timeTravel)); + } + return stringBuilder.ToString(); + } + } +} diff --git a/ZuneXml/CatalogServiceQueryHelper.cs b/ZuneXml/CatalogServiceQueryHelper.cs new file mode 100644 index 0000000..2ac59f3 --- /dev/null +++ b/ZuneXml/CatalogServiceQueryHelper.cs @@ -0,0 +1,145 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.CatalogServiceQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Text; + +namespace ZuneXml +{ + internal class CatalogServiceQueryHelper : ZuneServiceQueryHelper + { + protected EServiceEndpointId _endPoint; + + internal static ZuneServiceQueryHelper ConstructMusicCatalogQueryHelper( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new CatalogServiceQueryHelper(query); + } + + internal CatalogServiceQueryHelper(ZuneServiceQuery query) + : base(query) + { + this._endPoint = EServiceEndpointId.SEID_RootCatalog; + if (string.IsNullOrEmpty(ClientConfiguration.Service.TimeTravel) || !ZuneApplication.Service.IsSignedIn()) + return; + query.PassportTicketType = EPassportPolicyId.MBI; + } + + internal override string GetResourceUri() => this.BuildServiceUri(0, 0); + + protected virtual bool ResourceOnly + { + get + { + object property = this.Query.GetProperty(nameof(ResourceOnly)); + return property == null || !(bool)property; + } + } + + protected virtual bool RequireId => this.ResourceOnly; + + protected virtual bool RequireResource => true; + + protected virtual bool RequireRepresentation => this.ResourceOnly; + + private string BuildServiceUri(int chunkStart, int chunkSize) + { + StringBuilder requestUri = new StringBuilder(128); + string property1 = (string)this.Query.GetProperty("Url"); + if (!string.IsNullOrEmpty(property1)) + { + requestUri.Append(property1); + } + else + { + string property2 = (string)this.Query.GetProperty("Id"); + if (this.RequireId && property2 == string.Empty) + return (string)null; + string property3 = (string)this.Query.GetProperty("ResourceType"); + string property4 = (string)this.Query.GetProperty("Representation"); + if (this.RequireResource && property3 == null || this.RequireRepresentation && property4 == null) + return (string)null; + string endPointUri = Microsoft.Zune.Service.Service.GetEndPointUri(this._endPoint); + requestUri.Append(endPointUri); + requestUri.Append("/"); + if (!string.IsNullOrEmpty(property3)) + { + requestUri.Append(property3); + requestUri.Append("/"); + } + if (!string.IsNullOrEmpty(property2)) + { + requestUri.Append(property2); + requestUri.Append("/"); + } + if (!string.IsNullOrEmpty(property4)) + { + requestUri.Append(property4); + requestUri.Append("/"); + } + } + bool fFirst = true; + this.AppendStuffAfterRepresentation(requestUri, ref fFirst); + string property5 = (string)this.Query.GetProperty("ClientType"); + if (!string.IsNullOrEmpty(property5)) + ZuneServiceQueryHelper.AppendParam(requestUri, "clientType", property5, ref fFirst); + string property6 = (string)this.Query.GetProperty("Cost"); + if (!string.IsNullOrEmpty(property6)) + ZuneServiceQueryHelper.AppendParam(requestUri, "cost", property6, ref fFirst); + string property7 = (string)this.Query.GetProperty("Tag"); + if (!string.IsNullOrEmpty(property7)) + ZuneServiceQueryHelper.AppendParam(requestUri, "tag", property7, ref fFirst); + string property8 = (string)this.Query.GetProperty("Store"); + if (!string.IsNullOrEmpty(property8)) + ZuneServiceQueryHelper.AppendParam(requestUri, "store", property8, ref fFirst); + object property9 = this.Query.GetProperty("ChunkSize"); + if (property9 != null && (int)property9 > 0) + ZuneServiceQueryHelper.AppendParam(requestUri, nameof(chunkSize), property9.ToString(), ref fFirst); + object property10 = this.Query.GetProperty("IsActionable"); + if (property10 != null) + { + bool flag = (bool)property10; + if (flag) + ZuneServiceQueryHelper.AppendParam(requestUri, "isActionable", flag.ToString(), ref fFirst); + } + if (chunkSize > 0) + { + ZuneServiceQueryHelper.AppendParam(requestUri, "count", chunkSize.ToString(), ref fFirst); + ZuneServiceQueryHelper.AppendParam(requestUri, "startIndex", chunkStart.ToString(), ref fFirst); + } + string property11 = (string)this.Query.GetProperty("RequestSortBy"); + if (!string.IsNullOrEmpty(property11)) + ZuneServiceQueryHelper.AppendParam(requestUri, "orderby", property11, ref fFirst); + string timeTravel = ClientConfiguration.Service.TimeTravel; + if (!string.IsNullOrEmpty(timeTravel) && ZuneApplication.Service.IsSignedIn()) + ZuneServiceQueryHelper.AppendParam(requestUri, "instant", Uri.EscapeDataString(timeTravel), ref fFirst); + return requestUri.ToString(); + } + + protected virtual void AppendStuffAfterRepresentation(StringBuilder requestUri, ref bool fFirst) + { + string property1 = (string)this.Query.GetProperty("StartsWith"); + if (!string.IsNullOrEmpty(property1)) + ZuneServiceQueryHelper.AppendParam(requestUri, "startsWith", property1, ref fFirst); + string property2 = (string)this.Query.GetProperty("StartDate"); + if (!string.IsNullOrEmpty(property2)) + ZuneServiceQueryHelper.AppendParam(requestUri, "startDate", property2, ref fFirst); + string property3 = (string)this.Query.GetProperty("EndDate"); + if (!string.IsNullOrEmpty(property3)) + ZuneServiceQueryHelper.AppendParam(requestUri, "endDate", property3, ref fFirst); + object property4 = this.Query.GetProperty("MinWidth"); + if (property4 != null && (int)property4 > 0) + ZuneServiceQueryHelper.AppendParam(requestUri, "minWidth", property4.ToString(), ref fFirst); + object property5 = this.Query.GetProperty("MinHeight"); + if (property5 == null || (int)property5 <= 0) + return; + ZuneServiceQueryHelper.AppendParam(requestUri, "minHeight", property5.ToString(), ref fFirst); + } + } +} diff --git a/ZuneXml/Category.cs b/ZuneXml/Category.cs new file mode 100644 index 0000000..3faf50f --- /dev/null +++ b/ZuneXml/Category.cs @@ -0,0 +1,22 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Category +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal abstract class Category : XmlDataProviderObject + { + protected Category(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract string Id { get; } + + internal abstract string Title { get; } + } +} diff --git a/ZuneXml/ChannelReason.cs b/ZuneXml/ChannelReason.cs new file mode 100644 index 0000000..1885441 --- /dev/null +++ b/ZuneXml/ChannelReason.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ChannelReason +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class ChannelReason : XmlDataProviderObject + { + internal static XmlDataProviderObject ConstructChannelReasonObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ChannelReason(owner, objectTypeCookie); + } + + internal ChannelReason(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string Id => (string)this.GetProperty(nameof(Id)); + + internal string Description => (string)this.GetProperty(nameof(Description)); + } +} diff --git a/ZuneXml/ChannelTrack.cs b/ZuneXml/ChannelTrack.cs new file mode 100644 index 0000000..eb3cbe2 --- /dev/null +++ b/ZuneXml/ChannelTrack.cs @@ -0,0 +1,79 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ChannelTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneXml +{ + internal class ChannelTrack : PlaylistTrack + { + internal static XmlDataProviderObject ConstructChannelTrackObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ChannelTrack(owner, objectTypeCookie); + } + + internal ChannelTrack(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal IList Reasons => (IList)base.GetProperty(nameof(Reasons)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Actionable": + return (object)this.Actionable; + case "UserRating": + return (object)this.UserRating; + case "LibraryId": + return (object)this.LibraryId; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPoints": + return (object)this.HasPoints; + case "CanPlay": + return (object)this.CanPlay; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanDownload": + return (object)this.CanDownload; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFree": + return (object)this.CanPurchaseFree; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanPurchaseSubscriptionFree": + return (object)this.CanPurchaseSubscriptionFree; + case "CanSync": + return (object)this.CanSync; + case "CanBurn": + return (object)this.CanBurn; + case "InCollection": + return (object)this.InCollection; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "Ordinal": + return (object)this.Ordinal; + case "ImageId": + return (object)this.ImageId; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/ClientTypeEnum.cs b/ZuneXml/ClientTypeEnum.cs new file mode 100644 index 0000000..e969c98 --- /dev/null +++ b/ZuneXml/ClientTypeEnum.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ClientTypeEnum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal enum ClientTypeEnum + { + None, + Zune, + WindowsPhone, + } +} diff --git a/ZuneXml/ConstructObject.cs b/ZuneXml/ConstructObject.cs new file mode 100644 index 0000000..05aa838 --- /dev/null +++ b/ZuneXml/ConstructObject.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ConstructObject +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal delegate XmlDataProviderObject ConstructObject( + DataProviderQuery owner, + object objectTypeCookie); +} diff --git a/ZuneXml/Contributor.cs b/ZuneXml/Contributor.cs new file mode 100644 index 0000000..a3f97b0 --- /dev/null +++ b/ZuneXml/Contributor.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Contributor +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class Contributor : XmlDataProviderObject + { + internal static XmlDataProviderObject ConstructContributorObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Contributor(owner, objectTypeCookie); + } + + internal Contributor(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal Guid ContributorId => (Guid)this.GetProperty(nameof(ContributorId)); + + internal string ContributorName => (string)this.GetProperty(nameof(ContributorName)); + + internal int RoleId => (int)this.GetProperty(nameof(RoleId)); + + internal string RoleName => (string)this.GetProperty(nameof(RoleName)); + } +} diff --git a/ZuneXml/DataProviderQueryHelper.cs b/ZuneXml/DataProviderQueryHelper.cs new file mode 100644 index 0000000..93ede38 --- /dev/null +++ b/ZuneXml/DataProviderQueryHelper.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.DataProviderQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Net; + +namespace ZuneXml +{ + public class DataProviderQueryHelper + { + public static bool ResponseIsForbiddenOrUnauthorized(DataProviderQuery failedQuery) + { + if (!(failedQuery is XmlDataProviderQuery) || !(((XmlDataProviderQuery)failedQuery).ErrorCode is HttpStatusCode errorCode)) + return false; + return errorCode == HttpStatusCode.Forbidden || errorCode == HttpStatusCode.Unauthorized; + } + + public static bool ResponseIsNotFound(DataProviderQuery failedQuery) => failedQuery is XmlDataProviderQuery && ((XmlDataProviderQuery)failedQuery).ErrorCode is HttpStatusCode errorCode && errorCode == HttpStatusCode.NotFound; + } +} diff --git a/ZuneXml/DisclosureEnum.cs b/ZuneXml/DisclosureEnum.cs new file mode 100644 index 0000000..d522c5f --- /dev/null +++ b/ZuneXml/DisclosureEnum.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.DisclosureEnum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal enum DisclosureEnum + { + Invalid = -1, // 0xFFFFFFFF + None = 0, + Disclose = 1, + DiscloseAndPrompt = 2, + Prompt = 3, + } +} diff --git a/ZuneXml/Episode.cs b/ZuneXml/Episode.cs new file mode 100644 index 0000000..401acd2 --- /dev/null +++ b/ZuneXml/Episode.cs @@ -0,0 +1,116 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Episode +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class Episode : TVVideo + { + internal IList Languages => this.Rights.Languages; + + internal static XmlDataProviderObject ConstructEpisodeObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Episode(owner, objectTypeCookie); + } + + internal Episode(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal int EpisodeNumber => (int)base.GetProperty(nameof(EpisodeNumber)); + + internal int SeasonNumber => (int)base.GetProperty(nameof(SeasonNumber)); + + internal Series Series => (Series)base.GetProperty(nameof(Series)); + + internal IList Categories => (IList)base.GetProperty(nameof(Categories)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override string SortTitle => (string)base.GetProperty(nameof(SortTitle)); + + internal override string Description => (string)base.GetProperty(nameof(Description)); + + internal override DateTime ReleaseDate => (DateTime)base.GetProperty(nameof(ReleaseDate)); + + internal override string Copyright => (string)base.GetProperty(nameof(Copyright)); + + internal override string Rating => (string)base.GetProperty(nameof(Rating)); + + internal override TimeSpan Duration => (TimeSpan)base.GetProperty(nameof(Duration)); + + internal override double Popularity => (double)base.GetProperty(nameof(Popularity)); + + internal override Network Network => (Network)base.GetProperty(nameof(Network)); + + internal override string ProductionCompany => (string)base.GetProperty(nameof(ProductionCompany)); + + internal override Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + internal override MediaRights Rights => (MediaRights)base.GetProperty(nameof(Rights)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Languages": + return (object)this.Languages; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPreview": + return (object)this.HasPreview; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseHD": + return (object)this.CanPurchaseHD; + case "CanPurchaseSD": + return (object)this.CanPurchaseSD; + case "CanPurchaseSeason": + return (object)this.CanPurchaseSeason; + case "CanPurchaseSeasonHD": + return (object)this.CanPurchaseSeasonHD; + case "CanPurchaseSeasonSD": + return (object)this.CanPurchaseSeasonSD; + case "CanRent": + return (object)this.CanRent; + case "CanRentHD": + return (object)this.CanRentHD; + case "CanRentSD": + return (object)this.CanRentSD; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanSync": + return (object)this.CanSync; + case "InCollection": + return (object)this.InCollection; + case "InCollectionShortcut": + return (object)this.InCollectionShortcut; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "PrimaryArtist": + return (object)this.PrimaryArtist; + case "Artists": + return (object)this.Artists; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/Genre.cs b/ZuneXml/Genre.cs new file mode 100644 index 0000000..bc52304 --- /dev/null +++ b/ZuneXml/Genre.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Genre +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class Genre : Category + { + internal static XmlDataProviderObject ConstructGenreObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Genre(owner, objectTypeCookie); + } + + internal Genre(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override string Id => (string)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/HistoryQueryHelper.cs b/ZuneXml/HistoryQueryHelper.cs new file mode 100644 index 0000000..277b924 --- /dev/null +++ b/ZuneXml/HistoryQueryHelper.cs @@ -0,0 +1,41 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.HistoryQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using System.Text; + +namespace ZuneXml +{ + internal class HistoryQueryHelper : ZuneServiceQueryHelper + { + protected string _api; + + internal HistoryQueryHelper(ZuneServiceQuery query) + : base(query) + { + query.PassportTicketType = EPassportPolicyId.MBI_SSL; + query.CachePolicy = HttpRequestCachePolicy.BypassCache; + } + + internal override string GetResourceUri() + { + StringBuilder requestUri = new StringBuilder(128); + requestUri.Append(Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_CommerceV2)); + requestUri.Append(this._api); + bool fFirst = true; + ZuneServiceQueryHelper.AppendParam(requestUri, "tunerType", "zunePCClient", ref fFirst); + if (this.Query.GetProperty("MediaType") is string property) + ZuneServiceQueryHelper.AppendParam(requestUri, "mediaTypeOrCategory", property, ref fFirst); + ZuneServiceQueryHelper.AppendParam(requestUri, "startIndex", "1", ref fFirst); + object property1 = this.Query.GetProperty("ChunkSize"); + if (property1 is int) + ZuneServiceQueryHelper.AppendParam(requestUri, "chunkSize", property1.ToString(), ref fFirst); + return requestUri.ToString(); + } + + internal override string GetQueryPostBody() => ""; + } +} diff --git a/ZuneXml/IPageInfo.cs b/ZuneXml/IPageInfo.cs new file mode 100644 index 0000000..3a75fab --- /dev/null +++ b/ZuneXml/IPageInfo.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.IPageInfo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal interface IPageInfo + { + string GetPageUrl(int startIndex); + + string GetPagePostBody(int startIndex); + } +} diff --git a/ZuneXml/IXmlDataProviderObject.cs b/ZuneXml/IXmlDataProviderObject.cs new file mode 100644 index 0000000..48d10c5 --- /dev/null +++ b/ZuneXml/IXmlDataProviderObject.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.IXmlDataProviderObject +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.Collections.Generic; + +namespace ZuneXml +{ + internal interface IXmlDataProviderObject + { + bool ProcessXPath( + string currentXPath, + Hashtable attributes, + List matches); + } +} diff --git a/ZuneXml/InboxImageDataProviderObject.cs b/ZuneXml/InboxImageDataProviderObject.cs new file mode 100644 index 0000000..9bc6869 --- /dev/null +++ b/ZuneXml/InboxImageDataProviderObject.cs @@ -0,0 +1,87 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.InboxImageDataProviderObject +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class InboxImageDataProviderObject : DataProviderObject + { + public static readonly string PropertyName_InLibrary = nameof(InLibrary); + public static readonly string PropertyName_ImagePath = nameof(ImagePath); + public static readonly string PropertyName_Photo = nameof(Photo); + private bool _inLibrary; + private string _imagePath; + private Image _photo; + + public InboxImageDataProviderObject(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + public override object GetProperty(string propertyName) + { + if (propertyName == InboxImageDataProviderObject.PropertyName_InLibrary) + return (object)this.InLibrary; + if (propertyName == InboxImageDataProviderObject.PropertyName_ImagePath) + return (object)this.ImagePath; + return propertyName == InboxImageDataProviderObject.PropertyName_Photo ? (object)this.Photo : (object)null; + } + + public bool InLibrary + { + get => this._inLibrary; + set + { + if (this._inLibrary == value) + return; + this._inLibrary = value; + this.FirePropertyChanged(InboxImageDataProviderObject.PropertyName_InLibrary); + } + } + + public string ImagePath + { + get => this._imagePath; + set + { + if (!(this._imagePath != value)) + return; + this._imagePath = value; + this.FirePropertyChanged(InboxImageDataProviderObject.PropertyName_ImagePath); + } + } + + public Image Photo + { + get + { + if (this._photo == null && !string.IsNullOrEmpty(this._imagePath)) + this._photo = new Image("file://" + this._imagePath); + return this._photo; + } + } + + public override void SetProperty(string propertyName, object value) + { + if (propertyName == InboxImageDataProviderObject.PropertyName_InLibrary) + { + this.InLibrary = (bool)value; + } + else + { + if (!(propertyName == InboxImageDataProviderObject.PropertyName_ImagePath)) + throw new ApplicationException("unexpected property name"); + this.ImagePath = (string)value; + } + } + + internal void TransferToAppThread() + { + } + } +} diff --git a/ZuneXml/InboxImageQuery.cs b/ZuneXml/InboxImageQuery.cs new file mode 100644 index 0000000..e73ddf1 --- /dev/null +++ b/ZuneXml/InboxImageQuery.cs @@ -0,0 +1,186 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.InboxImageQuery +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Messaging; +using Microsoft.Zune.Service; +using System; +using System.IO; +using System.Net; + +namespace ZuneXml +{ + internal class InboxImageQuery : DataProviderQuery + { + public static readonly string PropertyName_Title = "Title"; + public static readonly string PropertyName_CollectionName = "CollectionName"; + public static readonly string PropertyName_URL = "URL"; + private string _title; + private string _collectionName; + private string _url; + + public static DataProviderQuery ConstructQuery(object queryTypeCookie) => (DataProviderQuery)new InboxImageQuery(queryTypeCookie); + + public InboxImageQuery(object queryTypeCookie) + : base(queryTypeCookie) + => this.Result = (object)new InboxImageDataProviderObject((DataProviderQuery)this, this.ResultTypeCookie); + + public override void SetProperty(string propertyName, object value) + { + if (propertyName == InboxImageQuery.PropertyName_Title) + { + this._title = (string)value; + this.UpdateLibraryState(); + } + else if (propertyName == InboxImageQuery.PropertyName_CollectionName) + { + this._collectionName = (string)value; + this.UpdateLibraryState(); + } + else + { + if (!(propertyName == InboxImageQuery.PropertyName_URL)) + throw new ApplicationException("unexpected property name"); + this._url = (string)value; + this.BeginExecute(); + } + } + + public override object GetProperty(string propertyName) + { + if (propertyName == InboxImageQuery.PropertyName_Title) + return (object)this._title; + if (propertyName == InboxImageQuery.PropertyName_CollectionName) + return (object)this._collectionName; + return propertyName == InboxImageQuery.PropertyName_URL ? (object)this._url : (object)null; + } + + protected override void BeginExecute() + { + this.DisposeLocalFile(); + if (string.IsNullOrEmpty(this._url) || !(this.Result is InboxImageDataProviderObject result)) + return; + this.SetWorkerStatus(DataProviderQueryStatus.RequestingData); + InboxImageQuery.RequestArgs requestArgs = new InboxImageQuery.RequestArgs(this._url, result, Environment.TickCount); + WebRequestHelper.ConstructWebRequest(this._url, EPassportPolicyId.MBI_SSL, HttpRequestCachePolicy.Default, true, false).GetResponseAsync(new AsyncRequestComplete(this.OnRequestComplete), (object)requestArgs); + } + + protected override void OnDispose() + { + this.DisposeLocalFile(); + base.OnDispose(); + } + + private void UpdateLibraryState() + { + this.DisposeLocalFile(); + InboxImageDataProviderObject result = this.Result as InboxImageDataProviderObject; + string inboxPhotoUrl = MessagingService.Instance.GetInboxPhotoUrl(this._title, this._collectionName); + result.InLibrary = inboxPhotoUrl != null; + result.ImagePath = inboxPhotoUrl; + } + + private void DisposeLocalFile() + { + if (!(this.Result is InboxImageDataProviderObject result) || result.InLibrary) + return; + string imagePath = result.ImagePath; + if (string.IsNullOrEmpty(imagePath)) + return; + try + { + System.IO.File.Delete(imagePath); + } + catch (Exception ex) + { + } + } + + private void OnRequestComplete(Microsoft.Zune.Service.HttpWebResponse response, object requestArgs) + { + InboxImageQuery.RequestArgs requestArgs1 = (InboxImageQuery.RequestArgs)requestArgs; + string requestUri = requestArgs1.m_requestUri; + InboxImageDataProviderObject result = requestArgs1.m_result; + int tcStart = requestArgs1.m_tcStart; + Stream stream = (Stream)null; + FileStream fileStream = (FileStream)null; + try + { + stream = response.StatusCode == HttpStatusCode.OK ? response.GetResponseStream() : throw new HttpWebException(response); + int tickCount1 = Environment.TickCount; + this.SetWorkerStatus(DataProviderQueryStatus.ProcessingData); + int contentLength = (int)response.ContentLength; + byte[] buffer = new byte[40960]; + string tempFileName = Path.GetTempFileName(); + fileStream = new FileStream(tempFileName, FileMode.Truncate, FileAccess.Write, FileShare.None, 40960, FileOptions.SequentialScan); + int count; + for (; contentLength > 0 && (count = stream.Read(buffer, 0, 40960)) > 0; contentLength -= count) + fileStream.Write(buffer, 0, count); + fileStream.Close(); + result.ImagePath = tempFileName; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetResult), (object)new InboxImageQuery.DeferredSetResultArgs(result)); + this.SetWorkerStatus(DataProviderQueryStatus.Complete); + int tickCount2 = Environment.TickCount; + } + catch (Exception ex) + { + this.SetWorkerStatus(DataProviderQueryStatus.Error); + } + finally + { + fileStream?.Close(); + stream?.Close(); + } + } + + private void SetWorkerStatus(DataProviderQueryStatus eStatus) => Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetStatus), (object)new InboxImageQuery.DeferredSetStatusArgs(eStatus)); + + private void DeferredSetStatus(object args) + { + if (!(args is InboxImageQuery.DeferredSetStatusArgs deferredSetStatusArgs)) + return; + this.Status = deferredSetStatusArgs.m_eStatus; + } + + private void DeferredSetResult(object argsObj) + { + if (!(argsObj is InboxImageQuery.DeferredSetResultArgs deferredSetResultArgs)) + return; + deferredSetResultArgs.m_result.TransferToAppThread(); + if (this.Result == deferredSetResultArgs.m_result) + return; + this.Result = (object)deferredSetResultArgs.m_result; + } + + private class RequestArgs + { + public readonly string m_requestUri; + public readonly InboxImageDataProviderObject m_result; + public readonly int m_tcStart; + + public RequestArgs(string requestUri, InboxImageDataProviderObject result, int tcStart) + { + this.m_requestUri = requestUri; + this.m_result = result; + this.m_tcStart = tcStart; + } + } + + private class DeferredSetStatusArgs + { + public readonly DataProviderQueryStatus m_eStatus; + + public DeferredSetStatusArgs(DataProviderQueryStatus eStatus) => this.m_eStatus = eStatus; + } + + private class DeferredSetResultArgs + { + public readonly InboxImageDataProviderObject m_result; + + public DeferredSetResultArgs(InboxImageDataProviderObject result) => this.m_result = result; + } + } +} diff --git a/ZuneXml/LinkPageInfo.cs b/ZuneXml/LinkPageInfo.cs new file mode 100644 index 0000000..9454cd8 --- /dev/null +++ b/ZuneXml/LinkPageInfo.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.LinkPageInfo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal class LinkPageInfo : IPageInfo + { + private string _nextPageUrl; + private string _requestBody; + + public LinkPageInfo(string nextPageUrl, string requestBody) + { + this._nextPageUrl = nextPageUrl; + this._requestBody = requestBody; + } + + public string GetPageUrl(int startIndex) => this._nextPageUrl; + + public string GetPagePostBody(int startIndex) => this._requestBody; + } +} diff --git a/ZuneXml/ListResult.cs b/ZuneXml/ListResult.cs new file mode 100644 index 0000000..711c72f --- /dev/null +++ b/ZuneXml/ListResult.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ListResult +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneXml +{ + internal abstract class ListResult : XmlDataProviderObject + { + protected ListResult(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract IList Items { get; } + } +} diff --git a/ZuneXml/MarketplaceRadioStation.cs b/ZuneXml/MarketplaceRadioStation.cs new file mode 100644 index 0000000..61ffb33 --- /dev/null +++ b/ZuneXml/MarketplaceRadioStation.cs @@ -0,0 +1,33 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MarketplaceRadioStation +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class MarketplaceRadioStation : MiniMedia + { + internal static XmlDataProviderObject ConstructMarketplaceRadioStationObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MarketplaceRadioStation(owner, objectTypeCookie); + } + + internal MarketplaceRadioStation(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal IList Genres => (IList)this.GetProperty(nameof(Genres)); + + internal override Guid Id => (Guid)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/Media.cs b/ZuneXml/Media.cs new file mode 100644 index 0000000..627a4f8 --- /dev/null +++ b/ZuneXml/Media.cs @@ -0,0 +1,64 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Media +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal abstract class Media : MiniMedia + { + internal string Artist + { + get + { + string str = (string)null; + MiniArtist primaryArtist = this.PrimaryArtist; + if (primaryArtist != null) + { + str = primaryArtist.Title; + } + else + { + IList artists = this.Artists; + if (artists != null) + { + IEnumerator enumerator = artists.GetEnumerator(); + try + { + if (enumerator.MoveNext()) + str = ((MiniMedia)enumerator.Current).Title; + } + finally + { + if (enumerator is IDisposable disposable) + disposable.Dispose(); + } + } + } + return str; + } + } + + protected Media(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract string SortTitle { get; } + + internal abstract Guid ImageId { get; } + + internal abstract MediaRights Rights { get; } + + internal abstract MiniArtist PrimaryArtist { get; } + + internal abstract IList Artists { get; } + + internal abstract double Popularity { get; } + } +} diff --git a/ZuneXml/MediaInstance.cs b/ZuneXml/MediaInstance.cs new file mode 100644 index 0000000..d9c3e76 --- /dev/null +++ b/ZuneXml/MediaInstance.cs @@ -0,0 +1,81 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MediaInstance +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class MediaInstance : XmlDataProviderObject + { + private MediaRightsEnum _rightEnum; + private VideoDefinitionEnum _videoDefinitionEnum; + private VideoResolutionEnum _videoResolutionEnum; + + public bool HasPurchasedTrial => this._rightEnum == MediaRightsEnum.PurchaseTrial; + + public bool HasPurchasedBeta => this._rightEnum == MediaRightsEnum.PurchaseBeta; + + public bool HasPurchased => this._rightEnum == MediaRightsEnum.Purchase || this._rightEnum == MediaRightsEnum.PurchaseStream || (this._rightEnum == MediaRightsEnum.PurchaseTrial || this._rightEnum == MediaRightsEnum.PurchaseBeta) || this._rightEnum == MediaRightsEnum.SubscriptionFreePurchase || this._rightEnum == MediaRightsEnum.AlbumPurchase; + + internal MediaRightsEnum RightEnum => this._rightEnum; + + internal VideoDefinitionEnum VideoDefinitionEnum => this._videoDefinitionEnum; + + internal VideoResolutionEnum VideoResolutionEnum => this._videoResolutionEnum; + + public override void SetProperty(string propertyName, object value) + { + switch (propertyName) + { + case "LicenseRight": + this._rightEnum = SchemaHelper.ToMediaRights((string)value); + break; + case "VideoDefinition": + this._videoDefinitionEnum = SchemaHelper.ToVideoDefinition((string)value); + break; + case "VideoResolution": + this._videoResolutionEnum = SchemaHelper.ToVideoResolution((string)value); + break; + } + base.SetProperty(propertyName, value); + } + + internal static XmlDataProviderObject ConstructMediaInstanceObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MediaInstance(owner, objectTypeCookie); + } + + internal MediaInstance(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal bool IsDownloadable => (bool)base.GetProperty(nameof(IsDownloadable)); + + internal string LicenseRight => (string)base.GetProperty(nameof(LicenseRight)); + + internal string VideoDefinition => (string)base.GetProperty(nameof(VideoDefinition)); + + internal string VideoResolution => (string)base.GetProperty(nameof(VideoResolution)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "HasPurchased": + return (object)this.HasPurchased; + case "HasPurchasedTrial": + return (object)this.HasPurchasedTrial; + case "HasPurchasedBeta": + return (object)this.HasPurchasedBeta; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/MediaRights.cs b/ZuneXml/MediaRights.cs new file mode 100644 index 0000000..af49219 --- /dev/null +++ b/ZuneXml/MediaRights.cs @@ -0,0 +1,270 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MediaRights +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Util; +using System; +using System.Collections; +using System.Collections.Generic; + +namespace ZuneXml +{ + internal class MediaRights : XmlDataProviderObject + { + internal Right GetOfferRight(ClientTypeEnum clientType, PriceTypeEnum priceType) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace) && this.Rights != null) + { + foreach (Right right in (IEnumerable)this.Rights) + { + if (clientType == right.ClientTypeEnum && priceType == right.PriceTypeEnum && Guid.Empty != right.OfferId) + return right; + } + } + return (Right)null; + } + + internal Right GetOfferRight( + MediaRightsEnum right, + ClientTypeEnum clientType, + PriceTypeEnum priceType) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace) && this.Rights != null) + { + foreach (Right right1 in (IEnumerable)this.Rights) + { + if (right == right1.RightEnum && clientType == right1.ClientTypeEnum && (priceType == right1.PriceTypeEnum && Guid.Empty != right1.OfferId)) + return right1; + } + } + return (Right)null; + } + + internal Right GetOfferRight( + MediaRightsEnum right, + AudioEncodingEnum encoding, + PriceTypeEnum priceType) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMusic) && this.Rights != null) + { + foreach (Right right1 in (IEnumerable)this.Rights) + { + if (right == right1.RightEnum && priceType == right1.PriceTypeEnum && (encoding == right1.AudioEncodingEnum && right1.OfferId != Guid.Empty)) + return right1; + } + } + return (Right)null; + } + + internal bool HasOfferRights( + MediaRightsEnum right, + ClientTypeEnum clientType, + PriceTypeEnum priceType) + { + return this.GetOfferRight(right, clientType, priceType) != null; + } + + internal bool HasOfferRights( + MediaRightsEnum right, + AudioEncodingEnum encoding, + PriceTypeEnum priceType, + out Right offer) + { + offer = this.GetOfferRight(right, encoding, priceType); + return offer != null; + } + + internal bool HasRights(ClientTypeEnum clientType) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace) && this.Rights != null) + { + foreach (Right right in (IEnumerable)this.Rights) + { + if (clientType == right.ClientTypeEnum) + return true; + } + } + return false; + } + + internal bool HasRights(MediaRightsEnum right, ClientTypeEnum clientType) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace) && this.Rights != null) + { + foreach (Right right1 in (IEnumerable)this.Rights) + { + if (right == right1.RightEnum && clientType == right1.ClientTypeEnum) + return true; + } + } + return false; + } + + internal bool HasRights(MediaRightsEnum right, AudioEncodingEnum encoding) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMusic) && this.Rights != null) + { + foreach (Right right1 in (IEnumerable)this.Rights) + { + if (right == right1.RightEnum && encoding == right1.AudioEncodingEnum) + return true; + } + } + return false; + } + + internal Right GetOfferRight( + MediaRightsEnum right, + VideoDefinitionEnum definition, + PriceTypeEnum priceType) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace) && this.IsAssociatedFeatureEnabled(right)) + { + if (definition == VideoDefinitionEnum.None) + { + Right right1 = (this.GetOfferRight(right, VideoDefinitionEnum.HD, priceType) ?? this.GetOfferRight(right, VideoDefinitionEnum.SD, priceType)) ?? this.GetOfferRight(right, VideoDefinitionEnum.XD, priceType); + if (right1 != null) + return right1; + } + if (this.Rights != null) + { + foreach (Right right1 in (IEnumerable)this.Rights) + { + if (right == right1.RightEnum && priceType == right1.PriceTypeEnum && (definition == right1.VideoDefinitionEnum || definition == VideoDefinitionEnum.None) && (right1.VideoResolutionEnum != VideoResolutionEnum.VR_1080P || right1.RightEnum != MediaRightsEnum.Purchase)) + return right1; + } + } + } + return (Right)null; + } + + internal bool HasRights( + MediaRightsEnum right, + VideoDefinitionEnum definition, + PriceTypeEnum priceType) + { + Right offerRight = this.GetOfferRight(right, definition, priceType); + if (right != MediaRightsEnum.PurchaseStream) + return offerRight != null; + return offerRight != null && this.HasRights(MediaRightsEnum.Purchase, definition, VideoDefinitionEnum.XD, priceType); + } + + internal Right GetOfferRight( + MediaRightsEnum right, + VideoDefinitionEnum definition1, + VideoDefinitionEnum definition2, + PriceTypeEnum priceType) + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace) && this.IsAssociatedFeatureEnabled(right) && this.Rights != null) + { + foreach (Right right1 in (IEnumerable)this.Rights) + { + if (right == right1.RightEnum && definition1 == right1.VideoDefinitionEnum && priceType == right1.PriceTypeEnum) + { + foreach (Right right2 in (IEnumerable)this.Rights) + { + if (right1 != right2 && right == right2.RightEnum && (definition2 == right2.VideoDefinitionEnum && priceType == right2.PriceTypeEnum) && right1.OfferId == right2.OfferId) + return right2; + } + } + } + } + return (Right)null; + } + + private bool IsAssociatedFeatureEnabled(MediaRightsEnum right) + { + bool flag = true; + if (right == MediaRightsEnum.RentStream && !FeatureEnablement.IsFeatureEnabled(Features.eMBRRental) || right == MediaRightsEnum.PreviewStream && !FeatureEnablement.IsFeatureEnabled(Features.eMBRPreview) || right == MediaRightsEnum.PurchaseStream && !FeatureEnablement.IsFeatureEnabled(Features.eMBRPurchase)) + flag = false; + return flag; + } + + internal bool HasRights( + MediaRightsEnum right, + VideoDefinitionEnum definition1, + VideoDefinitionEnum definition2, + PriceTypeEnum priceType) + { + return this.GetOfferRight(right, definition1, definition2, priceType) != null; + } + + internal bool HasAnyRights() + { + if (FeatureEnablement.IsFeatureEnabled(Features.eMarketplace) && this.Rights != null) + { + foreach (Right right in (IEnumerable)this.Rights) + { + if (this.IsAssociatedFeatureEnabled(right.RightEnum)) + return true; + } + } + return false; + } + + internal string GetCompId() + { + string str = (string)null; + if (this.Rights != null) + { + foreach (Right right in (IEnumerable)this.Rights) + { + string providerCode = right.ProviderCode; + if (!string.IsNullOrEmpty(providerCode)) + { + int length = providerCode.IndexOf(':'); + str = length <= 0 ? providerCode : providerCode.Substring(0, length); + break; + } + } + } + return str; + } + + internal IList Languages + { + get + { + List stringList = new List(); + foreach (Right right in (IEnumerable)this.Rights) + { + if (this.IsAssociatedFeatureEnabled(right.RightEnum) && (right.VideoDefinitionEnum == VideoDefinitionEnum.HD || right.VideoDefinitionEnum == VideoDefinitionEnum.SD) && right.PriceTypeEnum == PriceTypeEnum.Points) + { + string language = right.Language; + if (!string.IsNullOrEmpty(language) && !stringList.Contains(language)) + stringList.Add(language); + } + } + return (IList)stringList; + } + } + + internal static XmlDataProviderObject ConstructMediaRightsObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MediaRights(owner, objectTypeCookie); + } + + internal MediaRights(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal IList Rights => (IList)base.GetProperty(nameof(Rights)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Languages": + return (object)this.Languages; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/MediaRightsEnum.cs b/ZuneXml/MediaRightsEnum.cs new file mode 100644 index 0000000..fedee53 --- /dev/null +++ b/ZuneXml/MediaRightsEnum.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MediaRightsEnum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal enum MediaRightsEnum + { + None, + Preview, + PreviewStream, + SubscriptionStream, + SubscriptionDownload, + Purchase, + PurchaseTrial, + PurchaseStream, + PurchaseBeta, + SeasonPurchase, + SeasonPurchaseStream, + AlbumPurchase, + SubscriptionFreePurchase, + TransferToPortableDevice, + Rent, + RentStream, + Download, + } +} diff --git a/ZuneXml/MediaTypeEnum.cs b/ZuneXml/MediaTypeEnum.cs new file mode 100644 index 0000000..a8cb8b8 --- /dev/null +++ b/ZuneXml/MediaTypeEnum.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MediaTypeEnum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal enum MediaTypeEnum + { + Invalid = -1, // 0xFFFFFFFF + None = 0, + TVSeason = 1, + } +} diff --git a/ZuneXml/MessageDetails.cs b/ZuneXml/MessageDetails.cs new file mode 100644 index 0000000..3e85a00 --- /dev/null +++ b/ZuneXml/MessageDetails.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MessageDetails +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class MessageDetails : XmlDataProviderObject + { + internal static XmlDataProviderObject ConstructMessageDetailsObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MessageDetails(owner, objectTypeCookie); + } + + internal MessageDetails(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string TextContent => (string)this.GetProperty(nameof(TextContent)); + + internal Guid MediaId => (Guid)this.GetProperty(nameof(MediaId)); + + internal string ReplyLink => (string)this.GetProperty(nameof(ReplyLink)); + + internal string AltLink => (string)this.GetProperty(nameof(AltLink)); + + internal string AlbumTitle => (string)this.GetProperty(nameof(AlbumTitle)); + + internal string ArtistName => (string)this.GetProperty(nameof(ArtistName)); + + internal string SongTitle => (string)this.GetProperty(nameof(SongTitle)); + + internal int TrackNumber => (int)this.GetProperty(nameof(TrackNumber)); + + internal string PlaylistName => (string)this.GetProperty(nameof(PlaylistName)); + + internal string PodcastName => (string)this.GetProperty(nameof(PodcastName)); + + internal string PodcastUrl => (string)this.GetProperty(nameof(PodcastUrl)); + + internal Guid PodcastMediaId => (Guid)this.GetProperty(nameof(PodcastMediaId)); + + internal string UserTile => (string)this.GetProperty(nameof(UserTile)); + + internal string ZuneTag => (string)this.GetProperty(nameof(ZuneTag)); + + internal string ForumsMsgUrl => (string)this.GetProperty(nameof(ForumsMsgUrl)); + + internal string NotifSubject => (string)this.GetProperty(nameof(NotifSubject)); + + internal string NotifSource => (string)this.GetProperty(nameof(NotifSource)); + } +} diff --git a/ZuneXml/MessageRoot.cs b/ZuneXml/MessageRoot.cs new file mode 100644 index 0000000..8213ec5 --- /dev/null +++ b/ZuneXml/MessageRoot.cs @@ -0,0 +1,146 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MessageRoot +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using System; +using ZuneUI; + +namespace ZuneXml +{ + internal class MessageRoot : XmlDataProviderObject + { + private MessageTypeEnum _messageType = MessageTypeEnum.Invalid; + private EContentType _contentType = EContentType.Unknown; + + internal string UserTileUrl => ComposerHelper.GetUserTileUri(this.From); + + internal MessageTypeEnum MessageType + { + get => this._messageType; + private set + { + if (this._messageType == value) + return; + this._messageType = value; + this.ContentType = MessageRoot.ToContentType(value); + this.FirePropertyChanged(nameof(MessageType)); + this.FirePropertyChanged("IsSupported"); + } + } + + internal EContentType ContentType + { + get => this._contentType; + private set + { + if (this._contentType == value) + return; + this._contentType = value; + this.FirePropertyChanged(nameof(ContentType)); + } + } + + internal bool IsSupported + { + get + { + if (!this.Wishlist) + return this.MessageType != MessageTypeEnum.Invalid; + return this.MessageType == MessageTypeEnum.Song || this.MessageType == MessageTypeEnum.Album; + } + } + + private static EContentType ToContentType(MessageTypeEnum messageType) + { + EContentType econtentType; + switch (messageType) + { + case MessageTypeEnum.Album: + econtentType = EContentType.MusicAlbum; + break; + case MessageTypeEnum.MusicVideo: + case MessageTypeEnum.Video: + case MessageTypeEnum.Movie: + case MessageTypeEnum.MovieTrailer: + econtentType = EContentType.Video; + break; + case MessageTypeEnum.Playlist: + econtentType = EContentType.Playlist; + break; + case MessageTypeEnum.Podcast: + econtentType = EContentType.PodcastSeries; + break; + case MessageTypeEnum.Song: + econtentType = EContentType.MusicTrack; + break; + default: + econtentType = EContentType.Unknown; + break; + } + return econtentType; + } + + public override void SetProperty(string propertyName, object value) + { + base.SetProperty(propertyName, value); + switch (propertyName) + { + case "Type": + this.MessageType = SchemaHelper.ToMessageType(value as string); + break; + } + base.SetProperty(propertyName, value); + } + + internal static XmlDataProviderObject ConstructMessageRootObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MessageRoot(owner, objectTypeCookie); + } + + internal MessageRoot(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string MessagingId => (string)base.GetProperty(nameof(MessagingId)); + + internal string From => (string)base.GetProperty(nameof(From)); + + internal string Type => (string)base.GetProperty(nameof(Type)); + + internal string Subject => (string)base.GetProperty(nameof(Subject)); + + internal DateTime Received => (DateTime)base.GetProperty(nameof(Received)); + + internal string DetailsLink => (string)base.GetProperty(nameof(DetailsLink)); + + internal string Status + { + get => (string)base.GetProperty(nameof(Status)); + set => this.SetProperty(nameof(Status), (object)value); + } + + internal bool Wishlist => (bool)base.GetProperty(nameof(Wishlist)); + + internal Guid MediaId => (Guid)base.GetProperty(nameof(MediaId)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "UserTileUrl": + return (object)this.UserTileUrl; + case "IsSupported": + return (object)this.IsSupported; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/MessageTypeEnum.cs b/ZuneXml/MessageTypeEnum.cs new file mode 100644 index 0000000..d4e6e29 --- /dev/null +++ b/ZuneXml/MessageTypeEnum.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MessageTypeEnum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + public enum MessageTypeEnum + { + Invalid = -1, // 0xFFFFFFFF + Album = 0, + Card = 1, + Forums = 2, + FriendRequest = 3, + Message = 4, + MusicVideo = 5, + Notification = 6, + Photos = 7, + Playlist = 8, + Podcast = 9, + Song = 10, // 0x0000000A + Video = 11, // 0x0000000B + Movie = 12, // 0x0000000C + MovieTrailer = 13, // 0x0000000D + } +} diff --git a/ZuneXml/MessagingQueryHelper.cs b/ZuneXml/MessagingQueryHelper.cs new file mode 100644 index 0000000..2237320 --- /dev/null +++ b/ZuneXml/MessagingQueryHelper.cs @@ -0,0 +1,39 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MessagingQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using ZuneUI; + +namespace ZuneXml +{ + internal class MessagingQueryHelper : ZuneServiceQueryHelper + { + private EServiceEndpointId _endPoint; + + internal static ZuneServiceQueryHelper ConstructMessagingQueryHelper( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new MessagingQueryHelper(query); + } + + internal MessagingQueryHelper(ZuneServiceQuery query) + : base(query) + { + this._endPoint = EServiceEndpointId.SEID_Messaging; + query.CachePolicy = HttpRequestCachePolicy.BypassCache; + query.PassportTicketType = EPassportPolicyId.MBI_SSL; + } + + internal override string GetResourceUri() + { + string property1 = (string)this.Query.GetProperty("ZuneTag"); + if (string.IsNullOrEmpty(property1)) + return (string)null; + string property2 = (string)this.Query.GetProperty("RequestType"); + return string.IsNullOrEmpty(property2) ? (string)null : UrlHelper.MakeUrl(string.Format("{0}/messaging/{1}/inbox/{2}", (object)Microsoft.Zune.Service.Service.GetEndPointUri(this._endPoint), (object)property1.ToLower(), (object)property2)); + } + } +} diff --git a/ZuneXml/MiniAlbum.cs b/ZuneXml/MiniAlbum.cs new file mode 100644 index 0000000..d3dea41 --- /dev/null +++ b/ZuneXml/MiniAlbum.cs @@ -0,0 +1,32 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MiniAlbum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class MiniAlbum : MiniMedia + { + internal static XmlDataProviderObject ConstructMiniAlbumObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MiniAlbum(owner, objectTypeCookie); + } + + internal MiniAlbum(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal bool Premium => (bool)this.GetProperty(nameof(Premium)); + + internal override Guid Id => (Guid)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/MiniArtist.cs b/ZuneXml/MiniArtist.cs new file mode 100644 index 0000000..715ee86 --- /dev/null +++ b/ZuneXml/MiniArtist.cs @@ -0,0 +1,30 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MiniArtist +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class MiniArtist : MiniMedia + { + internal static XmlDataProviderObject ConstructMiniArtistObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MiniArtist(owner, objectTypeCookie); + } + + internal MiniArtist(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override Guid Id => (Guid)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/MiniMedia.cs b/ZuneXml/MiniMedia.cs new file mode 100644 index 0000000..0bf08a9 --- /dev/null +++ b/ZuneXml/MiniMedia.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MiniMedia +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal abstract class MiniMedia : XmlDataProviderObject + { + protected MiniMedia(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract Guid Id { get; } + + internal abstract string Title { get; } + } +} diff --git a/ZuneXml/Mood.cs b/ZuneXml/Mood.cs new file mode 100644 index 0000000..766f3a6 --- /dev/null +++ b/ZuneXml/Mood.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Mood +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class Mood : XmlDataProviderObject + { + internal static XmlDataProviderObject ConstructMoodObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Mood(owner, objectTypeCookie); + } + + internal Mood(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string Id => (string)this.GetProperty(nameof(Id)); + + internal string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/Movie.cs b/ZuneXml/Movie.cs new file mode 100644 index 0000000..2ca5373 --- /dev/null +++ b/ZuneXml/Movie.cs @@ -0,0 +1,152 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Movie +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class Movie : RatableVideo + { + internal override int PointsPrice => this.GetPointsPrice(); + + internal int PointsRental => this.GetPointsRental(); + + internal override bool HasPreview => this.GetHasPreview(); + + internal override bool CanPreview => this.GetCanPreview(); + + internal override bool CanSubscriptionPlay => this.GetCanSubscriptionPlay(); + + internal override bool CanPurchase => this.GetCanPurchase(); + + internal override bool CanPurchaseHD => this.GetCanPurchaseHD(); + + internal override bool CanPurchaseSD => this.GetCanPurchaseSD(); + + internal override bool CanPurchaseSeason => false; + + internal override bool CanPurchaseSeasonHD => false; + + internal override bool CanPurchaseSeasonSD => false; + + internal override bool CanPurchaseAlbumOnly => false; + + internal override bool CanRent => this.GetCanRent(); + + internal override bool CanRentHD => this.GetCanRentHD(); + + internal override bool CanRentSD => this.GetCanRentSD(); + + internal override bool InCollection => this.GetInCollection(); + + internal override bool InCollectionShortcut => this.GetInCollectionShortcut(); + + internal override bool IsDownloading => this.GetIsDownloading(); + + internal override bool IsParentallyBlocked => this.GetIsParentallyBlocked(this.Rating); + + internal override MiniArtist PrimaryArtist => (MiniArtist)null; + + internal override IList Artists => (IList)null; + + internal IList Languages => this.Rights.Languages; + + internal static XmlDataProviderObject ConstructMovieObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Movie(owner, objectTypeCookie); + } + + internal Movie(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string ProductionCompany => (string)base.GetProperty(nameof(ProductionCompany)); + + internal IList Contributors => (IList)base.GetProperty(nameof(Contributors)); + + internal IList Genres => (IList)base.GetProperty(nameof(Genres)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override string Rating => (string)base.GetProperty(nameof(Rating)); + + internal override string Description => (string)base.GetProperty(nameof(Description)); + + internal override string SortTitle => (string)base.GetProperty(nameof(SortTitle)); + + internal override double Popularity => (double)base.GetProperty(nameof(Popularity)); + + internal override DateTime ReleaseDate => (DateTime)base.GetProperty(nameof(ReleaseDate)); + + internal override Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + internal override MediaRights Rights => (MediaRights)base.GetProperty(nameof(Rights)); + + internal override TimeSpan Duration => (TimeSpan)base.GetProperty(nameof(Duration)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "PointsRental": + return (object)this.PointsRental; + case "Languages": + return (object)this.Languages; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPreview": + return (object)this.HasPreview; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseHD": + return (object)this.CanPurchaseHD; + case "CanPurchaseSD": + return (object)this.CanPurchaseSD; + case "CanPurchaseSeason": + return (object)this.CanPurchaseSeason; + case "CanPurchaseSeasonHD": + return (object)this.CanPurchaseSeasonHD; + case "CanPurchaseSeasonSD": + return (object)this.CanPurchaseSeasonSD; + case "CanRent": + return (object)this.CanRent; + case "CanRentHD": + return (object)this.CanRentHD; + case "CanRentSD": + return (object)this.CanRentSD; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanSync": + return (object)this.CanSync; + case "InCollection": + return (object)this.InCollection; + case "InCollectionShortcut": + return (object)this.InCollectionShortcut; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "PrimaryArtist": + return (object)this.PrimaryArtist; + case "Artists": + return (object)this.Artists; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/MovieGenre.cs b/ZuneXml/MovieGenre.cs new file mode 100644 index 0000000..dce7c5b --- /dev/null +++ b/ZuneXml/MovieGenre.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MovieGenre +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class MovieGenre : Category + { + internal static XmlDataProviderObject ConstructMovieGenreObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MovieGenre(owner, objectTypeCookie); + } + + internal MovieGenre(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override string Id => (string)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/MovieStudio.cs b/ZuneXml/MovieStudio.cs new file mode 100644 index 0000000..e8c20b3 --- /dev/null +++ b/ZuneXml/MovieStudio.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MovieStudio +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class MovieStudio : Category + { + internal static XmlDataProviderObject ConstructMovieStudioObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MovieStudio(owner, objectTypeCookie); + } + + internal MovieStudio(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override string Id => (string)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/MovieTrailer.cs b/ZuneXml/MovieTrailer.cs new file mode 100644 index 0000000..6730bc2 --- /dev/null +++ b/ZuneXml/MovieTrailer.cs @@ -0,0 +1,80 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MovieTrailer +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class MovieTrailer : Movie + { + internal static XmlDataProviderObject ConstructMovieTrailerObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MovieTrailer(owner, objectTypeCookie); + } + + internal MovieTrailer(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "PointsRental": + return (object)this.PointsRental; + case "Languages": + return (object)this.Languages; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPreview": + return (object)this.HasPreview; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseHD": + return (object)this.CanPurchaseHD; + case "CanPurchaseSD": + return (object)this.CanPurchaseSD; + case "CanPurchaseSeason": + return (object)this.CanPurchaseSeason; + case "CanPurchaseSeasonHD": + return (object)this.CanPurchaseSeasonHD; + case "CanPurchaseSeasonSD": + return (object)this.CanPurchaseSeasonSD; + case "CanRent": + return (object)this.CanRent; + case "CanRentHD": + return (object)this.CanRentHD; + case "CanRentSD": + return (object)this.CanRentSD; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanSync": + return (object)this.CanSync; + case "InCollection": + return (object)this.InCollection; + case "InCollectionShortcut": + return (object)this.InCollectionShortcut; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "PrimaryArtist": + return (object)this.PrimaryArtist; + case "Artists": + return (object)this.Artists; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/MusicVideo.cs b/ZuneXml/MusicVideo.cs new file mode 100644 index 0000000..f7fd2b4 --- /dev/null +++ b/ZuneXml/MusicVideo.cs @@ -0,0 +1,172 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.MusicVideo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using Microsoft.Zune.Util; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class MusicVideo : Video + { + internal virtual int LibraryId + { + get => this.GetLibraryId(); + set => this.SetLibraryId(value); + } + + internal override bool CanSync => this.CanPurchase || this.InCollection || this.IsDownloading; + + internal override int PointsPrice + { + get + { + int num = -1; + Right right = this.Rights.GetOfferRight(MediaRightsEnum.Purchase, VideoDefinitionEnum.None, PriceTypeEnum.Points) ?? this.Rights.GetOfferRight(MediaRightsEnum.AlbumPurchase, VideoDefinitionEnum.None, PriceTypeEnum.Points); + if (right != null) + num = right.PointsPrice; + return num; + } + } + + internal override bool HasPreview => this.GetHasPreview(); + + internal override bool CanPreview => this.GetCanPreview(); + + internal override bool CanSubscriptionPlay => FeatureEnablement.IsFeatureEnabled(Features.eSubscriptionMusicVideoStreaming) && this.GetCanSubscriptionPlay(); + + internal override bool CanPurchase + { + get + { + if (this.Rights.HasRights(MediaRightsEnum.Purchase, VideoDefinitionEnum.None, PriceTypeEnum.Points)) + return true; + return this.Rights.HasRights(MediaRightsEnum.AlbumPurchase, VideoDefinitionEnum.None, PriceTypeEnum.Points) && this.Album.Id != Guid.Empty; + } + } + + internal override bool CanPurchaseHD => false; + + internal override bool CanPurchaseSD => false; + + internal override bool CanPurchaseSeason => false; + + internal override bool CanPurchaseSeasonHD => false; + + internal override bool CanPurchaseSeasonSD => false; + + internal override bool CanPurchaseAlbumOnly => this.GetCanPurchaseAlbumOnly(); + + internal override bool CanRent => false; + + internal override bool CanRentHD => false; + + internal override bool CanRentSD => false; + + internal override bool InCollection => this.GetInCollection(); + + internal override bool InCollectionShortcut => this.GetInCollectionShortcut(); + + internal override bool IsDownloading => this.GetIsDownloading(); + + internal override bool IsParentallyBlocked => this.Explicit && ZuneApplication.Service.BlockExplicitContent(); + + internal static XmlDataProviderObject ConstructMusicVideoObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new MusicVideo(owner, objectTypeCookie); + } + + internal MusicVideo(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string Label => (string)base.GetProperty(nameof(Label)); + + internal Guid TrackId => (Guid)base.GetProperty(nameof(TrackId)); + + internal MiniAlbum Album => (MiniAlbum)base.GetProperty(nameof(Album)); + + internal Genre PrimaryGenre => (Genre)base.GetProperty(nameof(PrimaryGenre)); + + internal bool Explicit => (bool)base.GetProperty(nameof(Explicit)); + + internal int TrackNumber => (int)base.GetProperty(nameof(TrackNumber)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override string SortTitle => (string)base.GetProperty(nameof(SortTitle)); + + internal override double Popularity => (double)base.GetProperty(nameof(Popularity)); + + internal override DateTime ReleaseDate => (DateTime)base.GetProperty(nameof(ReleaseDate)); + + internal override TimeSpan Duration => (TimeSpan)base.GetProperty(nameof(Duration)); + + internal override Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + internal override MiniArtist PrimaryArtist => (MiniArtist)base.GetProperty(nameof(PrimaryArtist)); + + internal override IList Artists => (IList)base.GetProperty(nameof(Artists)); + + internal override MediaRights Rights => (MediaRights)base.GetProperty(nameof(Rights)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "LibraryId": + return (object)this.LibraryId; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPreview": + return (object)this.HasPreview; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseHD": + return (object)this.CanPurchaseHD; + case "CanPurchaseSD": + return (object)this.CanPurchaseSD; + case "CanPurchaseSeason": + return (object)this.CanPurchaseSeason; + case "CanPurchaseSeasonHD": + return (object)this.CanPurchaseSeasonHD; + case "CanPurchaseSeasonSD": + return (object)this.CanPurchaseSeasonSD; + case "CanRent": + return (object)this.CanRent; + case "CanRentHD": + return (object)this.CanRentHD; + case "CanRentSD": + return (object)this.CanRentSD; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanSync": + return (object)this.CanSync; + case "InCollection": + return (object)this.InCollection; + case "InCollectionShortcut": + return (object)this.InCollectionShortcut; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/Network.cs b/ZuneXml/Network.cs new file mode 100644 index 0000000..a6582c4 --- /dev/null +++ b/ZuneXml/Network.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Network +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class Network : Category + { + internal static XmlDataProviderObject ConstructNetworkObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Network(owner, objectTypeCookie); + } + + internal Network(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override string Id => (string)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/PlaylistTrack.cs b/ZuneXml/PlaylistTrack.cs new file mode 100644 index 0000000..4a8196d --- /dev/null +++ b/ZuneXml/PlaylistTrack.cs @@ -0,0 +1,80 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.PlaylistTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class PlaylistTrack : Track + { + internal static XmlDataProviderObject ConstructPlaylistTrackObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new PlaylistTrack(owner, objectTypeCookie); + } + + internal PlaylistTrack(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal int Index => (int)base.GetProperty(nameof(Index)); + + internal string Content => (string)base.GetProperty(nameof(Content)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Actionable": + return (object)this.Actionable; + case "UserRating": + return (object)this.UserRating; + case "LibraryId": + return (object)this.LibraryId; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPoints": + return (object)this.HasPoints; + case "CanPlay": + return (object)this.CanPlay; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanDownload": + return (object)this.CanDownload; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFree": + return (object)this.CanPurchaseFree; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanPurchaseSubscriptionFree": + return (object)this.CanPurchaseSubscriptionFree; + case "CanSync": + return (object)this.CanSync; + case "CanBurn": + return (object)this.CanBurn; + case "InCollection": + return (object)this.InCollection; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "Ordinal": + return (object)this.Ordinal; + case "ImageId": + return (object)this.ImageId; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/PodcastCatalogServiceQueryHelper.cs b/ZuneXml/PodcastCatalogServiceQueryHelper.cs new file mode 100644 index 0000000..a63500a --- /dev/null +++ b/ZuneXml/PodcastCatalogServiceQueryHelper.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.PodcastCatalogServiceQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text; + +namespace ZuneXml +{ + internal class PodcastCatalogServiceQueryHelper : CatalogServiceQueryHelper + { + internal static ZuneServiceQueryHelper ConstructPodcastCatalogQueryHelper( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new PodcastCatalogServiceQueryHelper(query); + } + + internal PodcastCatalogServiceQueryHelper(ZuneServiceQuery query) + : base(query) + { + } + + protected override bool RequireId => false; + + protected override bool RequireResource => false; + + protected override bool RequireRepresentation => false; + + protected override void AppendStuffAfterRepresentation( + StringBuilder requestUri, + ref bool fFirst) + { + base.AppendStuffAfterRepresentation(requestUri, ref fFirst); + string property1 = (string)this.Query.GetProperty("PodcastType"); + if (!string.IsNullOrEmpty(property1)) + ZuneServiceQueryHelper.AppendParam(requestUri, "type", property1, ref fFirst); + string property2 = (string)this.Query.GetProperty("PodcastUrl"); + if (string.IsNullOrEmpty(property2)) + return; + ZuneServiceQueryHelper.AppendParam(requestUri, "url", property2, ref fFirst); + } + + internal override string GetQueryPostBody() + { + string property = (string)this.Query.GetProperty("PostUrl"); + return !string.IsNullOrEmpty(property) ? "URL=" + property : (string)null; + } + } +} diff --git a/ZuneXml/PodcastSeries.cs b/ZuneXml/PodcastSeries.cs new file mode 100644 index 0000000..83a039c --- /dev/null +++ b/ZuneXml/PodcastSeries.cs @@ -0,0 +1,104 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.PodcastSeries +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class PodcastSeries : Media + { + private int _dbMediaId = -1; + + internal override MediaRights Rights => (MediaRights)null; + + internal override MiniArtist PrimaryArtist => (MiniArtist)null; + + internal override IList Artists => (IList)null; + + internal override double Popularity => 0.0; + + internal virtual int LibraryId + { + get => this.GetLibraryId(); + set + { + if (this._dbMediaId == value) + return; + this._dbMediaId = value; + this.FirePropertyChanged(nameof(LibraryId)); + } + } + + protected int GetLibraryId() + { + int dbMediaId = -1; + if (this.Id != Guid.Empty) + ZuneApplication.Service.InVisibleCollection(this.Id, EContentType.PodcastSeries, out dbMediaId); + return dbMediaId; + } + + internal static XmlDataProviderObject ConstructPodcastSeriesObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new PodcastSeries(owner, objectTypeCookie); + } + + internal PodcastSeries(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string ShortDescription => (string)base.GetProperty(nameof(ShortDescription)); + + internal string LongDescription => (string)base.GetProperty(nameof(LongDescription)); + + internal bool Explicit => (bool)base.GetProperty(nameof(Explicit)); + + internal string Author => (string)base.GetProperty(nameof(Author)); + + internal string SourceUrl => (string)base.GetProperty(nameof(SourceUrl)); + + internal DateTime ReleaseDate => (DateTime)base.GetProperty(nameof(ReleaseDate)); + + internal IList Categories => (IList)base.GetProperty(nameof(Categories)); + + internal string Type => (string)base.GetProperty(nameof(Type)); + + internal string WebsiteUrl => (string)base.GetProperty(nameof(WebsiteUrl)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override string SortTitle => (string)base.GetProperty(nameof(SortTitle)); + + internal override Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "LibraryId": + return (object)this.LibraryId; + case "Rights": + return (object)this.Rights; + case "PrimaryArtist": + return (object)this.PrimaryArtist; + case "Artists": + return (object)this.Artists; + case "Popularity": + return (object)this.Popularity; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/PodcastSubCategory.cs b/ZuneXml/PodcastSubCategory.cs new file mode 100644 index 0000000..3aec33e --- /dev/null +++ b/ZuneXml/PodcastSubCategory.cs @@ -0,0 +1,18 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.PodcastSubCategory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal abstract class PodcastSubCategory : Category + { + protected PodcastSubCategory(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + } +} diff --git a/ZuneXml/PriceTypeEnum.cs b/ZuneXml/PriceTypeEnum.cs new file mode 100644 index 0000000..5038e96 --- /dev/null +++ b/ZuneXml/PriceTypeEnum.cs @@ -0,0 +1,15 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.PriceTypeEnum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal enum PriceTypeEnum + { + None, + Points, + Currency, + } +} diff --git a/ZuneXml/ProfileTrack.cs b/ZuneXml/ProfileTrack.cs new file mode 100644 index 0000000..993e63a --- /dev/null +++ b/ZuneXml/ProfileTrack.cs @@ -0,0 +1,81 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ProfileTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class ProfileTrack : PlaylistTrack + { + internal static XmlDataProviderObject ConstructProfileTrackObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ProfileTrack(owner, objectTypeCookie); + } + + internal ProfileTrack(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string TopArtistName => (string)base.GetProperty(nameof(TopArtistName)); + + internal Guid TopArtistId => (Guid)base.GetProperty(nameof(TopArtistId)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Actionable": + return (object)this.Actionable; + case "UserRating": + return (object)this.UserRating; + case "LibraryId": + return (object)this.LibraryId; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPoints": + return (object)this.HasPoints; + case "CanPlay": + return (object)this.CanPlay; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanDownload": + return (object)this.CanDownload; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFree": + return (object)this.CanPurchaseFree; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanPurchaseSubscriptionFree": + return (object)this.CanPurchaseSubscriptionFree; + case "CanSync": + return (object)this.CanSync; + case "CanBurn": + return (object)this.CanBurn; + case "InCollection": + return (object)this.InCollection; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "Ordinal": + return (object)this.Ordinal; + case "ImageId": + return (object)this.ImageId; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/PropertyComparer`1.cs b/ZuneXml/PropertyComparer`1.cs new file mode 100644 index 0000000..3c84521 --- /dev/null +++ b/ZuneXml/PropertyComparer`1.cs @@ -0,0 +1,56 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.PropertyComparer`1 +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Collections; + +namespace ZuneXml +{ + public class PropertyComparer : IComparer where TPropertyType : IComparable + { + private Converter _propertyGetter; + private bool _sortDescending; + + public PropertyComparer(Converter propertyGetter, bool sortDescending) + { + this._propertyGetter = propertyGetter != null ? propertyGetter : throw new ArgumentNullException(nameof(propertyGetter)); + this._sortDescending = sortDescending; + } + + public int Compare(object x, object y) + { + int comparisonResult = 0; + if (!PropertyComparer.IsNullComparison(x, y, out comparisonResult)) + { + TPropertyType propertyType = this._propertyGetter(x); + TPropertyType other = this._propertyGetter(y); + if (!PropertyComparer.IsNullComparison((object)propertyType, (object)other, out comparisonResult)) + comparisonResult = propertyType.CompareTo(other); + } + if (this._sortDescending) + comparisonResult = -comparisonResult; + return comparisonResult; + } + + private static bool IsNullComparison(object x, object y, out int comparisonResult) + { + comparisonResult = 0; + bool flag = false; + if (x == null) + { + flag = true; + if (y != null) + comparisonResult = -1; + } + if (y == null) + { + flag = true; + comparisonResult = 1; + } + return flag; + } + } +} diff --git a/ZuneXml/PurchaseHistoryQueryHelper.cs b/ZuneXml/PurchaseHistoryQueryHelper.cs new file mode 100644 index 0000000..b4cdb4b --- /dev/null +++ b/ZuneXml/PurchaseHistoryQueryHelper.cs @@ -0,0 +1,47 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.PurchaseHistoryQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; + +namespace ZuneXml +{ + internal class PurchaseHistoryQueryHelper : HistoryQueryHelper + { + internal static PurchaseHistoryQueryHelper ConstructPurchaseHistoryQueryHelper( + ZuneServiceQuery query) + { + return new PurchaseHistoryQueryHelper(query); + } + + internal PurchaseHistoryQueryHelper(ZuneServiceQuery query) + : base(query) + => this._api = "/billing/purchaseHistory"; + + internal override bool OnQueryFilterDataProviderObject(XmlDataProviderObject dataObject) + { + bool flag1 = false; + if (dataObject is VideoHistory) + { + bool flag2 = false; + VideoHistory videoHistory = (VideoHistory)dataObject; + if (videoHistory.MediaInstances != null) + { + foreach (MediaInstance mediaInstance in (IEnumerable)videoHistory.MediaInstances) + { + if (mediaInstance.LicenseRight == "Rent" || mediaInstance.LicenseRight == "RentStream") + { + flag2 = true; + break; + } + } + } + bool flag3 = !(this.Query.GetProperty("Rentals") is bool property) || !property; + flag1 = flag2 == flag3; + } + return flag1; + } + } +} diff --git a/ZuneXml/RatableVideo.cs b/ZuneXml/RatableVideo.cs new file mode 100644 index 0000000..f890dc7 --- /dev/null +++ b/ZuneXml/RatableVideo.cs @@ -0,0 +1,65 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.RatableVideo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneXml +{ + internal abstract class RatableVideo : Video + { + internal override bool CanSync => false; + + internal override int PointsPrice => this.GetPointsPrice(); + + internal override bool HasPreview => this.GetHasPreview(); + + internal override bool CanPreview => this.GetCanPreview(); + + internal override bool CanSubscriptionPlay => this.GetCanSubscriptionPlay(); + + internal override bool CanPurchase => this.GetCanPurchase(); + + internal override bool CanPurchaseHD => this.GetCanPurchaseHD(); + + internal override bool CanPurchaseSD => this.GetCanPurchaseSD(); + + internal override bool CanPurchaseSeason => this.GetCanPurchaseSeason(); + + internal override bool CanPurchaseSeasonHD => this.GetCanPurchaseSeasonHD(); + + internal override bool CanPurchaseSeasonSD => this.GetCanPurchaseSeasonSD(); + + internal override bool CanPurchaseAlbumOnly => false; + + internal override bool CanRent => this.GetCanRent(); + + internal override bool CanRentHD => this.GetCanRentHD(); + + internal override bool CanRentSD => this.GetCanRentSD(); + + internal override bool InCollection => this.GetInCollection(); + + internal override bool InCollectionShortcut => this.GetInCollectionShortcut(); + + internal override bool IsDownloading => this.GetIsDownloading(); + + internal override bool IsParentallyBlocked => this.GetIsParentallyBlocked(this.Rating); + + internal override MiniArtist PrimaryArtist => (MiniArtist)null; + + internal override IList Artists => (IList)null; + + protected RatableVideo(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract string Description { get; } + + internal abstract string Rating { get; } + } +} diff --git a/ZuneXml/Reason.cs b/ZuneXml/Reason.cs new file mode 100644 index 0000000..eb577cd --- /dev/null +++ b/ZuneXml/Reason.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Reason +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class Reason : XmlDataProviderObject + { + internal static XmlDataProviderObject ConstructReasonObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Reason(owner, objectTypeCookie); + } + + internal Reason(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string Description => (string)this.GetProperty(nameof(Description)); + } +} diff --git a/ZuneXml/RecommendationsQueryHelper.cs b/ZuneXml/RecommendationsQueryHelper.cs new file mode 100644 index 0000000..8736e59 --- /dev/null +++ b/ZuneXml/RecommendationsQueryHelper.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.RecommendationsQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneXml +{ + internal class RecommendationsQueryHelper : CatalogServiceQueryHelper + { + internal static ZuneServiceQueryHelper ConstructRecommendationsQueryHelper( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new RecommendationsQueryHelper(query); + } + + internal RecommendationsQueryHelper(ZuneServiceQuery query) + : base(query) + { + this._endPoint = EServiceEndpointId.SEID_Recommendations; + query.CachePolicy = HttpRequestCachePolicy.BypassCache; + } + } +} diff --git a/ZuneXml/RecommendedAlbum.cs b/ZuneXml/RecommendedAlbum.cs new file mode 100644 index 0000000..0aef2f1 --- /dev/null +++ b/ZuneXml/RecommendedAlbum.cs @@ -0,0 +1,49 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.RecommendedAlbum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneXml +{ + internal class RecommendedAlbum : Album + { + internal static XmlDataProviderObject ConstructRecommendedAlbumObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new RecommendedAlbum(owner, objectTypeCookie); + } + + internal RecommendedAlbum(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal IList Reasons => (IList)base.GetProperty(nameof(Reasons)); + + internal string ReferrerContext => (string)base.GetProperty(nameof(ReferrerContext)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "PointsPrice": + return (object)this.PointsPrice; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "InCollection": + return (object)this.InCollection; + case "LibraryId": + return (object)this.LibraryId; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/RecommendedArtist.cs b/ZuneXml/RecommendedArtist.cs new file mode 100644 index 0000000..6b2a43d --- /dev/null +++ b/ZuneXml/RecommendedArtist.cs @@ -0,0 +1,30 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.RecommendedArtist +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneXml +{ + internal class RecommendedArtist : Artist + { + internal static XmlDataProviderObject ConstructRecommendedArtistObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new RecommendedArtist(owner, objectTypeCookie); + } + + internal RecommendedArtist(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal IList Reasons => (IList)this.GetProperty(nameof(Reasons)); + + internal string ReferrerContext => (string)this.GetProperty(nameof(ReferrerContext)); + } +} diff --git a/ZuneXml/RecommendedTrack.cs b/ZuneXml/RecommendedTrack.cs new file mode 100644 index 0000000..9dd4593 --- /dev/null +++ b/ZuneXml/RecommendedTrack.cs @@ -0,0 +1,77 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.RecommendedTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections; + +namespace ZuneXml +{ + internal class RecommendedTrack : PlaylistTrack + { + internal static XmlDataProviderObject ConstructRecommendedTrackObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new RecommendedTrack(owner, objectTypeCookie); + } + + internal RecommendedTrack(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal IList Reasons => (IList)base.GetProperty(nameof(Reasons)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Actionable": + return (object)this.Actionable; + case "UserRating": + return (object)this.UserRating; + case "LibraryId": + return (object)this.LibraryId; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPoints": + return (object)this.HasPoints; + case "CanPlay": + return (object)this.CanPlay; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanDownload": + return (object)this.CanDownload; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFree": + return (object)this.CanPurchaseFree; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanPurchaseSubscriptionFree": + return (object)this.CanPurchaseSubscriptionFree; + case "CanSync": + return (object)this.CanSync; + case "CanBurn": + return (object)this.CanBurn; + case "InCollection": + return (object)this.InCollection; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "Ordinal": + return (object)this.Ordinal; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/Review.cs b/ZuneXml/Review.cs new file mode 100644 index 0000000..636fa14 --- /dev/null +++ b/ZuneXml/Review.cs @@ -0,0 +1,36 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Review +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class Review : XmlDataProviderObject + { + internal static XmlDataProviderObject ConstructReviewObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Review(owner, objectTypeCookie); + } + + internal Review(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal DateTime Date => (DateTime)this.GetProperty(nameof(Date)); + + internal string Title => (string)this.GetProperty(nameof(Title)); + + internal string Comment => (string)this.GetProperty(nameof(Comment)); + + internal string UserName => (string)this.GetProperty(nameof(UserName)); + + internal float Rating => (float)this.GetProperty(nameof(Rating)); + } +} diff --git a/ZuneXml/ReviewListEntry.cs b/ZuneXml/ReviewListEntry.cs new file mode 100644 index 0000000..66a8621 --- /dev/null +++ b/ZuneXml/ReviewListEntry.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ReviewListEntry +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class ReviewListEntry : Review + { + internal static XmlDataProviderObject ConstructReviewListEntryObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ReviewListEntry(owner, objectTypeCookie); + } + + internal ReviewListEntry(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + } +} diff --git a/ZuneXml/ReviewsQueryHelper.cs b/ZuneXml/ReviewsQueryHelper.cs new file mode 100644 index 0000000..bfa74cc --- /dev/null +++ b/ZuneXml/ReviewsQueryHelper.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ReviewsQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneXml +{ + internal class ReviewsQueryHelper : SubRepresentationCatalogServiceQueryHelper + { + internal static ZuneServiceQueryHelper ConstructReviewsQueryHelper( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new ReviewsQueryHelper(query); + } + + internal ReviewsQueryHelper(ZuneServiceQuery query) + : base(query) + => this._endPoint = EServiceEndpointId.SEID_Stats; + } +} diff --git a/ZuneXml/Right.cs b/ZuneXml/Right.cs new file mode 100644 index 0000000..735a9c6 --- /dev/null +++ b/ZuneXml/Right.cs @@ -0,0 +1,226 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Right +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using ZuneUI; + +namespace ZuneXml +{ + internal class Right : XmlDataProviderObject + { + private MediaRightsEnum _rightEnum; + private AudioEncodingEnum _audioEncodingEnum; + private VideoDefinitionEnum _videoDefinitionEnum; + private VideoResolutionEnum _videoResolutionEnum; + private ClientTypeEnum _clientTypeEnum; + private PriceTypeEnum _priceTypeEnum; + + public bool HasPoints => this.PriceTypeEnum == PriceTypeEnum.Points; + + public bool HasCurrency => this.PriceTypeEnum == PriceTypeEnum.Currency; + + public int PointsPrice => this.HasPoints ? (int)this.Price : 0; + + public double CurrencyPrice => this.HasCurrency ? this.Price : 0.0; + + public bool IsFree + { + get + { + if (this.HasPoints && this.PointsPrice <= 0) + return true; + return this.HasCurrency && this.CurrencyPrice <= 0.0; + } + } + + public string Language + { + get + { + string str = (string)null; + if (!string.IsNullOrEmpty(this.AudioLocale)) + { + string displayLanguageName1 = LanguageHelper.GetDisplayLanguageName(this.AudioLocale); + if (!string.IsNullOrEmpty(displayLanguageName1)) + { + str = displayLanguageName1; + if (!string.IsNullOrEmpty(this.SubtitleLocale)) + { + string displayLanguageName2 = LanguageHelper.GetDisplayLanguageName(this.SubtitleLocale); + if (!string.IsNullOrEmpty(displayLanguageName2)) + str = string.Format(Shell.LoadString(StringId.IDS_VIDEO_SUBTITLE), (object)displayLanguageName1, (object)displayLanguageName2); + } + } + } + return str; + } + } + + internal MediaRightsEnum RightEnum + { + get => this._rightEnum; + set + { + if (this._rightEnum == value) + return; + this._rightEnum = value; + this.FirePropertyChanged(nameof(RightEnum)); + } + } + + internal AudioEncodingEnum AudioEncodingEnum + { + get => this._audioEncodingEnum; + set + { + if (this._audioEncodingEnum == value) + return; + this._audioEncodingEnum = value; + this.FirePropertyChanged(nameof(AudioEncodingEnum)); + } + } + + internal VideoDefinitionEnum VideoDefinitionEnum + { + get => this._videoDefinitionEnum; + set + { + if (this._videoDefinitionEnum == value) + return; + this._videoDefinitionEnum = value; + this.FirePropertyChanged(nameof(VideoDefinitionEnum)); + } + } + + internal VideoResolutionEnum VideoResolutionEnum + { + get => this._videoResolutionEnum; + set + { + if (this._videoResolutionEnum == value) + return; + this._videoResolutionEnum = value; + this.FirePropertyChanged(nameof(VideoResolutionEnum)); + } + } + + internal ClientTypeEnum ClientTypeEnum + { + get => this._clientTypeEnum; + set + { + if (this._clientTypeEnum == value) + return; + this._clientTypeEnum = value; + this.FirePropertyChanged(nameof(ClientTypeEnum)); + } + } + + internal PriceTypeEnum PriceTypeEnum + { + get => this._priceTypeEnum; + set + { + if (this._priceTypeEnum == value) + return; + this._priceTypeEnum = value; + this.FirePropertyChanged(nameof(PriceTypeEnum)); + this.FirePropertyChanged("HasPoints"); + this.FirePropertyChanged("HasCurrency"); + } + } + + public override void SetProperty(string propertyName, object value) + { + switch (propertyName) + { + case "LicenseRight": + this.RightEnum = SchemaHelper.ToMediaRights((string)value); + break; + case "AudioEncoding": + this.AudioEncodingEnum = SchemaHelper.ToAudioEncoding((string)value); + break; + case "VideoDefinition": + this.VideoDefinitionEnum = SchemaHelper.ToVideoDefinition((string)value); + break; + case "VideoResolution": + this.VideoResolutionEnum = SchemaHelper.ToVideoResolution((string)value); + break; + case "ClientType": + this.ClientTypeEnum = SchemaHelper.ToClientType((string)value); + break; + case "CurrencyCode": + this.PriceTypeEnum = SchemaHelper.ToPriceType((string)value); + break; + } + base.SetProperty(propertyName, value); + } + + internal static XmlDataProviderObject ConstructRightObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Right(owner, objectTypeCookie); + } + + internal Right(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal string LicenseType => (string)base.GetProperty(nameof(LicenseType)); + + internal string LicenseRight => (string)base.GetProperty(nameof(LicenseRight)); + + internal string ProviderName => (string)base.GetProperty(nameof(ProviderName)); + + internal string ProviderCode => (string)base.GetProperty(nameof(ProviderCode)); + + internal Guid OfferId => (Guid)base.GetProperty(nameof(OfferId)); + + internal double Price => (double)base.GetProperty(nameof(Price)); + + internal double OriginalPrice => (double)base.GetProperty(nameof(OriginalPrice)); + + internal string CurrencyCode => (string)base.GetProperty(nameof(CurrencyCode)); + + internal string DisplayPrice => (string)base.GetProperty(nameof(DisplayPrice)); + + internal string AudioEncoding => (string)base.GetProperty(nameof(AudioEncoding)); + + internal string AudioLocale => (string)base.GetProperty(nameof(AudioLocale)); + + internal string SubtitleLocale => (string)base.GetProperty(nameof(SubtitleLocale)); + + internal string VideoEncoding => (string)base.GetProperty(nameof(VideoEncoding)); + + internal string VideoDefinition => (string)base.GetProperty(nameof(VideoDefinition)); + + internal string VideoResolution => (string)base.GetProperty(nameof(VideoResolution)); + + internal string ClientType => (string)base.GetProperty(nameof(ClientType)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "HasPoints": + return (object)this.HasPoints; + case "HasCurrency": + return (object)this.HasCurrency; + case "PointsPrice": + return (object)this.PointsPrice; + case "CurrencyPrice": + return (object)this.CurrencyPrice; + case "Language": + return (object)this.Language; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/SchemaHelper.cs b/ZuneXml/SchemaHelper.cs new file mode 100644 index 0000000..267a0ea --- /dev/null +++ b/ZuneXml/SchemaHelper.cs @@ -0,0 +1,264 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.SchemaHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal class SchemaHelper + { + internal static MediaRightsEnum ToMediaRights(string value) + { + MediaRightsEnum mediaRightsEnum = MediaRightsEnum.None; + if (!string.IsNullOrEmpty(value)) + { + switch (value) + { + case "Preview": + mediaRightsEnum = MediaRightsEnum.Preview; + break; + case "PreviewStream": + mediaRightsEnum = MediaRightsEnum.PreviewStream; + break; + case "Stream": + mediaRightsEnum = MediaRightsEnum.SubscriptionStream; + break; + case "Subscription": + mediaRightsEnum = MediaRightsEnum.SubscriptionDownload; + break; + case "Purchase": + mediaRightsEnum = MediaRightsEnum.Purchase; + break; + case "PurchaseStream": + mediaRightsEnum = MediaRightsEnum.PurchaseStream; + break; + case "SeasonPurchase": + mediaRightsEnum = MediaRightsEnum.SeasonPurchase; + break; + case "SeasonPurchaseStream": + mediaRightsEnum = MediaRightsEnum.SeasonPurchaseStream; + break; + case "AlbumPurchase": + mediaRightsEnum = MediaRightsEnum.AlbumPurchase; + break; + case "SubscriptionFree": + mediaRightsEnum = MediaRightsEnum.SubscriptionFreePurchase; + break; + case "TransferToPortableDevice": + mediaRightsEnum = MediaRightsEnum.TransferToPortableDevice; + break; + case "Rent": + mediaRightsEnum = MediaRightsEnum.Rent; + break; + case "RentStream": + mediaRightsEnum = MediaRightsEnum.RentStream; + break; + case "Trial": + mediaRightsEnum = MediaRightsEnum.PurchaseTrial; + break; + case "Download": + mediaRightsEnum = MediaRightsEnum.Download; + break; + case "Beta": + mediaRightsEnum = MediaRightsEnum.PurchaseBeta; + break; + } + } + return mediaRightsEnum; + } + + internal static AudioEncodingEnum ToAudioEncoding(string value) + { + AudioEncodingEnum audioEncodingEnum = AudioEncodingEnum.None; + if (!string.IsNullOrEmpty(value)) + { + switch (value) + { + case "MP3": + audioEncodingEnum = AudioEncodingEnum.MP3; + break; + case "WMA": + audioEncodingEnum = AudioEncodingEnum.WMA; + break; + } + } + return audioEncodingEnum; + } + + internal static VideoResolutionEnum ToVideoResolution(string value) + { + VideoResolutionEnum videoResolutionEnum = VideoResolutionEnum.None; + if (!string.IsNullOrEmpty(value)) + { + switch (value) + { + case "1080p": + videoResolutionEnum = VideoResolutionEnum.VR_1080P; + break; + case "720p": + videoResolutionEnum = VideoResolutionEnum.VR_720P; + break; + case "480p": + videoResolutionEnum = VideoResolutionEnum.VR_480P; + break; + case "240p": + videoResolutionEnum = VideoResolutionEnum.VR_240P; + break; + } + } + return videoResolutionEnum; + } + + internal static VideoDefinitionEnum ToVideoDefinition(string value) + { + VideoDefinitionEnum videoDefinitionEnum = VideoDefinitionEnum.None; + if (!string.IsNullOrEmpty(value)) + { + switch (value) + { + case "HD": + videoDefinitionEnum = VideoDefinitionEnum.HD; + break; + case "SD": + videoDefinitionEnum = VideoDefinitionEnum.SD; + break; + case "XD": + videoDefinitionEnum = VideoDefinitionEnum.XD; + break; + } + } + return videoDefinitionEnum; + } + + internal static ClientTypeEnum ToClientType(string value) + { + ClientTypeEnum clientTypeEnum = ClientTypeEnum.None; + if (!string.IsNullOrEmpty(value)) + { + switch (value) + { + case "Zune 3.0": + clientTypeEnum = ClientTypeEnum.Zune; + break; + case "WinMobile 7.0": + case "WinMobile 7.1": + clientTypeEnum = ClientTypeEnum.WindowsPhone; + break; + } + } + return clientTypeEnum; + } + + internal static DisclosureEnum ToDisclosureEnum(string value) + { + DisclosureEnum disclosureEnum = DisclosureEnum.None; + if (!string.IsNullOrEmpty(value)) + { + switch (value) + { + case "Disclose": + disclosureEnum = DisclosureEnum.Disclose; + break; + case "DiscloseANDPrompt": + disclosureEnum = DisclosureEnum.DiscloseAndPrompt; + break; + case "Prompt": + disclosureEnum = DisclosureEnum.Prompt; + break; + } + } + return disclosureEnum; + } + + internal static PriceTypeEnum ToPriceType(string value) + { + PriceTypeEnum priceTypeEnum = PriceTypeEnum.None; + if (!string.IsNullOrEmpty(value)) + { + switch (value.ToUpper()) + { + case "MPT": + priceTypeEnum = PriceTypeEnum.Points; + break; + default: + priceTypeEnum = PriceTypeEnum.Currency; + break; + } + } + return priceTypeEnum; + } + + internal static MessageTypeEnum ToMessageType(string value) + { + MessageTypeEnum messageTypeEnum = MessageTypeEnum.Invalid; + if (!string.IsNullOrEmpty(value)) + { + switch (value) + { + case "album": + messageTypeEnum = MessageTypeEnum.Album; + break; + case "card": + messageTypeEnum = MessageTypeEnum.Card; + break; + case "forums": + messageTypeEnum = MessageTypeEnum.Forums; + break; + case "friendrequest": + messageTypeEnum = MessageTypeEnum.FriendRequest; + break; + case "message": + messageTypeEnum = MessageTypeEnum.Message; + break; + case "musicvideo": + messageTypeEnum = MessageTypeEnum.MusicVideo; + break; + case "notification": + messageTypeEnum = MessageTypeEnum.Notification; + break; + case "photos": + messageTypeEnum = MessageTypeEnum.Photos; + break; + case "playlist": + messageTypeEnum = MessageTypeEnum.Playlist; + break; + case "podcast": + messageTypeEnum = MessageTypeEnum.Podcast; + break; + case "song": + messageTypeEnum = MessageTypeEnum.Song; + break; + case "video": + messageTypeEnum = MessageTypeEnum.Video; + break; + case "movie": + messageTypeEnum = MessageTypeEnum.Movie; + break; + case "movietrailer": + messageTypeEnum = MessageTypeEnum.MovieTrailer; + break; + default: + messageTypeEnum = MessageTypeEnum.Invalid; + break; + } + } + return messageTypeEnum; + } + + internal static MediaTypeEnum ToMediaTypeEnum(string value) + { + MediaTypeEnum mediaTypeEnum = MediaTypeEnum.None; + if (!string.IsNullOrEmpty(value)) + { + switch (value) + { + case "TVSeason": + mediaTypeEnum = MediaTypeEnum.TVSeason; + break; + } + } + return mediaTypeEnum; + } + } +} diff --git a/ZuneXml/Season.cs b/ZuneXml/Season.cs new file mode 100644 index 0000000..eccb75c --- /dev/null +++ b/ZuneXml/Season.cs @@ -0,0 +1,64 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Season +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class Season : XmlDataProviderObject + { + internal bool IsPriceDiscounted + { + get + { + Right right = this.Rights.GetOfferRight(MediaRightsEnum.SeasonPurchase, ClientTypeEnum.None, PriceTypeEnum.Points) ?? this.Rights.GetOfferRight(MediaRightsEnum.SeasonPurchaseStream, ClientTypeEnum.None, PriceTypeEnum.Points); + return right != null && right.Price < right.OriginalPrice; + } + } + + internal static XmlDataProviderObject ConstructSeasonObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Season(owner, objectTypeCookie); + } + + internal Season(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal int Id => (int)base.GetProperty(nameof(Id)); + + internal string Title => (string)base.GetProperty(nameof(Title)); + + internal Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + internal DateTime ReleaseDate => (DateTime)base.GetProperty(nameof(ReleaseDate)); + + internal int EpisodeCount => (int)base.GetProperty(nameof(EpisodeCount)); + + internal string Description => (string)base.GetProperty(nameof(Description)); + + internal string Rating => (string)base.GetProperty(nameof(Rating)); + + internal MediaRights Rights => (MediaRights)base.GetProperty(nameof(Rights)); + + internal bool IsComplete => (bool)base.GetProperty(nameof(IsComplete)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "IsPriceDiscounted": + return (object)this.IsPriceDiscounted; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/Series.cs b/ZuneXml/Series.cs new file mode 100644 index 0000000..daf230f --- /dev/null +++ b/ZuneXml/Series.cs @@ -0,0 +1,72 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Series +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class Series : Media + { + internal override MediaRights Rights => (MediaRights)null; + + internal override MiniArtist PrimaryArtist => (MiniArtist)null; + + internal override IList Artists => (IList)null; + + internal static XmlDataProviderObject ConstructSeriesObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Series(owner, objectTypeCookie); + } + + internal Series(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal DateTime ReleaseDate => (DateTime)base.GetProperty(nameof(ReleaseDate)); + + internal string Rating => (string)base.GetProperty(nameof(Rating)); + + internal int SeasonCount => (int)base.GetProperty(nameof(SeasonCount)); + + internal string ProductionCompany => (string)base.GetProperty(nameof(ProductionCompany)); + + internal string Description => (string)base.GetProperty(nameof(Description)); + + internal IList Categories => (IList)base.GetProperty(nameof(Categories)); + + internal Network Network => (Network)base.GetProperty(nameof(Network)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + internal override string SortTitle => (string)base.GetProperty(nameof(SortTitle)); + + internal override double Popularity => (double)base.GetProperty(nameof(Popularity)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Rights": + return (object)this.Rights; + case "PrimaryArtist": + return (object)this.PrimaryArtist; + case "Artists": + return (object)this.Artists; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/SeriesCategory.cs b/ZuneXml/SeriesCategory.cs new file mode 100644 index 0000000..8f4479c --- /dev/null +++ b/ZuneXml/SeriesCategory.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.SeriesCategory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class SeriesCategory : PodcastSubCategory + { + internal static XmlDataProviderObject ConstructSeriesCategoryObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new SeriesCategory(owner, objectTypeCookie); + } + + internal SeriesCategory(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override string Id => (string)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/Short.cs b/ZuneXml/Short.cs new file mode 100644 index 0000000..bda1032 --- /dev/null +++ b/ZuneXml/Short.cs @@ -0,0 +1,105 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Short +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal class Short : TVVideo + { + internal static XmlDataProviderObject ConstructShortObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Short(owner, objectTypeCookie); + } + + internal Short(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal Guid BackgroundImageId => (Guid)base.GetProperty(nameof(BackgroundImageId)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override string SortTitle => (string)base.GetProperty(nameof(SortTitle)); + + internal override string Description => (string)base.GetProperty(nameof(Description)); + + internal override DateTime ReleaseDate => (DateTime)base.GetProperty(nameof(ReleaseDate)); + + internal override string Copyright => (string)base.GetProperty(nameof(Copyright)); + + internal override string Rating => (string)base.GetProperty(nameof(Rating)); + + internal override TimeSpan Duration => (TimeSpan)base.GetProperty(nameof(Duration)); + + internal override string ProductionCompany => (string)base.GetProperty(nameof(ProductionCompany)); + + internal override Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + internal override MediaRights Rights => (MediaRights)base.GetProperty(nameof(Rights)); + + internal override Network Network => (Network)base.GetProperty(nameof(Network)); + + internal override double Popularity => (double)base.GetProperty(nameof(Popularity)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPreview": + return (object)this.HasPreview; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseHD": + return (object)this.CanPurchaseHD; + case "CanPurchaseSD": + return (object)this.CanPurchaseSD; + case "CanPurchaseSeason": + return (object)this.CanPurchaseSeason; + case "CanPurchaseSeasonHD": + return (object)this.CanPurchaseSeasonHD; + case "CanPurchaseSeasonSD": + return (object)this.CanPurchaseSeasonSD; + case "CanRent": + return (object)this.CanRent; + case "CanRentHD": + return (object)this.CanRentHD; + case "CanRentSD": + return (object)this.CanRentSD; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanSync": + return (object)this.CanSync; + case "InCollection": + return (object)this.InCollection; + case "InCollectionShortcut": + return (object)this.InCollectionShortcut; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "PrimaryArtist": + return (object)this.PrimaryArtist; + case "Artists": + return (object)this.Artists; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/SocialQueryHelper.cs b/ZuneXml/SocialQueryHelper.cs new file mode 100644 index 0000000..73946fa --- /dev/null +++ b/ZuneXml/SocialQueryHelper.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.SocialQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System; +using System.Text; +using ZuneUI; + +namespace ZuneXml +{ + internal class SocialQueryHelper : ZuneServiceQueryHelper + { + internal static ZuneServiceQueryHelper ConstructSocialQueryHelper( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new SocialQueryHelper(query); + } + + internal SocialQueryHelper(ZuneServiceQuery query) + : base(query) + { + } + + internal override object GetComputedProperty(string propertyName) => propertyName == "URI" ? (object)this.GetResourceUri() : base.GetComputedProperty(propertyName); + + internal override string GetResourceUri() + { + string zuneTagOrGuid = (string)null; + Guid? property1 = (Guid?)this.Query.GetProperty("UserGuid"); + if (property1.HasValue && property1.Value != Guid.Empty) + zuneTagOrGuid = property1.Value.ToString().ToUpper(); + if (string.IsNullOrEmpty(zuneTagOrGuid)) + zuneTagOrGuid = this.Query.GetProperty("ZuneTag") as string; + StringBuilder args = new StringBuilder(ComposerHelper.CreateOperationUri(this.Query.GetProperty("Operation") as string, zuneTagOrGuid)); + bool first = true; + int? property2 = (int?)this.Query.GetProperty("StartIndex"); + if (property2.HasValue) + { + UrlHelper.AppendParam(first, args, "startIndex", property2.ToString()); + first = false; + } + int? property3 = (int?)this.Query.GetProperty("ChunkSize"); + if (property3.HasValue) + UrlHelper.AppendParam(first, args, "chunkSize", property3.ToString()); + return args.ToString(); + } + } +} diff --git a/ZuneXml/SubRepresentationCatalogServiceQueryHelper.cs b/ZuneXml/SubRepresentationCatalogServiceQueryHelper.cs new file mode 100644 index 0000000..b7a292b --- /dev/null +++ b/ZuneXml/SubRepresentationCatalogServiceQueryHelper.cs @@ -0,0 +1,37 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.SubRepresentationCatalogServiceQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text; + +namespace ZuneXml +{ + internal class SubRepresentationCatalogServiceQueryHelper : CatalogServiceQueryHelper + { + internal SubRepresentationCatalogServiceQueryHelper(ZuneServiceQuery query) + : base(query) + { + } + + protected override void AppendStuffAfterRepresentation( + StringBuilder requestUri, + ref bool fFirst) + { + string property1 = (string)this.Query.GetProperty("SubId"); + string property2 = (string)this.Query.GetProperty("SubRepresentation"); + if (!string.IsNullOrEmpty(property1)) + { + requestUri.Append("/"); + requestUri.Append(property1); + } + if (!string.IsNullOrEmpty(property2)) + { + requestUri.Append("/"); + requestUri.Append(property2); + } + base.AppendStuffAfterRepresentation(requestUri, ref fFirst); + } + } +} diff --git a/ZuneXml/SubscriptionHistoryQueryHelper.cs b/ZuneXml/SubscriptionHistoryQueryHelper.cs new file mode 100644 index 0000000..573e29d --- /dev/null +++ b/ZuneXml/SubscriptionHistoryQueryHelper.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.SubscriptionHistoryQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal class SubscriptionHistoryQueryHelper : HistoryQueryHelper + { + internal static SubscriptionHistoryQueryHelper ConstructSubscriptionHistoryQueryHelper( + ZuneServiceQuery query) + { + return new SubscriptionHistoryQueryHelper(query); + } + + internal SubscriptionHistoryQueryHelper(ZuneServiceQuery query) + : base(query) + => this._api = "/account/subscriptionhistory"; + } +} diff --git a/ZuneXml/TVVideo.cs b/ZuneXml/TVVideo.cs new file mode 100644 index 0000000..ed1fb8f --- /dev/null +++ b/ZuneXml/TVVideo.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.TVVideo +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal abstract class TVVideo : RatableVideo + { + protected TVVideo(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract string ProductionCompany { get; } + + internal abstract string Copyright { get; } + + internal abstract Network Network { get; } + } +} diff --git a/ZuneXml/Thumbnail.cs b/ZuneXml/Thumbnail.cs new file mode 100644 index 0000000..5b8be22 --- /dev/null +++ b/ZuneXml/Thumbnail.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Thumbnail +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; + +namespace ZuneXml +{ + internal abstract class Thumbnail : XmlDataProviderObject + { + protected Thumbnail(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract string Id { get; } + + internal abstract string Title { get; } + + internal abstract string SortTitle { get; } + + internal abstract Guid ImageId { get; } + } +} diff --git a/ZuneXml/TopListenersQueryHelper.cs b/ZuneXml/TopListenersQueryHelper.cs new file mode 100644 index 0000000..23d5bf8 --- /dev/null +++ b/ZuneXml/TopListenersQueryHelper.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.TopListenersQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; + +namespace ZuneXml +{ + internal class TopListenersQueryHelper : ZuneServiceQueryHelper + { + internal static ZuneServiceQueryHelper ConstructTopListenersQueryHelper( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new TopListenersQueryHelper(query); + } + + internal TopListenersQueryHelper(ZuneServiceQuery query) + : base(query) + => query.PassportTicketType = EPassportPolicyId.MBI; + + internal override string GetResourceUri() + { + string property = (string)this.Query.GetProperty("ArtistId"); + return string.IsNullOrEmpty(property) ? (string)null : string.Format("{0}/music/artist/{1}/toplisteners", (object)Microsoft.Zune.Service.Service.GetEndPointUri(EServiceEndpointId.SEID_SocialApi), (object)property.ToLower()); + } + } +} diff --git a/ZuneXml/Track.cs b/ZuneXml/Track.cs new file mode 100644 index 0000000..6432de5 --- /dev/null +++ b/ZuneXml/Track.cs @@ -0,0 +1,321 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Track +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Collections; +using ZuneUI; + +namespace ZuneXml +{ + internal class Track : Media + { + private int _dbMediaId = -1; + private int _userRating; + private int _ordinal; + + internal virtual bool CanPlay + { + get + { + bool flag = this.Rights.HasRights(MediaRightsEnum.Preview, AudioEncodingEnum.WMA); + if (!flag) + flag = this.CanSubscriptionPlay; + if (!flag && this.Id != Guid.Empty) + flag = ZuneApplication.Service.InVisibleCollection(this.Id, EContentType.MusicTrack); + return flag; + } + } + + internal virtual bool CanPreview => this.Rights.HasRights(MediaRightsEnum.Preview, AudioEncodingEnum.WMA); + + internal virtual bool CanSubscriptionPlay => this.Rights.HasRights(MediaRightsEnum.SubscriptionStream, AudioEncodingEnum.WMA) && ZuneApplication.Service.IsSignedInWithSubscription(); + + internal virtual bool CanDownload + { + get + { + bool flag = false; + if (ZuneApplication.Service.CanDownloadSubscriptionContent()) + { + bool fIsDownloadPending = false; + bool fIsHidden = false; + if (this.Id != Guid.Empty && (!ZuneApplication.Service.IsDownloading(this.Id, EContentType.MusicTrack, out fIsDownloadPending, out fIsHidden) || fIsHidden) && !ZuneApplication.Service.InVisibleCollection(this.Id, EContentType.MusicTrack)) + flag = this.Rights.HasRights(MediaRightsEnum.SubscriptionDownload, AudioEncodingEnum.WMA); + } + return flag && !this.IsParentallyBlocked; + } + } + + internal virtual bool CanPurchase => this.SelectPurchaseRight() != null; + + internal virtual bool CanPurchaseFree + { + get + { + bool flag = false; + Right offer = (Right)null; + if (this.Rights.HasOfferRights(MediaRightsEnum.Purchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer) && offer.IsFree) + flag = true; + else if (this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer) && offer.IsFree) + flag = true; + else if (this.Rights.HasOfferRights(MediaRightsEnum.Purchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer) && offer.IsFree) + flag = true; + else if (this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer) && offer.IsFree) + flag = true; + return flag; + } + } + + internal virtual bool CanPurchaseMP3 + { + get + { + Right offer; + return this.Rights.HasOfferRights(MediaRightsEnum.Purchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer) || this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer); + } + } + + internal virtual bool CanPurchaseAlbumOnly + { + get + { + Right offer; + return !this.Rights.HasOfferRights(MediaRightsEnum.Purchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer) && !this.Rights.HasOfferRights(MediaRightsEnum.Purchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer) && (this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer) || this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer)); + } + } + + internal virtual bool CanPurchaseSubscriptionFree + { + get + { + Right offer; + return ZuneApplication.Service.GetSubscriptionFreeTrackBalance() > 0 && (this.Rights.HasOfferRights(MediaRightsEnum.SubscriptionFreePurchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer) || this.Rights.HasOfferRights(MediaRightsEnum.SubscriptionFreePurchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer)); + } + } + + internal virtual bool HasPoints + { + get + { + bool flag = false; + Right right = this.SelectPurchaseRight(); + if (right != null) + flag = right.HasPoints; + return flag; + } + } + + internal virtual bool InCollection => this.GetInCollection(); + + internal virtual bool IsDownloading => this.GetIsDownloading(); + + internal virtual int LibraryId + { + get => this.GetLibraryId(); + set + { + if (this._dbMediaId == value) + return; + this._dbMediaId = value; + this.FirePropertyChanged(nameof(LibraryId)); + } + } + + internal virtual bool CanSync => this.CanPurchase || this.InCollection || this.IsDownloading || this.CanDownload; + + internal virtual bool CanBurn => this.CanPurchase; + + internal virtual int PointsPrice + { + get + { + int num = -1; + Right offer; + if (this.Rights.HasOfferRights(MediaRightsEnum.Purchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer)) + num = offer.PointsPrice; + else if (this.Rights.HasOfferRights(MediaRightsEnum.Purchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer)) + num = offer.PointsPrice; + else if (this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer)) + num = offer.PointsPrice; + else if (this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer)) + num = offer.PointsPrice; + return num; + } + } + + internal virtual bool Actionable => this.Rights.HasAnyRights(); + + internal virtual int Ordinal + { + get => this._ordinal; + set + { + if (this._ordinal == value) + return; + this._ordinal = value; + this.FirePropertyChanged(nameof(Ordinal)); + } + } + + internal virtual int UserRating + { + get + { + this._userRating = RecommendationsHelper.GetUserRating((DataProviderObject)this); + return this._userRating; + } + set + { + if (this._userRating == value) + return; + this._userRating = value; + this.FirePropertyChanged(nameof(UserRating)); + } + } + + internal virtual bool IsParentallyBlocked => this.Explicit && ZuneApplication.Service.BlockExplicitContent(); + + protected bool GetInCollection() + { + bool flag = false; + if (this.Id != Guid.Empty) + flag = ZuneApplication.Service.InVisibleCollection(this.Id, EContentType.MusicTrack, out int _); + return flag; + } + + protected bool GetIsDownloading() + { + bool flag = false; + if (this.Id != Guid.Empty) + { + bool fIsDownloadPending = false; + bool fIsHidden = false; + flag = ZuneApplication.Service.IsDownloading(this.Id, EContentType.MusicTrack, out fIsDownloadPending, out fIsHidden); + } + return flag; + } + + protected int GetLibraryId() + { + int dbMediaId = -1; + if (this.Id != Guid.Empty) + ZuneApplication.Service.InVisibleCollection(this.Id, EContentType.MusicTrack, out dbMediaId); + return dbMediaId; + } + + private Right SelectPurchaseRight() + { + Right offer; + if (!this.Rights.HasOfferRights(MediaRightsEnum.Purchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer) && !this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.MP3, PriceTypeEnum.Points, out offer) && !this.Rights.HasOfferRights(MediaRightsEnum.Purchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer) && !this.Rights.HasOfferRights(MediaRightsEnum.AlbumPurchase, AudioEncodingEnum.WMA, PriceTypeEnum.Points, out offer)) + offer = (Right)null; + return offer; + } + + internal static XmlDataProviderObject ConstructTrackObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new Track(owner, objectTypeCookie); + } + + internal Track(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal TimeSpan Duration => (TimeSpan)base.GetProperty(nameof(Duration)); + + internal int TrackNumber => (int)base.GetProperty(nameof(TrackNumber)); + + internal int DiscNumber => (int)base.GetProperty(nameof(DiscNumber)); + + internal string AlbumTitle => (string)base.GetProperty(nameof(AlbumTitle)); + + internal Guid AlbumId => (Guid)base.GetProperty(nameof(AlbumId)); + + internal MiniArtist AlbumArtist => (MiniArtist)base.GetProperty(nameof(AlbumArtist)); + + internal string ArtistName => (string)base.GetProperty(nameof(ArtistName)); + + internal Genre PrimaryGenre => (Genre)base.GetProperty(nameof(PrimaryGenre)); + + internal bool Explicit => (bool)base.GetProperty(nameof(Explicit)); + + internal int PlayCount => (int)base.GetProperty(nameof(PlayCount)); + + internal string ReferrerContext => (string)base.GetProperty(nameof(ReferrerContext)); + + internal Guid MusicVideoId => (Guid)base.GetProperty(nameof(MusicVideoId)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override string SortTitle => (string)base.GetProperty(nameof(SortTitle)); + + internal override MiniArtist PrimaryArtist => (MiniArtist)base.GetProperty(nameof(PrimaryArtist)); + + internal override IList Artists => (IList)base.GetProperty(nameof(Artists)); + + internal override double Popularity => (double)base.GetProperty(nameof(Popularity)); + + internal override Guid ImageId => (Guid)base.GetProperty(nameof(ImageId)); + + internal override MediaRights Rights => (MediaRights)base.GetProperty(nameof(Rights)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Actionable": + return (object)this.Actionable; + case "UserRating": + return (object)this.UserRating; + case "LibraryId": + return (object)this.LibraryId; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPoints": + return (object)this.HasPoints; + case "CanPlay": + return (object)this.CanPlay; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanDownload": + return (object)this.CanDownload; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFree": + return (object)this.CanPurchaseFree; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanPurchaseSubscriptionFree": + return (object)this.CanPurchaseSubscriptionFree; + case "CanSync": + return (object)this.CanSync; + case "CanBurn": + return (object)this.CanBurn; + case "InCollection": + return (object)this.InCollection; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "Ordinal": + return (object)this.Ordinal; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/TrackDownloadHistory.cs b/ZuneXml/TrackDownloadHistory.cs new file mode 100644 index 0000000..63f43ad --- /dev/null +++ b/ZuneXml/TrackDownloadHistory.cs @@ -0,0 +1,143 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.TrackDownloadHistory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using ZuneUI; + +namespace ZuneXml +{ + internal class TrackDownloadHistory : TrackHistory + { + internal override bool InCollection => this.GetInCollection(); + + internal override bool IsDownloading => this.GetIsDownloading(); + + internal override int LibraryId => this.GetLibraryId(); + + internal override bool CanPlay => false; + + internal override bool CanSync => false; + + internal override bool CanBurn => false; + + internal override int PointsPrice => 0; + + internal override bool CanPurchaseSubscriptionFree => false; + + internal override bool CanDownload + { + get + { + bool flag = false; + if (!this.InCollection && this.MediaInstances != null) + { + foreach (MediaInstance mediaInstance in (IEnumerable)this.MediaInstances) + { + flag = mediaInstance.IsDownloadable; + if (!flag) + break; + } + } + if (flag && Download.Instance.GetErrorCode(this.Id) == HRESULT._ZUNE_E_NO_SUBSCRIPTION_DOWNLOAD_RIGHTS.Int) + flag = false; + return flag; + } + } + + internal override bool CanPurchase => true; + + internal override bool CanPreview => false; + + internal override bool CanSubscriptionPlay => false; + + internal override bool CanPurchaseMP3 => false; + + internal override bool CanPurchaseAlbumOnly => false; + + internal override bool Actionable => false; + + internal override int UserRating => 0; + + internal override bool IsParentallyBlocked => false; + + internal static XmlDataProviderObject ConstructTrackDownloadHistoryObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new TrackDownloadHistory(owner, objectTypeCookie); + } + + internal TrackDownloadHistory(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override DateTime Date => (DateTime)base.GetProperty(nameof(Date)); + + internal override IList MediaInstances => (IList)base.GetProperty(nameof(MediaInstances)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Actionable": + return (object)this.Actionable; + case "UserRating": + return (object)this.UserRating; + case "LibraryId": + return (object)this.LibraryId; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPoints": + return (object)this.HasPoints; + case "CanPlay": + return (object)this.CanPlay; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanDownload": + return (object)this.CanDownload; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFree": + return (object)this.CanPurchaseFree; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanPurchaseSubscriptionFree": + return (object)this.CanPurchaseSubscriptionFree; + case "CanSync": + return (object)this.CanSync; + case "CanBurn": + return (object)this.CanBurn; + case "InCollection": + return (object)this.InCollection; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "Ordinal": + return (object)this.Ordinal; + case "SortTitle": + return (object)this.SortTitle; + case "ImageId": + return (object)this.ImageId; + case "Rights": + return (object)this.Rights; + case "Artists": + return (object)this.Artists; + case "Popularity": + return (object)this.Popularity; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/TrackHistory.cs b/ZuneXml/TrackHistory.cs new file mode 100644 index 0000000..46610a3 --- /dev/null +++ b/ZuneXml/TrackHistory.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.TrackHistory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal abstract class TrackHistory : Track + { + protected TrackHistory(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract DateTime Date { get; } + + internal abstract IList MediaInstances { get; } + } +} diff --git a/ZuneXml/TrackPurchaseHistory.cs b/ZuneXml/TrackPurchaseHistory.cs new file mode 100644 index 0000000..9ffa069 --- /dev/null +++ b/ZuneXml/TrackPurchaseHistory.cs @@ -0,0 +1,143 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.TrackPurchaseHistory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using ZuneUI; + +namespace ZuneXml +{ + internal class TrackPurchaseHistory : TrackHistory + { + internal override bool InCollection => this.GetInCollection(); + + internal override bool IsDownloading => this.GetIsDownloading(); + + internal override bool CanPlay => false; + + internal override bool CanSync => false; + + internal override bool CanBurn => false; + + internal override int PointsPrice => 0; + + internal override bool CanPurchaseSubscriptionFree => false; + + internal override bool CanPurchaseAlbumOnly => false; + + internal override bool CanDownload + { + get + { + bool flag = false; + if (!this.InCollection && this.MediaInstances != null) + { + foreach (MediaInstance mediaInstance in (IEnumerable)this.MediaInstances) + { + flag = mediaInstance.IsDownloadable; + if (!flag) + break; + } + } + if (flag && Download.Instance.GetErrorCode(this.Id) == HRESULT._NS_E_MEDIA_DOWNLOAD_MAXIMUM_EXCEEDED.Int) + flag = false; + return flag; + } + } + + internal override bool CanPurchase => !this.CanDownload; + + internal override int LibraryId => -1; + + internal override bool CanPreview => false; + + internal override bool CanSubscriptionPlay => false; + + internal override bool CanPurchaseMP3 => false; + + internal override bool Actionable => false; + + internal override int UserRating => 0; + + internal override bool IsParentallyBlocked => false; + + internal static XmlDataProviderObject ConstructTrackPurchaseHistoryObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new TrackPurchaseHistory(owner, objectTypeCookie); + } + + internal TrackPurchaseHistory(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override DateTime Date => (DateTime)base.GetProperty(nameof(Date)); + + internal override IList MediaInstances => (IList)base.GetProperty(nameof(MediaInstances)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Actionable": + return (object)this.Actionable; + case "UserRating": + return (object)this.UserRating; + case "LibraryId": + return (object)this.LibraryId; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPoints": + return (object)this.HasPoints; + case "CanPlay": + return (object)this.CanPlay; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanDownload": + return (object)this.CanDownload; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFree": + return (object)this.CanPurchaseFree; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanPurchaseSubscriptionFree": + return (object)this.CanPurchaseSubscriptionFree; + case "CanSync": + return (object)this.CanSync; + case "CanBurn": + return (object)this.CanBurn; + case "InCollection": + return (object)this.InCollection; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "Ordinal": + return (object)this.Ordinal; + case "SortTitle": + return (object)this.SortTitle; + case "ImageId": + return (object)this.ImageId; + case "Rights": + return (object)this.Rights; + case "Artists": + return (object)this.Artists; + case "Popularity": + return (object)this.Popularity; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/Video.cs b/ZuneXml/Video.cs new file mode 100644 index 0000000..0bc2450 --- /dev/null +++ b/ZuneXml/Video.cs @@ -0,0 +1,193 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.Video +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; + +namespace ZuneXml +{ + internal abstract class Video : Media + { + private int _dbMediaId = -1; + + internal void SetLibraryId(int dbMediaId) + { + if (this._dbMediaId == dbMediaId) + return; + this._dbMediaId = dbMediaId; + this.FirePropertyChanged("LibraryId"); + } + + internal int GetLibraryId() + { + int dbMediaId = -1; + if (this.Id != Guid.Empty) + ZuneApplication.Service.InVisibleCollection(this.Id, EContentType.Video, out dbMediaId); + return dbMediaId; + } + + internal int GetPointsPrice() + { + int num1 = -1; + int num2 = -1; + Right right1 = this.Rights.GetOfferRight(MediaRightsEnum.Purchase, VideoDefinitionEnum.HD, VideoDefinitionEnum.XD, PriceTypeEnum.Points) ?? this.Rights.GetOfferRight(MediaRightsEnum.AlbumPurchase, VideoDefinitionEnum.HD, VideoDefinitionEnum.XD, PriceTypeEnum.Points); + if (right1 != null) + num2 = right1.PointsPrice; + int num3 = -1; + Right right2 = this.Rights.GetOfferRight(MediaRightsEnum.Purchase, VideoDefinitionEnum.SD, VideoDefinitionEnum.XD, PriceTypeEnum.Points) ?? this.Rights.GetOfferRight(MediaRightsEnum.AlbumPurchase, VideoDefinitionEnum.SD, VideoDefinitionEnum.XD, PriceTypeEnum.Points); + if (right2 != null) + num3 = right2.PointsPrice; + if (num2 > 0 && num3 > 0) + num1 = ClientConfiguration.Service.PurchaseHD ? num2 : num3; + else if (num2 > 0) + num1 = num2; + else if (num3 > 0) + num1 = num3; + return num1; + } + + internal int GetPointsRental() + { + int num1 = -1; + int num2 = -1; + Right offerRight1 = this.Rights.GetOfferRight(MediaRightsEnum.Rent, VideoDefinitionEnum.HD, VideoDefinitionEnum.XD, PriceTypeEnum.Points); + if (offerRight1 != null) + num2 = offerRight1.PointsPrice; + int num3 = -1; + Right offerRight2 = this.Rights.GetOfferRight(MediaRightsEnum.Rent, VideoDefinitionEnum.SD, VideoDefinitionEnum.XD, PriceTypeEnum.Points); + if (offerRight2 != null) + num3 = offerRight2.PointsPrice; + if (num2 > 0 && num3 > 0) + num1 = ClientConfiguration.Service.PurchaseHD ? num2 : num3; + else if (num2 > 0) + num1 = num2; + else if (num3 > 0) + num1 = num3; + return num1; + } + + internal bool GetHasPreview() => this.Rights.HasRights(MediaRightsEnum.Preview, VideoDefinitionEnum.None, PriceTypeEnum.None) || this.Rights.HasRights(MediaRightsEnum.PreviewStream, VideoDefinitionEnum.None, PriceTypeEnum.None); + + internal bool GetCanPreview() => (this.Rights.HasRights(MediaRightsEnum.Preview, VideoDefinitionEnum.None, PriceTypeEnum.None) || this.Rights.HasRights(MediaRightsEnum.PreviewStream, VideoDefinitionEnum.None, PriceTypeEnum.None)) && !this.IsParentallyBlocked; + + internal bool GetCanSubscriptionPlay() => this.Rights.HasRights(MediaRightsEnum.SubscriptionStream, VideoDefinitionEnum.None, PriceTypeEnum.None) && ZuneApplication.Service.IsSignedInWithSubscription() && !this.IsParentallyBlocked; + + internal bool GetCanPurchase() => this.GetCanPurchaseHD() || this.GetCanPurchaseSD(); + + internal bool GetCanPurchaseHD() => this.Rights.HasRights(MediaRightsEnum.Purchase, VideoDefinitionEnum.HD, VideoDefinitionEnum.XD, PriceTypeEnum.Points) || this.Rights.HasRights(MediaRightsEnum.PurchaseStream, VideoDefinitionEnum.HD, PriceTypeEnum.Points) || this.Rights.HasRights(MediaRightsEnum.AlbumPurchase, VideoDefinitionEnum.HD, PriceTypeEnum.Points); + + internal bool GetCanPurchaseSD() => this.Rights.HasRights(MediaRightsEnum.Purchase, VideoDefinitionEnum.SD, VideoDefinitionEnum.XD, PriceTypeEnum.Points) || this.Rights.HasRights(MediaRightsEnum.PurchaseStream, VideoDefinitionEnum.SD, PriceTypeEnum.Points) || this.Rights.HasRights(MediaRightsEnum.AlbumPurchase, VideoDefinitionEnum.SD, VideoDefinitionEnum.XD, PriceTypeEnum.Points); + + internal bool GetCanPurchaseSeason() => this.GetCanPurchaseSeasonHD() || this.GetCanPurchaseSeasonSD(); + + internal bool GetCanPurchaseSeasonHD() => this.Rights.HasRights(MediaRightsEnum.SeasonPurchase, VideoDefinitionEnum.HD, VideoDefinitionEnum.XD, PriceTypeEnum.Points) || this.Rights.HasRights(MediaRightsEnum.SeasonPurchaseStream, VideoDefinitionEnum.HD, PriceTypeEnum.Points); + + internal bool GetCanPurchaseSeasonSD() => this.Rights.HasRights(MediaRightsEnum.SeasonPurchase, VideoDefinitionEnum.SD, VideoDefinitionEnum.XD, PriceTypeEnum.Points) || this.Rights.HasRights(MediaRightsEnum.SeasonPurchaseStream, VideoDefinitionEnum.SD, PriceTypeEnum.Points); + + internal bool GetCanPurchaseAlbumOnly() => !this.Rights.HasRights(MediaRightsEnum.Purchase, VideoDefinitionEnum.None, PriceTypeEnum.Points) && this.Rights.HasRights(MediaRightsEnum.AlbumPurchase, VideoDefinitionEnum.None, PriceTypeEnum.Points); + + internal bool GetCanRent() => this.GetCanRentHD() || this.GetCanRentSD(); + + internal bool GetCanRentHD() => this.Rights.HasRights(MediaRightsEnum.Rent, VideoDefinitionEnum.HD, PriceTypeEnum.Points) || this.Rights.HasRights(MediaRightsEnum.RentStream, VideoDefinitionEnum.HD, PriceTypeEnum.Points); + + internal bool GetCanRentSD() => this.Rights.HasRights(MediaRightsEnum.Rent, VideoDefinitionEnum.SD, PriceTypeEnum.Points) || this.Rights.HasRights(MediaRightsEnum.RentStream, VideoDefinitionEnum.SD, PriceTypeEnum.Points); + + internal bool GetInCollection() + { + bool flag = false; + if (this.Id != Guid.Empty) + flag = ZuneApplication.Service.InVisibleCollection(this.Id, EContentType.Video); + return flag; + } + + internal bool GetInCollectionShortcut() + { + bool flag = false; + if (this.Id != Guid.Empty) + flag = ZuneApplication.Service.GetMediaStatus(this.Id, EContentType.Video) == EMediaStatus.StatusInCollectionShortcut; + return flag; + } + + internal bool GetIsDownloading() + { + bool flag = false; + if (this.Id != Guid.Empty) + { + bool fIsHidden = false; + flag = ZuneApplication.Service.IsDownloading(this.Id, EContentType.Video, out bool _, out fIsHidden); + } + return flag; + } + + internal bool GetIsParentallyBlocked(string rating) + { + string empty = string.Empty; + string system; + switch (this) + { + case Movie _: + system = "Movies"; + break; + case TVVideo _: + system = "TV"; + break; + default: + return false; + } + return ZuneApplication.Service.BlockRatedContent(system, rating); + } + + protected Video(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract DateTime ReleaseDate { get; } + + internal abstract TimeSpan Duration { get; } + + internal abstract int PointsPrice { get; } + + internal abstract bool HasPreview { get; } + + internal abstract bool CanPreview { get; } + + internal abstract bool CanSubscriptionPlay { get; } + + internal abstract bool CanPurchase { get; } + + internal abstract bool CanPurchaseHD { get; } + + internal abstract bool CanPurchaseSD { get; } + + internal abstract bool CanPurchaseSeason { get; } + + internal abstract bool CanPurchaseSeasonHD { get; } + + internal abstract bool CanPurchaseSeasonSD { get; } + + internal abstract bool CanRent { get; } + + internal abstract bool CanRentHD { get; } + + internal abstract bool CanRentSD { get; } + + internal abstract bool CanPurchaseAlbumOnly { get; } + + internal abstract bool CanSync { get; } + + internal abstract bool InCollection { get; } + + internal abstract bool InCollectionShortcut { get; } + + internal abstract bool IsDownloading { get; } + + internal abstract bool IsParentallyBlocked { get; } + } +} diff --git a/ZuneXml/VideoCatalogServiceQueryHelper.cs b/ZuneXml/VideoCatalogServiceQueryHelper.cs new file mode 100644 index 0000000..edad016 --- /dev/null +++ b/ZuneXml/VideoCatalogServiceQueryHelper.cs @@ -0,0 +1,28 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.VideoCatalogServiceQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal class VideoCatalogServiceQueryHelper : SubRepresentationCatalogServiceQueryHelper + { + internal static ZuneServiceQueryHelper ConstructVideoCatalogQuery( + ZuneServiceQuery query) + { + return (ZuneServiceQueryHelper)new VideoCatalogServiceQueryHelper(query); + } + + internal VideoCatalogServiceQueryHelper(ZuneServiceQuery query) + : base(query) + { + } + + protected override bool RequireId => false; + + protected override bool RequireResource => false; + + protected override bool RequireRepresentation => false; + } +} diff --git a/ZuneXml/VideoCategory.cs b/ZuneXml/VideoCategory.cs new file mode 100644 index 0000000..d90c2de --- /dev/null +++ b/ZuneXml/VideoCategory.cs @@ -0,0 +1,29 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.VideoCategory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class VideoCategory : Category + { + internal static XmlDataProviderObject ConstructVideoCategoryObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new VideoCategory(owner, objectTypeCookie); + } + + internal VideoCategory(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override string Id => (string)this.GetProperty(nameof(Id)); + + internal override string Title => (string)this.GetProperty(nameof(Title)); + } +} diff --git a/ZuneXml/VideoDefinitionEnum.cs b/ZuneXml/VideoDefinitionEnum.cs new file mode 100644 index 0000000..150e60a --- /dev/null +++ b/ZuneXml/VideoDefinitionEnum.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.VideoDefinitionEnum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + public enum VideoDefinitionEnum + { + None, + HD, + SD, + XD, + } +} diff --git a/ZuneXml/VideoHistory.cs b/ZuneXml/VideoHistory.cs new file mode 100644 index 0000000..e6627dc --- /dev/null +++ b/ZuneXml/VideoHistory.cs @@ -0,0 +1,228 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.VideoHistory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using ZuneUI; + +namespace ZuneXml +{ + internal class VideoHistory : Video + { + private MediaTypeEnum _mediaTypeEnum; + + public override void SetProperty(string propertyName, object value) + { + switch (propertyName) + { + case "MediaType": + this._mediaTypeEnum = SchemaHelper.ToMediaTypeEnum((string)value); + break; + } + base.SetProperty(propertyName, value); + } + + internal override bool CanSync => false; + + internal override bool InCollection => this.GetInCollection(); + + internal override bool InCollectionShortcut => this.GetInCollectionShortcut(); + + internal override bool IsDownloading => this.GetIsDownloading(); + + internal override bool CanPreview => false; + + internal override bool CanSubscriptionPlay => false; + + internal override int PointsPrice => 0; + + internal bool CanDownloadHD + { + get + { + bool flag = false; + if (!this.InCollection && this.MediaInstances != null) + { + foreach (MediaInstance mediaInstance in (IEnumerable)this.MediaInstances) + { + if ((mediaInstance.RightEnum == MediaRightsEnum.AlbumPurchase || mediaInstance.RightEnum == MediaRightsEnum.Purchase || (mediaInstance.RightEnum == MediaRightsEnum.SeasonPurchase || mediaInstance.RightEnum == MediaRightsEnum.Rent)) && (mediaInstance.VideoDefinitionEnum == VideoDefinitionEnum.HD && mediaInstance.VideoResolutionEnum == VideoResolutionEnum.VR_720P)) + { + flag = mediaInstance.IsDownloadable; + if (!flag) + break; + } + } + } + if (flag && Download.Instance.GetErrorCode(this.Id) == HRESULT._NS_E_MEDIA_DOWNLOAD_MAXIMUM_EXCEEDED.Int) + flag = false; + return flag; + } + } + + internal bool CanDownload + { + get + { + bool flag = false; + if (!this.InCollection && this.MediaInstances != null) + { + foreach (MediaInstance mediaInstance in (IEnumerable)this.MediaInstances) + { + if ((mediaInstance.RightEnum == MediaRightsEnum.AlbumPurchase || mediaInstance.RightEnum == MediaRightsEnum.Purchase || (mediaInstance.RightEnum == MediaRightsEnum.SeasonPurchase || mediaInstance.RightEnum == MediaRightsEnum.Rent)) && (mediaInstance.VideoDefinitionEnum == VideoDefinitionEnum.XD || mediaInstance.VideoDefinitionEnum == VideoDefinitionEnum.SD || mediaInstance.VideoDefinitionEnum == VideoDefinitionEnum.HD && mediaInstance.VideoResolutionEnum == VideoResolutionEnum.VR_720P)) + { + flag = mediaInstance.IsDownloadable; + if (!flag) + break; + } + } + } + if (flag && Download.Instance.GetErrorCode(this.Id) == HRESULT._NS_E_MEDIA_DOWNLOAD_MAXIMUM_EXCEEDED.Int) + flag = false; + return flag; + } + } + + internal override bool CanPurchase => !this.CanDownload && this.MediaInstances != null && this.MediaInstances.Count > 0; + + internal override bool CanPurchaseAlbumOnly => false; + + internal override bool CanRent => !this.CanDownload && this.MediaInstances != null && this.MediaInstances.Count > 0; + + internal override DateTime ReleaseDate => DateTime.MinValue; + + internal override TimeSpan Duration => TimeSpan.Zero; + + internal override double Popularity => 0.0; + + internal override bool HasPreview => false; + + internal override bool CanPurchaseHD => false; + + internal override bool CanPurchaseSD => false; + + internal override bool CanPurchaseSeason => false; + + internal override bool CanPurchaseSeasonHD => false; + + internal override bool CanPurchaseSeasonSD => false; + + internal override bool CanRentHD => false; + + internal override bool CanRentSD => false; + + internal override bool IsParentallyBlocked => false; + + internal override Guid ImageId => Guid.Empty; + + internal override string SortTitle => string.Empty; + + internal override MediaRights Rights => (MediaRights)null; + + internal override IList Artists => (IList)null; + + internal virtual bool IsTVSeason => this._mediaTypeEnum == MediaTypeEnum.TVSeason; + + internal static XmlDataProviderObject ConstructVideoHistoryObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new VideoHistory(owner, objectTypeCookie); + } + + internal VideoHistory(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal DateTime Date => (DateTime)base.GetProperty(nameof(Date)); + + internal string MediaType => (string)base.GetProperty(nameof(MediaType)); + + internal string SeasonTitle => (string)base.GetProperty(nameof(SeasonTitle)); + + internal int SeasonNumber => (int)base.GetProperty(nameof(SeasonNumber)); + + internal string SeriesTitle => (string)base.GetProperty(nameof(SeriesTitle)); + + internal IList SeasonEpisodes => (IList)base.GetProperty(nameof(SeasonEpisodes)); + + internal IList MediaInstances => (IList)base.GetProperty(nameof(MediaInstances)); + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override MiniArtist PrimaryArtist => (MiniArtist)base.GetProperty(nameof(PrimaryArtist)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "CanDownload": + return (object)this.CanDownload; + case "CanDownloadHD": + return (object)this.CanDownloadHD; + case "IsTVSeason": + return (object)this.IsTVSeason; + case "ReleaseDate": + return (object)this.ReleaseDate; + case "Duration": + return (object)this.Duration; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPreview": + return (object)this.HasPreview; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseHD": + return (object)this.CanPurchaseHD; + case "CanPurchaseSD": + return (object)this.CanPurchaseSD; + case "CanPurchaseSeason": + return (object)this.CanPurchaseSeason; + case "CanPurchaseSeasonHD": + return (object)this.CanPurchaseSeasonHD; + case "CanPurchaseSeasonSD": + return (object)this.CanPurchaseSeasonSD; + case "CanRent": + return (object)this.CanRent; + case "CanRentHD": + return (object)this.CanRentHD; + case "CanRentSD": + return (object)this.CanRentSD; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanSync": + return (object)this.CanSync; + case "InCollection": + return (object)this.InCollection; + case "InCollectionShortcut": + return (object)this.InCollectionShortcut; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "SortTitle": + return (object)this.SortTitle; + case "ImageId": + return (object)this.ImageId; + case "Rights": + return (object)this.Rights; + case "Artists": + return (object)this.Artists; + case "Popularity": + return (object)this.Popularity; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/VideoResolutionEnum.cs b/ZuneXml/VideoResolutionEnum.cs new file mode 100644 index 0000000..e403f2f --- /dev/null +++ b/ZuneXml/VideoResolutionEnum.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.VideoResolutionEnum +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +namespace ZuneXml +{ + internal enum VideoResolutionEnum + { + None, + VR_240P, + VR_480P, + VR_720P, + VR_1080P, + } +} diff --git a/ZuneXml/WMISServiceDataProviderQuery.cs b/ZuneXml/WMISServiceDataProviderQuery.cs new file mode 100644 index 0000000..61a76eb --- /dev/null +++ b/ZuneXml/WMISServiceDataProviderQuery.cs @@ -0,0 +1,123 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.WMISServiceDataProviderQuery +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Text; +using System.Threading; +using ZuneUI; + +namespace ZuneXml +{ + internal class WMISServiceDataProviderQuery : XmlDataProviderQuery + { + private string m_strPostBody; + private bool _endpointsInitialized; + + internal static DataProviderQuery ConstructWmisQuery(object queryTypeCookie) => (DataProviderQuery)new WMISServiceDataProviderQuery(queryTypeCookie); + + public WMISServiceDataProviderQuery(object queryTypeCookie) + : base(queryTypeCookie) + => this._keepAlive = false; + + protected override void BeginExecute() + { + if (this._endpointsInitialized) + base.BeginExecute(); + else + ThreadPool.QueueUserWorkItem(new WaitCallback(this.BackgroundInitializeWMISEndpointCollection)); + } + + private void BackgroundInitializeWMISEndpointCollection(object unused) + { + HRESULT hresult = (HRESULT)ZuneApplication.Service.InitializeWMISEndpointCollection(); + if (hresult.IsSuccess) + { + this._endpointsInitialized = true; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredInvokeBeginExecute), (object)null); + } + else + { + ++this._requestGeneration; + this.SetWorkerStatus(this._requestGeneration, DataProviderQueryStatus.RequestingData); + this.SetWorkerStatus(this._requestGeneration, DataProviderQueryStatus.Error, (object)hresult); + } + } + + private void DeferredInvokeBeginExecute(object unused) => base.BeginExecute(); + + protected override string GetResourceUri() => this.BuildServiceUri(0, 0); + + protected override string GetPostBody() => this.m_strPostBody; + + private string BuildServiceUri(int chunkStart, int chunkSize) + { + this.m_strPostBody = (string)null; + string property1 = (string)this.GetProperty("SearchString"); + string property2 = (string)this.GetProperty("artistId"); + string property3 = (string)this.GetProperty("albumId"); + string strEndPointName; + string paramName; + string paramValue1; + if (!string.IsNullOrEmpty(property1)) + { + strEndPointName = WMISEndpointIds.WMISEID_Search; + paramName = "SearchString"; + paramValue1 = property1; + } + else if (!string.IsNullOrEmpty(property2)) + { + strEndPointName = WMISEndpointIds.WMISEID_GetResultsForArtist; + paramName = "artistId"; + paramValue1 = property2; + } + else + { + if (string.IsNullOrEmpty(property3)) + return (string)null; + strEndPointName = WMISEndpointIds.WMISEID_GetAlbumDetailsByAlbumId; + paramName = "albumId"; + paramValue1 = property3; + Guid.NewGuid(); + this.m_strPostBody = string.Empty; + } + string wmisEndPointUri = ZuneApplication.Service.GetWMISEndPointUri(strEndPointName); + if (string.IsNullOrEmpty(wmisEndPointUri)) + return (string)null; + UriBuilder uriBuilder = new UriBuilder(wmisEndPointUri); + StringBuilder args = new StringBuilder(); + UrlHelper.AppendParam(true, args, paramName, paramValue1); + string wmisPartner = ClientConfiguration.Service.WMISPartner; + if (!string.IsNullOrEmpty(wmisPartner)) + UrlHelper.AppendParam(false, args, "Partner", wmisPartner); + string[] strArray = new string[5] + { + "locale", + "maxNumberOfResults", + "resultTypeString", + "countOnly", + "volume" + }; + foreach (string str in strArray) + { + string paramValue2 = (string)null; + object property4 = this.GetProperty(str); + if (property4 != null) + paramValue2 = property4.ToString(); + if (!string.IsNullOrEmpty(paramValue2)) + UrlHelper.AppendParam(false, args, str, paramValue2); + } + string str1 = args.ToString(); + if (str1.Length > 0 && str1[0] == '?') + str1 = str1.Remove(0, 1); + uriBuilder.Query = str1; + return uriBuilder.Uri.AbsoluteUri; + } + } +} diff --git a/ZuneXml/WebRequestHelper.cs b/ZuneXml/WebRequestHelper.cs new file mode 100644 index 0000000..8cbb10f --- /dev/null +++ b/ZuneXml/WebRequestHelper.cs @@ -0,0 +1,93 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.WebRequestHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Globalization; +using System.Text; + +namespace ZuneXml +{ + internal class WebRequestHelper + { + private static string AcceptLanguage; + + private static void SetCommonHeaders( + HttpWebRequest request, + EPassportPolicyId passportTicketType, + HttpRequestCachePolicy cachePolicy, + bool acceptGZipEncoding) + { + request.CachePolicy = cachePolicy; + if (passportTicketType != EPassportPolicyId.None) + { + string passportTicket = ZuneApplication.Service.GetPassportTicket(passportTicketType); + if (!string.IsNullOrEmpty(passportTicket)) + request.Authorization = "WLID1.0 " + passportTicket; + } + request.AcceptGZipEncoding = acceptGZipEncoding; + request.AcceptLanguage = WebRequestHelper.Locale; + } + + public static HttpWebRequest ConstructWebRequest( + string requestUri, + EPassportPolicyId passportTicketType, + HttpRequestCachePolicy cachePolicy, + bool fKeepAlive, + bool acceptGZipEncoding) + { + string absoluteUri = new Uri(requestUri).AbsoluteUri; + if (absoluteUri != requestUri) + { + int num = TraceSwitches.DataProviderSwitch.TraceWarning ? 1 : 0; + requestUri = absoluteUri; + } + if (cachePolicy == HttpRequestCachePolicy.Default && UriResourceTracker.Instance.IsResourceModified(requestUri)) + { + cachePolicy = HttpRequestCachePolicy.Refresh; + UriResourceTracker.Instance.SetResourceModified(requestUri, false); + } + HttpWebRequest request = HttpWebRequest.Create(requestUri); + request.KeepAlive = fKeepAlive; + request.CancelOnShutdown = true; + WebRequestHelper.SetCommonHeaders(request, passportTicketType, cachePolicy, acceptGZipEncoding); + int num1 = TraceSwitches.DataProviderSwitch.TraceWarning ? 1 : 0; + return request; + } + + public static HttpWebRequest ConstructWebPostRequest( + string requestUri, + string requestBody, + EPassportPolicyId passportTicketType, + HttpRequestCachePolicy cachePolicy, + bool fKeepAlive, + bool acceptGZipEncoding) + { + HttpWebRequest request = HttpWebRequest.Create(requestUri); + request.KeepAlive = fKeepAlive; + request.CachePolicy = cachePolicy; + request.Method = "POST"; + request.ContentType = "application/x-www-form-urlencoded"; + WebRequestHelper.SetCommonHeaders(request, passportTicketType, cachePolicy, acceptGZipEncoding); + byte[] bytes = new ASCIIEncoding().GetBytes(requestBody); + request.ContentLength = (long)bytes.Length; + request.GetRequestStream().Write(bytes, 0, bytes.Length); + int num = TraceSwitches.DataProviderSwitch.TraceWarning ? 1 : 0; + return request; + } + + public static string Locale + { + get + { + if (WebRequestHelper.AcceptLanguage == null) + WebRequestHelper.AcceptLanguage = CultureInfo.CurrentUICulture.Name; + return WebRequestHelper.AcceptLanguage; + } + } + } +} diff --git a/ZuneXml/WinPhoneApp.cs b/ZuneXml/WinPhoneApp.cs new file mode 100644 index 0000000..d0a9246 --- /dev/null +++ b/ZuneXml/WinPhoneApp.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.WinPhoneApp +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class WinPhoneApp : App + { + internal static XmlDataProviderObject ConstructWinPhoneAppObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new WinPhoneApp(owner, objectTypeCookie); + } + + internal WinPhoneApp(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Price": + return (object)this.Price; + case "DisplayPrice": + return (object)this.DisplayPrice; + case "DisplayPriceFull": + return (object)this.DisplayPriceFull; + case "DisplayPriceTrial": + return (object)this.DisplayPriceTrial; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFull": + return (object)this.CanPurchaseFull; + case "CanPurchaseTrial": + return (object)this.CanPurchaseTrial; + case "CanDownload": + return (object)this.CanDownload; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/WinPhoneAppData.cs b/ZuneXml/WinPhoneAppData.cs new file mode 100644 index 0000000..8d1d7c3 --- /dev/null +++ b/ZuneXml/WinPhoneAppData.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.WinPhoneAppData +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class WinPhoneAppData : AppData + { + internal static XmlDataProviderObject ConstructWinPhoneAppDataObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new WinPhoneAppData(owner, objectTypeCookie); + } + + internal WinPhoneAppData(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Price": + return (object)this.Price; + case "DisplayPrice": + return (object)this.DisplayPrice; + case "DisplayPriceFull": + return (object)this.DisplayPriceFull; + case "DisplayPriceTrial": + return (object)this.DisplayPriceTrial; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFull": + return (object)this.CanPurchaseFull; + case "CanPurchaseTrial": + return (object)this.CanPurchaseTrial; + case "CanDownload": + return (object)this.CanDownload; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/WinPhoneAppGenre.cs b/ZuneXml/WinPhoneAppGenre.cs new file mode 100644 index 0000000..cb8bf71 --- /dev/null +++ b/ZuneXml/WinPhoneAppGenre.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.WinPhoneAppGenre +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class WinPhoneAppGenre : AppGenre + { + internal static XmlDataProviderObject ConstructWinPhoneAppGenreObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new WinPhoneAppGenre(owner, objectTypeCookie); + } + + internal WinPhoneAppGenre(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + } +} diff --git a/ZuneXml/WinPhoneAppHistory.cs b/ZuneXml/WinPhoneAppHistory.cs new file mode 100644 index 0000000..768e63c --- /dev/null +++ b/ZuneXml/WinPhoneAppHistory.cs @@ -0,0 +1,24 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.WinPhoneAppHistory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal abstract class WinPhoneAppHistory : App + { + protected WinPhoneAppHistory(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal abstract DateTime Date { get; } + + internal abstract IList MediaInstances { get; } + } +} diff --git a/ZuneXml/WinPhoneAppPurchaseHistory.cs b/ZuneXml/WinPhoneAppPurchaseHistory.cs new file mode 100644 index 0000000..8228b3d --- /dev/null +++ b/ZuneXml/WinPhoneAppPurchaseHistory.cs @@ -0,0 +1,60 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.WinPhoneAppPurchaseHistory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; + +namespace ZuneXml +{ + internal class WinPhoneAppPurchaseHistory : WinPhoneAppHistory + { + internal static XmlDataProviderObject ConstructWinPhoneAppPurchaseHistoryObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new WinPhoneAppPurchaseHistory(owner, objectTypeCookie); + } + + internal WinPhoneAppPurchaseHistory(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + internal override string Title => (string)base.GetProperty(nameof(Title)); + + internal override Guid Id => (Guid)base.GetProperty(nameof(Id)); + + internal override DateTime Date => (DateTime)base.GetProperty(nameof(Date)); + + internal override IList MediaInstances => (IList)base.GetProperty(nameof(MediaInstances)); + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Price": + return (object)this.Price; + case "DisplayPrice": + return (object)this.DisplayPrice; + case "DisplayPriceFull": + return (object)this.DisplayPriceFull; + case "DisplayPriceTrial": + return (object)this.DisplayPriceTrial; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFull": + return (object)this.CanPurchaseFull; + case "CanPurchaseTrial": + return (object)this.CanPurchaseTrial; + case "CanDownload": + return (object)this.CanDownload; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/XmlDataProviderObject.cs b/ZuneXml/XmlDataProviderObject.cs new file mode 100644 index 0000000..0b70721 --- /dev/null +++ b/ZuneXml/XmlDataProviderObject.cs @@ -0,0 +1,364 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.XmlDataProviderObject +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Shell; +using MicrosoftZuneLibrary; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Xml; + +namespace ZuneXml +{ + public class XmlDataProviderObject : DataProviderObject, IXmlDataProviderObject, IDatabaseMedia + { + private static string _strUuidPrefix1 = "urn:uuid:"; + private static string _strUuidPrefix2 = "uid:uuid:"; + private Dictionary _propertyValues; + + public XmlDataProviderObject(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + foreach (DataProviderMapping dataProviderMapping in (IEnumerable)this.Mappings.Values) + { + string propertyTypeName = dataProviderMapping.PropertyTypeName; + if (!this.IsXmlValueType(propertyTypeName)) + { + if (propertyTypeName == "List") + this.SetProperty(dataProviderMapping.PropertyName, (object)new XmlDataVirtualList(this.Owner, dataProviderMapping.UnderlyingCollectionTypeCookie)); + else + this.SetProperty(dataProviderMapping.PropertyName, (object)XmlDataProviderObjectFactory.CreateObject(this.Owner, dataProviderMapping.PropertyTypeCookie)); + } + } + } + + internal IPageInfo NextPage + { + get + { + IPageInfo pageInfo = (IPageInfo)null; + foreach (DataProviderMapping dataProviderMapping in (IEnumerable)this.Mappings.Values) + { + if (dataProviderMapping.PropertyTypeName == "List") + { + XmlDataVirtualList property = (XmlDataVirtualList)this.GetProperty(dataProviderMapping.PropertyName); + if (property != null) + { + pageInfo = property.NextPage; + break; + } + } + } + return pageInfo; + } + set + { + foreach (DataProviderMapping dataProviderMapping in (IEnumerable)this.Mappings.Values) + { + if (dataProviderMapping.PropertyTypeName == "List") + { + XmlDataVirtualList property = (XmlDataVirtualList)this.GetProperty(dataProviderMapping.PropertyName); + if (property != null) + property.NextPage = value; + } + } + } + } + + public bool PageToEnd + { + get + { + bool flag = false; + foreach (DataProviderMapping dataProviderMapping in (IEnumerable)this.Mappings.Values) + { + if (dataProviderMapping.PropertyTypeName == "List") + { + XmlDataVirtualList property = (XmlDataVirtualList)this.GetProperty(dataProviderMapping.PropertyName); + if (property != null) + { + flag = property.PageToEnd; + break; + } + } + } + return flag; + } + set + { + foreach (DataProviderMapping dataProviderMapping in (IEnumerable)this.Mappings.Values) + { + if (dataProviderMapping.PropertyTypeName == "List") + { + XmlDataVirtualList property = (XmlDataVirtualList)this.GetProperty(dataProviderMapping.PropertyName); + if (property != null) + property.PageToEnd = value; + } + } + } + } + + public override object GetProperty(string propertyName) + { + object obj = (object)null; + if (this._propertyValues != null && this._propertyValues.TryGetValue(propertyName, out obj)) + return obj; + DataProviderMapping dataProviderMapping; + if (this.Mappings.TryGetValue(propertyName, out dataProviderMapping)) + { + object defaultValue = dataProviderMapping.DefaultValue; + if (defaultValue != null) + { + obj = defaultValue; + } + else + { + string propertyTypeName = dataProviderMapping.PropertyTypeName; + if (propertyTypeName == "String") + obj = (object)string.Empty; + else if (propertyTypeName == "Int32") + obj = (object)0; + else if (propertyTypeName == "Int64") + obj = (object)0; + else if (propertyTypeName == "DateTime") + obj = (object)new DateTime(0L); + else if (propertyTypeName == "TimeSpan") + obj = (object)new TimeSpan(0L); + else if (propertyTypeName == "Guid") + obj = (object)Guid.Empty; + else if (propertyTypeName == "Boolean") + obj = (object)false; + else if (propertyTypeName == "Double") + obj = (object)0.0; + else if (propertyTypeName == "Single") + obj = (object)0.0f; + } + } + if (obj != null) + { + this.EnsureValuesDictionary(); + this._propertyValues[propertyName] = obj; + } + return obj; + } + + public override void SetProperty(string propertyName, object value) + { + if (!this.EnsureValuesDictionary() && this._propertyValues.ContainsKey(propertyName) && object.Equals(this._propertyValues[propertyName], value)) + return; + this._propertyValues[propertyName] = value; + this.FirePropertyChanged(propertyName); + } + + public virtual void GetMediaIdAndType(out int mediaId, out EMediaTypes mediaType) + { + object property = this.GetProperty("LibraryId"); + mediaId = property == null ? -1 : (int)property; + mediaType = XmlDataProviderObject.NameToMediaType(this.TypeName); + } + + public static EMediaTypes NameToMediaType(string typeName) + { + if (typeName == "ProfileData") + return EMediaTypes.eMediaTypeUserCard; + if (typeName == "Track" || typeName == "PlaylistTrack" || (typeName == "ProfileTrack" || typeName == "TrackDownloadHistory") || (typeName == "TrackPurchaseHistory" || typeName == "ChannelTrack")) + return EMediaTypes.eMediaTypeAudio; + if (typeName == "Album") + return EMediaTypes.eMediaTypeAudioAlbum; + if (typeName == "PodcastSeries") + return EMediaTypes.eMediaTypePodcastSeries; + return typeName == "MusicVideo" ? EMediaTypes.eMediaTypeVideo : EMediaTypes.eMediaTypeInvalid; + } + + private bool EnsureValuesDictionary() + { + if (this._propertyValues != null) + return false; + this._propertyValues = new Dictionary(); + return true; + } + + internal void SetPropertyFromStringValue( + DataProviderMapping propertyMapping, + string stringValue) + { + object obj = (object)stringValue; + string propertyName = propertyMapping.PropertyName; + string propertyTypeName = propertyMapping.PropertyTypeName; + try + { + if (propertyTypeName == "Int32") + obj = (object)int.Parse(stringValue); + else if (propertyTypeName == "Int64") + obj = (object)long.Parse(stringValue); + else if (propertyTypeName == "TimeSpan") + obj = (object)XmlConvert.ToTimeSpan(stringValue); + else if (propertyTypeName == "DateTime") + obj = (object)XmlConvert.ToDateTime(stringValue, XmlDateTimeSerializationMode.Utc); + else if (propertyTypeName == "Guid") + obj = !stringValue.StartsWith(XmlDataProviderObject._strUuidPrefix1) ? (!stringValue.StartsWith(XmlDataProviderObject._strUuidPrefix2) ? (object)new Guid(stringValue) : (object)new Guid(stringValue.Substring(XmlDataProviderObject._strUuidPrefix2.Length))) : (object)new Guid(stringValue.Substring(XmlDataProviderObject._strUuidPrefix1.Length)); + else if (propertyTypeName == "Boolean") + obj = (object)bool.Parse(stringValue); + else if (propertyTypeName == "Double") + obj = (object)double.Parse(stringValue, (IFormatProvider)CultureInfo.InvariantCulture); + else if (propertyTypeName == "Single") + obj = (object)float.Parse(stringValue, (IFormatProvider)CultureInfo.InvariantCulture); + else if (propertyTypeName != "String") + obj = (object)null; + this.SetProperty(propertyName, obj); + } + catch (FormatException ex) + { + int num = TraceSwitches.DataProviderSwitch.TraceError ? 1 : 0; + } + } + + private bool IsXmlValueType(string propertyType) => propertyType == "String" || propertyType == "Int32" || (propertyType == "Int64" || propertyType == "TimeSpan") || (propertyType == "DateTime" || propertyType == "Guid" || (propertyType == "Boolean" || propertyType == "Double")) || propertyType == "Single"; + + public bool ProcessXPath( + string currentXPath, + Hashtable attributes, + List matches) + { + bool flag1 = false; + foreach (DataProviderMapping propertyMapping in (IEnumerable)this.Mappings.Values) + { + string tailXPath; + string matchingAttributeName; + if (propertyMapping.Source != null && XmlDataProviderObject.MatchesXPath(currentXPath, attributes, propertyMapping.Source, out tailXPath, out matchingAttributeName)) + { + string propertyTypeName = propertyMapping.PropertyTypeName; + bool flag2 = string.IsNullOrEmpty(tailXPath); + bool flag3 = !flag2 && (tailXPath.StartsWith("/") || tailXPath.StartsWith("@")); + bool flag4 = flag2 || flag3; + bool encodedXml = flag2 && propertyMapping.Target == "Xml"; + if (flag2 && (this.IsXmlValueType(propertyTypeName) || encodedXml)) + { + int num = TraceSwitches.DataProviderSwitch.TraceVerbose ? 1 : 0; + matches.Add(new XmlDataProviderQuery.XPathMatch(this, propertyMapping, matchingAttributeName, encodedXml)); + flag1 = true; + } + else if (flag4 && propertyTypeName == "List") + { + IXmlDataProviderObject property = (IXmlDataProviderObject)this.GetProperty(propertyMapping.PropertyName); + int num = TraceSwitches.DataProviderSwitch.TraceVerbose ? 1 : 0; + flag1 |= property.ProcessXPath(tailXPath, attributes, matches); + if (!TraceSwitches.DataProviderSwitch.TraceVerbose) + ; + } + else if (flag3) + { + int num1 = TraceSwitches.DataProviderSwitch.TraceVerbose ? 1 : 0; + if (this.GetProperty(propertyMapping.PropertyName) is XmlDataProviderObject property) + flag1 |= property.ProcessXPath(tailXPath, attributes, matches); + int num2 = TraceSwitches.DataProviderSwitch.TraceVerbose ? 1 : 0; + } + } + } + int num3 = flag1 ? 1 : 0; + return flag1; + } + + internal void TransferToAppThread() + { + if (this._propertyValues == null) + return; + foreach (object obj in this._propertyValues.Values) + { + if (obj is XmlDataProviderObject dataProviderObject) + dataProviderObject.TransferToAppThread(); + else if (obj is XmlDataVirtualList xmlDataVirtualList) + xmlDataVirtualList.TransferToAppThread(); + } + } + + internal void OnQueryComplete() + { + if (this._propertyValues == null) + return; + foreach (object obj in this._propertyValues.Values) + { + if (obj is XmlDataVirtualList xmlDataVirtualList) + xmlDataVirtualList.OnQueryComplete(); + } + } + + internal static bool MatchesXPath( + string xpathCheck, + Hashtable attributes, + string scriptSource, + out string tailXPath, + out string matchingAttributeName) + { + tailXPath = string.Empty; + matchingAttributeName = (string)null; + string sourceXPath; + string condAttrName; + string condAttrValue; + if (!XmlDataProviderObject.SplitScriptSource(scriptSource, out sourceXPath, out condAttrName, out condAttrValue) || condAttrName != null && (!(attributes[(object)condAttrName] is string attribute) || condAttrValue != attribute) || (!xpathCheck.StartsWith(sourceXPath) || xpathCheck.Length > sourceXPath.Length && xpathCheck[sourceXPath.Length] != '/' && xpathCheck[sourceXPath.Length] != '@')) + return false; + int num = sourceXPath.IndexOf('@'); + if (num >= 0) + { + tailXPath = xpathCheck.Substring(sourceXPath.Length); + matchingAttributeName = sourceXPath.Substring(num + 1); + } + else if (xpathCheck.Length > sourceXPath.Length) + tailXPath = xpathCheck.Substring(sourceXPath.Length); + return true; + } + + private static bool SplitScriptSource( + string scriptSource, + out string sourceXPath, + out string condAttrName, + out string condAttrValue) + { + sourceXPath = scriptSource; + condAttrName = (string)null; + condAttrValue = (string)null; + int length1 = scriptSource.IndexOf('['); + if (length1 < 0) + return true; + int num = scriptSource.IndexOf(']', length1 + 1); + if (length1 == 0 || num < 0 || num != scriptSource.Length - 1) + return false; + sourceXPath = scriptSource.Substring(0, length1).Trim(); + string str1 = scriptSource.Substring(length1 + 1, num - (length1 + 1)).Trim(); + if (str1.Length == 0 || str1[0] != '@') + return false; + string str2 = str1.Substring(1); + int length2 = str2.IndexOf('='); + if (length2 == 0) + return false; + if (length2 < 0) + { + condAttrName = str2; + } + else + { + condAttrName = str2.Substring(0, length2).Trim(); + if (str2.Length < length2 + 2) + return false; + condAttrValue = str2.Substring(length2 + 2, str2.Length - (length2 + 2) - 1).Trim(); + } + return true; + } + + internal void ChangeListSort(string newSortBy) + { + if (this._propertyValues == null) + return; + foreach (object obj in this._propertyValues.Values) + { + if (obj is XmlDataVirtualList xmlDataVirtualList) + xmlDataVirtualList.SortBy = newSortBy; + } + } + } +} diff --git a/ZuneXml/XmlDataProviderObjectFactory.cs b/ZuneXml/XmlDataProviderObjectFactory.cs new file mode 100644 index 0000000..f67bc2e --- /dev/null +++ b/ZuneXml/XmlDataProviderObjectFactory.cs @@ -0,0 +1,117 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.XmlDataProviderObjectFactory +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections.Generic; + +namespace ZuneXml +{ + public class XmlDataProviderObjectFactory + { + private static IDictionary _mapMarkupCookieToConstructor; + private static IDictionary _mapTypeNameToMarkupCookie; + + public static void ClearBindings() => XmlDataProviderObjectFactory._mapMarkupCookieToConstructor = (IDictionary)null; + + public static void Bind(string typeName, object markupTypeCookie) + { + if (XmlDataProviderObjectFactory._mapTypeNameToMarkupCookie == null) + XmlDataProviderObjectFactory._mapTypeNameToMarkupCookie = (IDictionary)new Dictionary(40); + XmlDataProviderObjectFactory._mapTypeNameToMarkupCookie[typeName] = markupTypeCookie; + } + + private static void RegisterTypeConstructor(string typeName, ConstructObject constructor) + { + object key = XmlDataProviderObjectFactory._mapTypeNameToMarkupCookie[typeName]; + if (XmlDataProviderObjectFactory._mapMarkupCookieToConstructor == null) + XmlDataProviderObjectFactory._mapMarkupCookieToConstructor = (IDictionary)new Dictionary(40); + XmlDataProviderObjectFactory._mapMarkupCookieToConstructor[key] = constructor; + } + + internal static ConstructObject GetConstructor(object objectTypeCookie) + { + if (XmlDataProviderObjectFactory._mapMarkupCookieToConstructor == null) + { + XmlDataProviderObjectFactory.RegisterTypeConstructors(); + XmlDataProviderObjectFactory._mapTypeNameToMarkupCookie = (IDictionary)null; + } + ConstructObject constructObject = (ConstructObject)null; + if (XmlDataProviderObjectFactory._mapMarkupCookieToConstructor.ContainsKey(objectTypeCookie)) + constructObject = XmlDataProviderObjectFactory._mapMarkupCookieToConstructor[objectTypeCookie]; + return constructObject; + } + + internal static XmlDataProviderObject CreateObject( + DataProviderQuery owner, + object objectTypeCookie) + { + ConstructObject constructor = XmlDataProviderObjectFactory.GetConstructor(objectTypeCookie); + return constructor != null ? constructor(owner, objectTypeCookie) : new XmlDataProviderObject(owner, objectTypeCookie); + } + + internal static void RegisterTypeConstructors() + { + XmlDataProviderObjectFactory.RegisterTypeConstructor("BadgeData", new ConstructObject(BadgeData.ConstructBadgeDataObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("TrackPurchaseHistory", new ConstructObject(TrackPurchaseHistory.ConstructTrackPurchaseHistoryObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("AppCapabilities", new ConstructObject(AppCapabilities.ConstructAppCapabilitiesObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Artist", new ConstructObject(Artist.ConstructArtistObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("PlaylistTrack", new ConstructObject(PlaylistTrack.ConstructPlaylistTrackObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ZuneHDApp", new ConstructObject(ZuneHDApp.ConstructZuneHDAppObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MessageDetails", new ConstructObject(MessageDetails.ConstructMessageDetailsObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Season", new ConstructObject(Season.ConstructSeasonObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MusicVideo", new ConstructObject(MusicVideo.ConstructMusicVideoObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MediaInstance", new ConstructObject(MediaInstance.ConstructMediaInstanceObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("SeriesCategory", new ConstructObject(SeriesCategory.ConstructSeriesCategoryObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("RecommendedTrack", new ConstructObject(RecommendedTrack.ConstructRecommendedTrackObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("AppCapability", new ConstructObject(AppCapability.ConstructAppCapabilityObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MovieGenre", new ConstructObject(MovieGenre.ConstructMovieGenreObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MarketplaceRadioStation", new ConstructObject(MarketplaceRadioStation.ConstructMarketplaceRadioStationObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("RecommendedAlbum", new ConstructObject(RecommendedAlbum.ConstructRecommendedAlbumObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Episode", new ConstructObject(Episode.ConstructEpisodeObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("AppMediaRights", new ConstructObject(AppMediaRights.ConstructAppMediaRightsObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Movie", new ConstructObject(Movie.ConstructMovieObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Track", new ConstructObject(Track.ConstructTrackObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Right", new ConstructObject(Right.ConstructRightObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Album", new ConstructObject(Album.ConstructAlbumObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MovieStudio", new ConstructObject(MovieStudio.ConstructMovieStudioObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Review", new ConstructObject(Review.ConstructReviewObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("AppGenre", new ConstructObject(AppGenre.ConstructAppGenreObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ReviewListEntry", new ConstructObject(ReviewListEntry.ConstructReviewListEntryObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ChannelReason", new ConstructObject(ChannelReason.ConstructChannelReasonObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MiniAlbum", new ConstructObject(MiniAlbum.ConstructMiniAlbumObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ZuneHDAppData", new ConstructObject(ZuneHDAppData.ConstructZuneHDAppDataObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ArtistEvent", new ConstructObject(ArtistEvent.ConstructArtistEventObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("AppData", new ConstructObject(AppData.ConstructAppDataObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("WinPhoneAppPurchaseHistory", new ConstructObject(WinPhoneAppPurchaseHistory.ConstructWinPhoneAppPurchaseHistoryObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Series", new ConstructObject(Series.ConstructSeriesObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("VideoCategory", new ConstructObject(VideoCategory.ConstructVideoCategoryObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MessageRoot", new ConstructObject(MessageRoot.ConstructMessageRootObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("App", new ConstructObject(App.ConstructAppObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Genre", new ConstructObject(Genre.ConstructGenreObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("VideoHistory", new ConstructObject(VideoHistory.ConstructVideoHistoryObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("WinPhoneAppGenre", new ConstructObject(WinPhoneAppGenre.ConstructWinPhoneAppGenreObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ChannelTrack", new ConstructObject(ChannelTrack.ConstructChannelTrackObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ZuneHDAppGenre", new ConstructObject(ZuneHDAppGenre.ConstructZuneHDAppGenreObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ProfileTrack", new ConstructObject(ProfileTrack.ConstructProfileTrackObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("WinPhoneAppData", new ConstructObject(WinPhoneAppData.ConstructWinPhoneAppDataObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("TrackDownloadHistory", new ConstructObject(TrackDownloadHistory.ConstructTrackDownloadHistoryObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("PodcastSeries", new ConstructObject(PodcastSeries.ConstructPodcastSeriesObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MiniArtist", new ConstructObject(MiniArtist.ConstructMiniArtistObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("WinPhoneApp", new ConstructObject(WinPhoneApp.ConstructWinPhoneAppObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Mood", new ConstructObject(Mood.ConstructMoodObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MediaRights", new ConstructObject(MediaRights.ConstructMediaRightsObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Reason", new ConstructObject(Reason.ConstructReasonObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("AppScreenshot", new ConstructObject(AppScreenshot.ConstructAppScreenshotObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ZplTrack", new ConstructObject(ZplTrack.ConstructZplTrackObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Network", new ConstructObject(Network.ConstructNetworkObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("RecommendedArtist", new ConstructObject(RecommendedArtist.ConstructRecommendedArtistObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("MovieTrailer", new ConstructObject(MovieTrailer.ConstructMovieTrailerObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("ArtistEventList", new ConstructObject(ArtistEventList.ConstructArtistEventListObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Short", new ConstructObject(Short.ConstructShortObject)); + XmlDataProviderObjectFactory.RegisterTypeConstructor("Contributor", new ConstructObject(Contributor.ConstructContributorObject)); + } + } +} diff --git a/ZuneXml/XmlDataProviderQuery.cs b/ZuneXml/XmlDataProviderQuery.cs new file mode 100644 index 0000000..d3590f4 --- /dev/null +++ b/ZuneXml/XmlDataProviderQuery.cs @@ -0,0 +1,537 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.XmlDataProviderQuery +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using Microsoft.Zune.Configuration; +using Microsoft.Zune.PerfTrace; +using Microsoft.Zune.Service; +using Microsoft.Zune.Shell; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using System.Threading; +using System.Xml; + +namespace ZuneXml +{ + public class XmlDataProviderQuery : DataProviderQuery + { + protected EPassportPolicyId _passportTicketType; + protected HttpRequestCachePolicy _cachePolicy; + private string _lastUri; + internal int _requestGeneration; + protected bool _keepAlive; + protected bool _ignoreNamespacePrefix; + protected bool _ignoreDuplicateGenerationRequests; + protected bool _acceptGZipEncoding; + private object _errorCode; + private bool _refreshOnCacheExpire; + private Microsoft.Iris.Timer _autoRefreshTimer; + + protected XmlDataProviderQuery(object queryTypeCookie) + : base(queryTypeCookie) + { + this._passportTicketType = EPassportPolicyId.None; + this._cachePolicy = HttpRequestCachePolicy.Default; + this._keepAlive = true; + this._ignoreNamespacePrefix = true; + this._ignoreDuplicateGenerationRequests = true; + this.Result = (object)XmlDataProviderObjectFactory.CreateObject((DataProviderQuery)this, this.ResultTypeCookie); + } + + protected override void OnDispose() + { + base.OnDispose(); + if (this._autoRefreshTimer == null) + return; + this._autoRefreshTimer.Stop(); + this._autoRefreshTimer.Dispose(); + this._autoRefreshTimer = (Microsoft.Iris.Timer)null; + } + + public object ErrorCode => this._errorCode; + + public HttpRequestCachePolicy CachePolicy + { + get => this._cachePolicy; + set => this._cachePolicy = value; + } + + public EPassportPolicyId PassportTicketType + { + get => this._passportTicketType; + set => this._passportTicketType = value; + } + + public bool IgnoreDuplicateGenerationRequests + { + get => this._ignoreDuplicateGenerationRequests; + set => this._ignoreDuplicateGenerationRequests = value; + } + + public bool RefreshOnCacheExpire + { + get => this._refreshOnCacheExpire; + set => this._refreshOnCacheExpire = value; + } + + protected override void BeginExecute() + { + if (this.GetProperty("SendPassportTicket") is bool property) + this._passportTicketType = property ? EPassportPolicyId.MBI : EPassportPolicyId.None; + if (this.GetProperty("SendSecurePassportTicket") is bool property) + this._passportTicketType = property ? EPassportPolicyId.MBI_SSL : EPassportPolicyId.None; + if (this.GetProperty("RefreshOnCacheExpire") is bool property) + this._refreshOnCacheExpire = property; + string resourceUri = this.GetResourceUri(); + string postBody = this.GetPostBody(); + if (string.IsNullOrEmpty(resourceUri)) + return; + this.GetDataFromResource(resourceUri, postBody, true); + } + + protected virtual string GetResourceUri() => (string)null; + + protected virtual string GetPostBody() => (string)null; + + internal virtual bool FilterDataProviderObject(XmlDataProviderObject dataObject) => false; + + protected override void OnPropertyChanged(string propertyName) + { + if (propertyName == "LocalSortBy" && this.Result != null) + ((XmlDataProviderObject)this.Result).ChangeListSort((string)this.GetProperty(propertyName)); + base.OnPropertyChanged(propertyName); + } + + internal void GetDataFromResource(string uri, string body, bool fNewGeneration) + { + XmlDataProviderQuery.GetDataFromResourceArgs fromResourceArgs = new XmlDataProviderQuery.GetDataFromResourceArgs(uri, body, fNewGeneration); + if (Application.IsApplicationThread) + this.GetDataFromResource((object)fromResourceArgs); + else + Application.DeferredInvoke(new DeferredInvokeHandler(this.GetDataFromResource), (object)fromResourceArgs); + } + + private void GetDataFromResource(object obj) + { + XmlDataProviderQuery.GetDataFromResourceArgs fromResourceArgs = (XmlDataProviderQuery.GetDataFromResourceArgs)obj; + string requestUri = fromResourceArgs.Uri; + string requestBody = fromResourceArgs.Body; + bool newGeneration = fromResourceArgs.NewGeneration; + string property1 = (string)this.GetProperty("LocalSortBy"); + bool fPaged = this.GetProperty("Paged") is bool property2 && property2; + XmlDataProviderObject result = (XmlDataProviderObject)null; + if (newGeneration) + { + ++this._requestGeneration; + result = XmlDataProviderObjectFactory.CreateObject((DataProviderQuery)this, this.ResultTypeCookie); + if (property1 != null) + result.ChangeListSort(property1); + } + else + { + result = (XmlDataProviderObject)this.Result; + if (this._ignoreDuplicateGenerationRequests && string.Equals(requestUri, this._lastUri, StringComparison.CurrentCultureIgnoreCase)) + return; + } + this._lastUri = requestUri; + this.SetWorkerStatus(this._requestGeneration, DataProviderQueryStatus.RequestingData); + bool flag = false; + string localUri = (string)null; + if (!flag) + ThreadPool.QueueUserWorkItem((WaitCallback)(arg => + { + int requestGeneration = (int)arg; + Microsoft.Zune.Service.HttpWebRequest httpWebRequest = this.ConstructWebRequest(requestUri, requestBody); + XmlDataProviderQuery.RequestArgs requestArgs = new XmlDataProviderQuery.RequestArgs(requestGeneration, requestUri, requestBody, localUri, result, fPaged, DateTime.Now, Environment.TickCount, httpWebRequest.CachePolicy); + httpWebRequest.GetResponseAsync(new AsyncRequestComplete(this.OnRequestComplete), (object)requestArgs); + }), (object)this._requestGeneration); + Microsoft.Zune.PerfTrace.PerfTrace.TraceUICollectionEvent(UICollectionEvent.DataProviderQueryBegin, this._lastUri); + } + + private void OnRequestComplete(Microsoft.Zune.Service.HttpWebResponse response, object requestArgs) + { + XmlDataProviderQuery.RequestArgs requestArgs1 = (XmlDataProviderQuery.RequestArgs)requestArgs; + Stream xmlStream = (Stream)null; + try + { + xmlStream = response.StatusCode == HttpStatusCode.OK ? response.GetResponseStream() : throw new HttpWebException(response); + this.ParseXml(xmlStream, requestArgs1.m_requestGeneration, requestArgs1.m_requestUri, requestArgs1.m_requestBody, requestArgs1.m_result, requestArgs1.m_fPaged, requestArgs1.m_tmStartTime, requestArgs1.m_tcStart); + if (requestArgs1.m_cachePolicy == HttpRequestCachePolicy.Refresh && this._cachePolicy == HttpRequestCachePolicy.Default && requestArgs1.m_result.NextPage != null) + UriResourceTracker.Instance.SetResourceModified(requestArgs1.m_result.NextPage.GetPageUrl(0), true); + this.SetAutoRefreshTimer(response.Expires); + } + catch (Exception ex) + { + if (ex is HttpWebException) + { + object statusCode = (object)((HttpWebException)ex).Response.StatusCode; + this.SetWorkerStatus(requestArgs1.m_requestGeneration, DataProviderQueryStatus.Error, statusCode); + } + else + this.SetWorkerStatus(requestArgs1.m_requestGeneration, DataProviderQueryStatus.Error, (object)null); + int num = TraceSwitches.DataProviderSwitch.TraceWarning ? 1 : 0; + } + finally + { + xmlStream?.Close(); + response.Close(); + Microsoft.Zune.PerfTrace.PerfTrace.TraceUICollectionEvent(UICollectionEvent.DataProviderQueryComplete, this._lastUri); + } + } + + private void ParseXml( + Stream xmlStream, + int requestGeneration, + string requestUri, + string requestBody, + XmlDataProviderObject result, + bool fPaged, + DateTime tmStartTime, + int tcStart) + { + int num1 = 0; + int num2 = 0; + bool flag1 = false; + XmlDataProviderReader xmlReader = (XmlDataProviderReader)null; + try + { + num1 = Environment.TickCount - tcStart; + this.SetWorkerStatus(requestGeneration, DataProviderQueryStatus.ProcessingData); + StringBuilder stringBuilder = new StringBuilder(80); + int[] numArray = new int[20]; + xmlReader = new XmlDataProviderReader(xmlStream); + List xpathMatchList = new List(2); + bool flag2 = false; + int num3 = TraceSwitches.DataProviderSwitch.TraceVerbose ? 1 : 0; + XmlNodeType xmlNodeType = XmlNodeType.None; + while (xmlNodeType != XmlNodeType.None || xmlReader.Read()) + { + xmlNodeType = XmlNodeType.None; + if (requestGeneration != this._requestGeneration) + { + flag2 = true; + break; + } + if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Depth < numArray.Length) + { + int depth = xmlReader.Depth; + stringBuilder.Length = depth > 0 ? numArray[depth - 1] : 0; + stringBuilder.Append('/'); + if (this._ignoreNamespacePrefix) + stringBuilder.Append(xmlReader.LocalName); + else + stringBuilder.Append(xmlReader.Name); + numArray[depth] = stringBuilder.Length; + string str = stringBuilder.ToString(); + if (fPaged) + { + IPageInfo nextPageInfo = this.ExtractNextPageInfo(requestUri, requestBody, str, xmlReader); + if (nextPageInfo != null) + result.NextPage = nextPageInfo; + } + Hashtable attributes = new Hashtable(3); + if (xmlReader.MoveToFirstAttribute()) + { + do + { + attributes[(object)xmlReader.Name] = (object)xmlReader.Value; + } + while (xmlReader.MoveToNextAttribute()); + } + result.ProcessXPath(str, attributes, xpathMatchList); + if (xpathMatchList.Count > 0) + { + flag1 = true; + string xmlValue = (string)null; + if (xmlReader.Read() && (xmlNodeType = xmlReader.NodeType) == XmlNodeType.Text) + { + xmlNodeType = XmlNodeType.None; + xmlValue = xmlReader.Value; + } + XmlDataProviderQuery.ProcessXPathMatches(xpathMatchList, attributes, xmlValue, xmlReader); + } + foreach (string key in (IEnumerable)attributes.Keys) + { + result.ProcessXPath(str + "@" + key, attributes, xpathMatchList); + if (xpathMatchList.Count > 0) + { + flag1 = true; + XmlDataProviderQuery.ProcessXPathMatches(xpathMatchList, attributes, (string)null, (XmlDataProviderReader)null); + } + } + } + } + if (!flag2) + { + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetResult), (object)new XmlDataProviderQuery.DeferredSetResultArgs(requestGeneration, result)); + this.SetWorkerStatus(requestGeneration, DataProviderQueryStatus.Complete); + if (TraceSwitches.DataProviderSwitch.TraceWarning) + { + num2 = Environment.TickCount - tcStart; + int num4 = flag1 ? 1 : 0; + } + } + } + catch (Exception ex) + { + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetResult), (object)new XmlDataProviderQuery.DeferredSetResultArgs(requestGeneration, result)); + this.SetWorkerStatus(requestGeneration, DataProviderQueryStatus.Error); + throw ex; + } + finally + { + xmlReader?.Close(); + } + int num5 = TraceSwitches.DataProviderSwitch.TraceVerbose ? 1 : 0; + } + + internal virtual IPageInfo ExtractNextPageInfo( + string requestUri, + string requestBody, + string strElementPath, + XmlDataProviderReader xmlReader) + { + if (strElementPath == "/feed/link") + { + bool flag = false; + if (xmlReader.MoveToFirstAttribute()) + { + do + { + if (xmlReader.Name == "rel") + flag = xmlReader.Value == "next"; + else if (xmlReader.Name == "href" && flag && !string.IsNullOrEmpty(xmlReader.Value)) + return (IPageInfo)new LinkPageInfo(XmlDataProviderQuery.ConstructLinkUrl(requestUri, xmlReader.Value), requestBody); + } + while (xmlReader.MoveToNextAttribute()); + } + } + return (IPageInfo)null; + } + + private Microsoft.Zune.Service.HttpWebRequest ConstructWebRequest( + string requestUri, + string requestBody) + { + return requestBody != null ? WebRequestHelper.ConstructWebPostRequest(requestUri, requestBody, this._passportTicketType, this._cachePolicy, this._keepAlive, this._acceptGZipEncoding) : WebRequestHelper.ConstructWebRequest(requestUri, this._passportTicketType, this._cachePolicy, this._keepAlive, this._acceptGZipEncoding); + } + + private static string ConstructLinkUrl(string baseUrl, string relativeUrl) + { + string str = (string)null; + if (relativeUrl.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) + { + str = relativeUrl; + } + else + { + int num = baseUrl.IndexOf("//"); + if (num > 0) + { + int length = baseUrl.IndexOf('/', num + 2); + if (length > 0) + str = baseUrl.Substring(0, length) + relativeUrl; + } + } + return str; + } + + private static void ProcessXPathMatches( + List xpathMatches, + Hashtable attributes, + string xmlValue, + XmlDataProviderReader xmlReader) + { + foreach (XmlDataProviderQuery.XPathMatch xpathMatch in xpathMatches) + { + string str = xmlValue; + if (xpathMatch.matchingAttributeName != null) + str = (string)attributes[(object)xpathMatch.matchingAttributeName]; + if (xpathMatch.encodedXml && str != null && xmlReader != null) + xmlReader.PushElement(str); + else if (str != null) + xpathMatch.instance.SetPropertyFromStringValue(xpathMatch.propertyMapping, str); + } + xpathMatches.Clear(); + } + + protected void SetWorkerStatus(int requestGeneration, DataProviderQueryStatus eStatus) => this.SetWorkerStatus(requestGeneration, eStatus, (object)null); + + protected void SetWorkerStatus( + int requestGeneration, + DataProviderQueryStatus eStatus, + object errorCode) + { + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetStatus), (object)new XmlDataProviderQuery.DeferredSetStatusArgs(requestGeneration, eStatus, errorCode)); + } + + private void DeferredSetStatus(object args) + { + if (!(args is XmlDataProviderQuery.DeferredSetStatusArgs deferredSetStatusArgs) || deferredSetStatusArgs.m_requestGeneration != this._requestGeneration) + return; + this.Status = deferredSetStatusArgs.m_eStatus; + this._errorCode = this.Status != DataProviderQueryStatus.Error ? (object)null : deferredSetStatusArgs.m_errorCode; + if (this.Status == DataProviderQueryStatus.Error) + this._lastUri = (string)null; + if (this.Result == null || this.Status != DataProviderQueryStatus.Complete) + return; + ((XmlDataProviderObject)this.Result).OnQueryComplete(); + } + + private void SetAutoRefreshTimer(DateTime expires) + { + if (!this._refreshOnCacheExpire) + return; + Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetAutoRefreshTimer), (object)expires); + } + + private void DeferredSetAutoRefreshTimer(object args) + { + DateTime utcNow = DateTime.UtcNow; + DateTime dateTime = (DateTime)args; + if (dateTime == DateTime.MaxValue || dateTime <= utcNow) + { + int refreshQueryFallback = ClientConfiguration.Service.AutoRefreshQueryFallback; + dateTime = utcNow.AddMilliseconds((double)refreshQueryFallback); + } + if (!(dateTime != DateTime.MaxValue)) + return; + if (this._autoRefreshTimer == null) + { + this._autoRefreshTimer = new Microsoft.Iris.Timer(); + this._autoRefreshTimer.Tick += (EventHandler)((sender, eventArgs) => + { + this._autoRefreshTimer.Stop(); + this.Refresh(); + }); + } + int num1 = new Random().Next(1, 300000); + if (dateTime > utcNow) + { + long num2 = dateTime.Subtract(utcNow).Ticks / 10000L; + if (num2 > (long)(int.MaxValue - num1)) + num1 += 900000; + else + num1 += (int)num2; + } + this._autoRefreshTimer.Stop(); + this._autoRefreshTimer.Interval = num1; + this._autoRefreshTimer.Start(); + } + + private void DeferredSetResult(object argsObj) + { + if (!(argsObj is XmlDataProviderQuery.DeferredSetResultArgs deferredSetResultArgs) || deferredSetResultArgs.m_requestGeneration != this._requestGeneration) + return; + deferredSetResultArgs.m_result.TransferToAppThread(); + if (this.Result == deferredSetResultArgs.m_result) + return; + this.Result = (object)deferredSetResultArgs.m_result; + } + + private class GetDataFromResourceArgs + { + public readonly string Uri; + public readonly string Body; + public readonly bool NewGeneration; + + public GetDataFromResourceArgs(string uri, string body, bool fNewGeneration) + { + this.Uri = uri; + this.Body = body; + this.NewGeneration = fNewGeneration; + } + } + + private class RequestArgs + { + public readonly int m_requestGeneration; + public readonly string m_requestUri; + public readonly string m_requestBody; + public readonly string m_localUri; + public readonly XmlDataProviderObject m_result; + public readonly bool m_fPaged; + public readonly DateTime m_tmStartTime; + public readonly int m_tcStart; + public readonly HttpRequestCachePolicy m_cachePolicy; + + public RequestArgs( + int requestGeneration, + string requestUri, + string requestBody, + string localUri, + XmlDataProviderObject result, + bool fPaged, + DateTime tmStartTime, + int tcStart, + HttpRequestCachePolicy cachePolicy) + { + this.m_requestGeneration = requestGeneration; + this.m_requestUri = requestUri; + this.m_requestBody = requestBody; + this.m_localUri = localUri; + this.m_result = result; + this.m_fPaged = fPaged; + this.m_tmStartTime = tmStartTime; + this.m_tcStart = tcStart; + this.m_cachePolicy = cachePolicy; + } + } + + private class DeferredSetStatusArgs + { + public readonly DataProviderQueryStatus m_eStatus; + public readonly int m_requestGeneration; + public readonly object m_errorCode; + + public DeferredSetStatusArgs( + int requestGeneration, + DataProviderQueryStatus eStatus, + object errorCode) + { + this.m_eStatus = eStatus; + this.m_requestGeneration = requestGeneration; + this.m_errorCode = errorCode; + } + } + + private class DeferredSetResultArgs + { + public readonly XmlDataProviderObject m_result; + public readonly int m_requestGeneration; + + public DeferredSetResultArgs(int requestGeneration, XmlDataProviderObject result) + { + this.m_requestGeneration = requestGeneration; + this.m_result = result; + } + } + + public struct XPathMatch + { + public XmlDataProviderObject instance; + public DataProviderMapping propertyMapping; + public string matchingAttributeName; + public bool encodedXml; + + public XPathMatch( + XmlDataProviderObject instance, + DataProviderMapping propertyMapping, + string matchingAttributeName, + bool encodedXml) + { + this.instance = instance; + this.propertyMapping = propertyMapping; + this.matchingAttributeName = matchingAttributeName; + this.encodedXml = encodedXml; + } + } + } +} diff --git a/ZuneXml/XmlDataProviderReader.cs b/ZuneXml/XmlDataProviderReader.cs new file mode 100644 index 0000000..9868c2b --- /dev/null +++ b/ZuneXml/XmlDataProviderReader.cs @@ -0,0 +1,164 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.XmlDataProviderReader +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Collections; +using System.IO; +using System.Xml; + +namespace ZuneXml +{ + internal class XmlDataProviderReader + { + private Stack _internalStack; + private XmlTextReader _currentReader; + private int _parentDepth; + + public XmlDataProviderReader(Stream xmlStream) => this.PushReader(new XmlTextReader(xmlStream) + { + WhitespaceHandling = WhitespaceHandling.None + }); + + public void Close() + { + while (this._currentReader != null) + this.CloseCurrent(); + } + + public int Depth + { + get + { + int parentDepth = this._parentDepth; + if (this.Count > 0) + parentDepth += this._currentReader.Depth; + return parentDepth; + } + } + + public string LocalName + { + get + { + string str = string.Empty; + if (this._currentReader != null) + str = this._currentReader.LocalName; + return str; + } + } + + public string Name + { + get + { + string str = string.Empty; + if (this._currentReader != null) + str = this._currentReader.Name; + return str; + } + } + + public string Value + { + get + { + string empty = string.Empty; + if (this._currentReader != null) + empty = this._currentReader.Value; + return empty; + } + } + + public XmlNodeType NodeType + { + get + { + XmlNodeType xmlNodeType = XmlNodeType.None; + if (this._currentReader != null) + xmlNodeType = this._currentReader.NodeType; + return xmlNodeType; + } + } + + private int Count => (this._internalStack != null ? this._internalStack.Count : 0) + (this._currentReader != null ? 1 : 0); + + public bool Read() + { + bool flag = false; + if (this._currentReader != null) + { + flag = this._currentReader.Read(); + if (!flag) + this.CloseCurrent(); + } + return flag; + } + + public bool MoveToFirstAttribute() + { + bool flag = false; + if (this._currentReader != null) + flag = this._currentReader.MoveToFirstAttribute(); + return flag; + } + + public bool MoveToNextAttribute() + { + bool flag = false; + if (this._currentReader != null) + flag = this._currentReader.MoveToNextAttribute(); + return flag; + } + + public void PushElement(string xmlElement) + { + if (this.Count <= 0 || string.IsNullOrEmpty(xmlElement)) + return; + XmlParserContext context = new XmlParserContext(this._currentReader.NameTable, new XmlNamespaceManager(this._currentReader.NameTable), this._currentReader.XmlLang, XmlSpace.None, this._currentReader.Encoding); + this.PushReader(new XmlTextReader(xmlElement, XmlNodeType.Element, context) + { + WhitespaceHandling = WhitespaceHandling.None + }); + } + + private void CloseCurrent() + { + if (this._currentReader != null) + this._currentReader.Close(); + this.PopReader(); + } + + private void PushReader(XmlTextReader reader) + { + if (this._currentReader != null) + { + if (this._internalStack == null) + this._internalStack = new Stack(2); + this._parentDepth += this._currentReader.Depth; + this._internalStack.Push((object)this._currentReader); + } + else + this._parentDepth = 0; + this._currentReader = reader; + } + + private void PopReader() + { + if (this._internalStack != null && this._internalStack.Count > 0) + { + this._currentReader = (XmlTextReader)this._internalStack.Pop(); + this._parentDepth -= this._currentReader.Depth; + if (this._parentDepth >= 0) + return; + this._parentDepth = 0; + } + else + { + this._currentReader = (XmlTextReader)null; + this._parentDepth = 0; + } + } + } +} diff --git a/ZuneXml/XmlDataProviders.cs b/ZuneXml/XmlDataProviders.cs new file mode 100644 index 0000000..f43ae09 --- /dev/null +++ b/ZuneXml/XmlDataProviders.cs @@ -0,0 +1,20 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.XmlDataProviders +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal static class XmlDataProviders + { + internal static void Register() + { + Application.RegisterDataProvider("ZuneService", new DataProviderQueryFactory(ZuneServiceQuery.ConstructZuneServiceQuery)); + Application.RegisterDataProvider("WMISFAI", new DataProviderQueryFactory(WMISServiceDataProviderQuery.ConstructWmisQuery)); + Application.RegisterDataProvider("InboxImage", new DataProviderQueryFactory(InboxImageQuery.ConstructQuery)); + } + } +} diff --git a/ZuneXml/XmlDataVirtualList.cs b/ZuneXml/XmlDataVirtualList.cs new file mode 100644 index 0000000..86d88e2 --- /dev/null +++ b/ZuneXml/XmlDataVirtualList.cs @@ -0,0 +1,245 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.XmlDataVirtualList +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; + +namespace ZuneXml +{ + public class XmlDataVirtualList : VirtualList, IXmlDataProviderObject + { + private DataProviderQuery _owner; + private int _currentIndex; + private object _itemTypeCookie; + private ConstructObject _itemConstructor; + private int _chunkStartIndex; + private List _chunkItems; + private string _encodedSortBy; + private string[] _sortBy; + private bool[] _sortAscending; + private IPageInfo _nextPage; + private bool _pageToEnd; + + public XmlDataVirtualList(DataProviderQuery owner, object itemTypeCookie) + : base(true) + { + this._owner = owner; + this._itemTypeCookie = itemTypeCookie; + this._itemConstructor = itemTypeCookie == null ? (ConstructObject)null : XmlDataProviderObjectFactory.GetConstructor(itemTypeCookie); + this._currentIndex = -1; + this._chunkStartIndex = 0; + this._encodedSortBy = (string)null; + this._sortAscending = (bool[])null; + this._sortBy = (string[])null; + } + + internal IPageInfo NextPage + { + get => this._nextPage; + set => this._nextPage = value; + } + + public bool PageToEnd + { + get => this._pageToEnd; + set + { + if (this._pageToEnd == value) + return; + this._pageToEnd = value; + if (!this._pageToEnd) + return; + this.GetNextChunk(); + } + } + + protected override object OnRequestItem(int index) => this.Data[(object)index]; + + protected override void OnRequestSlowData(int index) + { + this.NotifySlowDataAcquireComplete(index); + if (index != this.Count - 1 || this._chunkStartIndex == this.Count || (this.NextPage == null || this.PageToEnd)) + return; + this.GetNextChunk(); + } + + private void GetNextChunk() + { + if (this.NextPage == null) + return; + this._chunkStartIndex = this.Count; + this._currentIndex = -1; + if (!(this._owner is XmlDataProviderQuery owner)) + return; + ThreadPool.QueueUserWorkItem(new WaitCallback(XmlDataVirtualList.GetNextChunkThread), (object)new XmlDataVirtualList.GetNextChunkArgs(owner, this.NextPage, this._chunkStartIndex)); + } + + private static void GetNextChunkThread(object obj) + { + XmlDataVirtualList.GetNextChunkArgs getNextChunkArgs = (XmlDataVirtualList.GetNextChunkArgs)obj; + string pageUrl = getNextChunkArgs.PageInfo.GetPageUrl(getNextChunkArgs.StartIndex); + string pagePostBody = getNextChunkArgs.PageInfo.GetPagePostBody(getNextChunkArgs.StartIndex); + if (string.IsNullOrEmpty(pageUrl)) + return; + getNextChunkArgs.Query.GetDataFromResource(pageUrl, pagePostBody, false); + } + + public bool ProcessXPath( + string currentXPath, + Hashtable attributes, + List matches) + { + bool flag = false; + if (string.IsNullOrEmpty(currentXPath)) + { + if (this._chunkItems == null) + this._chunkItems = new List(); + ++this._currentIndex; + if (this._itemConstructor != null) + this._chunkItems.Add(this._itemConstructor(this._owner, this._itemTypeCookie)); + else + this._chunkItems.Add(new XmlDataProviderObject(this._owner, this._itemTypeCookie)); + } + else + { + IXmlDataProviderObject chunkItem = (IXmlDataProviderObject)this._chunkItems[this._currentIndex]; + if (chunkItem != null) + flag = chunkItem.ProcessXPath(currentXPath, attributes, matches); + } + return flag; + } + + internal void TransferToAppThread() + { + if (this._chunkItems == null) + return; + foreach (XmlDataProviderObject chunkItem in this._chunkItems) + chunkItem.TransferToAppThread(); + int count = 0; + foreach (XmlDataProviderObject chunkItem in this._chunkItems) + { + if (!(this._owner is XmlDataProviderQuery owner) || !owner.FilterDataProviderObject(chunkItem)) + this.Data[(object)(this._chunkStartIndex + count++)] = (object)chunkItem; + } + this.AddRange(count); + this.Sort(); + this._chunkItems.Clear(); + } + + internal void OnQueryComplete() + { + if (this.NextPage == null || !this.PageToEnd) + return; + this.GetNextChunk(); + } + + private void Sort() + { + if (this._sortBy == null || this._sortBy.Length <= 0 || this.Count <= 1) + return; + IPageInfo nextPage = this.NextPage; + XmlDataProviderObject[] array = new XmlDataProviderObject[this.Count]; + if (array == null) + return; + for (int index = 0; index < this.Count; ++index) + array[index] = (XmlDataProviderObject)this.Data[(object)index]; + Array.Sort(array, new Comparison(this.CompareUsingSortBy)); + for (int index = 0; index < this.Count; ++index) + { + this.Data[(object)index] = (object)array[index]; + this.Modified(index); + } + } + + public string SortBy + { + get => this._encodedSortBy; + set + { + if (!(this._encodedSortBy != value)) + return; + string[] strArray1 = (string[])null; + bool[] flagArray = (bool[])null; + if (!string.IsNullOrEmpty(value)) + { + string[] strArray2 = value.Split(','); + strArray1 = new string[strArray2.Length]; + flagArray = new bool[strArray2.Length]; + for (int index = 0; index < strArray2.Length; ++index) + this.ExtractSortData(strArray2[index], out strArray1[index], out flagArray[index]); + } + this._sortBy = strArray1; + this._sortAscending = flagArray; + this.Sort(); + } + } + + private void ExtractSortData(string sort, out string filteredValue, out bool sortAscending) + { + filteredValue = sort; + sortAscending = true; + if (string.IsNullOrEmpty(sort)) + return; + if (sort[0] == '-') + { + filteredValue = sort.Substring(1); + sortAscending = false; + } + else + { + if (sort[0] != '+') + return; + filteredValue = sort.Substring(1); + sortAscending = true; + } + } + + private int CompareUsingSortBy(XmlDataProviderObject x, XmlDataProviderObject y) + { + int num = 0; + for (int index = 0; index < this._sortBy.Length; ++index) + { + num = XmlDataVirtualList.Compare(x, y, this._sortBy[index], this._sortAscending[index]); + if (num != 0) + break; + } + return num; + } + + private static int Compare( + XmlDataProviderObject x, + XmlDataProviderObject y, + string propertyName, + bool ascending) + { + object property1 = x.GetProperty(propertyName); + object property2 = y.GetProperty(propertyName); + IComparable comparable1 = property1 as IComparable; + IComparable comparable2 = property2 as IComparable; + if (comparable1 == null || comparable2 == null) + return 0; + int num = comparable1.CompareTo((object)comparable2); + return ascending ? num : -num; + } + + private class GetNextChunkArgs + { + public readonly XmlDataProviderQuery Query; + public readonly IPageInfo PageInfo; + public readonly int StartIndex; + + public GetNextChunkArgs(XmlDataProviderQuery query, IPageInfo pageInfo, int startIndex) + { + this.Query = query; + this.PageInfo = pageInfo; + this.StartIndex = startIndex; + } + } + } +} diff --git a/ZuneXml/ZplTrack.cs b/ZuneXml/ZplTrack.cs new file mode 100644 index 0000000..308312d --- /dev/null +++ b/ZuneXml/ZplTrack.cs @@ -0,0 +1,86 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ZplTrack +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class ZplTrack : PlaylistTrack + { + internal static XmlDataProviderObject ConstructZplTrackObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ZplTrack(owner, objectTypeCookie); + } + + internal ZplTrack(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Actionable": + return (object)this.Actionable; + case "UserRating": + return (object)this.UserRating; + case "LibraryId": + return (object)this.LibraryId; + case "PointsPrice": + return (object)this.PointsPrice; + case "HasPoints": + return (object)this.HasPoints; + case "CanPlay": + return (object)this.CanPlay; + case "CanPreview": + return (object)this.CanPreview; + case "CanSubscriptionPlay": + return (object)this.CanSubscriptionPlay; + case "CanDownload": + return (object)this.CanDownload; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFree": + return (object)this.CanPurchaseFree; + case "CanPurchaseMP3": + return (object)this.CanPurchaseMP3; + case "CanPurchaseAlbumOnly": + return (object)this.CanPurchaseAlbumOnly; + case "CanPurchaseSubscriptionFree": + return (object)this.CanPurchaseSubscriptionFree; + case "CanSync": + return (object)this.CanSync; + case "CanBurn": + return (object)this.CanBurn; + case "InCollection": + return (object)this.InCollection; + case "IsDownloading": + return (object)this.IsDownloading; + case "IsParentallyBlocked": + return (object)this.IsParentallyBlocked; + case "Ordinal": + return (object)this.Ordinal; + case "SortTitle": + return (object)this.SortTitle; + case "ImageId": + return (object)this.ImageId; + case "Rights": + return (object)this.Rights; + case "PrimaryArtist": + return (object)this.PrimaryArtist; + case "Artists": + return (object)this.Artists; + case "Popularity": + return (object)this.Popularity; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/ZuneHDApp.cs b/ZuneXml/ZuneHDApp.cs new file mode 100644 index 0000000..59c1623 --- /dev/null +++ b/ZuneXml/ZuneHDApp.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ZuneHDApp +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class ZuneHDApp : App + { + internal static XmlDataProviderObject ConstructZuneHDAppObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ZuneHDApp(owner, objectTypeCookie); + } + + internal ZuneHDApp(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Price": + return (object)this.Price; + case "DisplayPrice": + return (object)this.DisplayPrice; + case "DisplayPriceFull": + return (object)this.DisplayPriceFull; + case "DisplayPriceTrial": + return (object)this.DisplayPriceTrial; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFull": + return (object)this.CanPurchaseFull; + case "CanPurchaseTrial": + return (object)this.CanPurchaseTrial; + case "CanDownload": + return (object)this.CanDownload; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/ZuneHDAppData.cs b/ZuneXml/ZuneHDAppData.cs new file mode 100644 index 0000000..477bc8c --- /dev/null +++ b/ZuneXml/ZuneHDAppData.cs @@ -0,0 +1,50 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ZuneHDAppData +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class ZuneHDAppData : AppData + { + internal static XmlDataProviderObject ConstructZuneHDAppDataObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ZuneHDAppData(owner, objectTypeCookie); + } + + internal ZuneHDAppData(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + + public override object GetProperty(string propertyName) + { + switch (propertyName) + { + case "Price": + return (object)this.Price; + case "DisplayPrice": + return (object)this.DisplayPrice; + case "DisplayPriceFull": + return (object)this.DisplayPriceFull; + case "DisplayPriceTrial": + return (object)this.DisplayPriceTrial; + case "CanPurchase": + return (object)this.CanPurchase; + case "CanPurchaseFull": + return (object)this.CanPurchaseFull; + case "CanPurchaseTrial": + return (object)this.CanPurchaseTrial; + case "CanDownload": + return (object)this.CanDownload; + default: + return base.GetProperty(propertyName); + } + } + } +} diff --git a/ZuneXml/ZuneHDAppGenre.cs b/ZuneXml/ZuneHDAppGenre.cs new file mode 100644 index 0000000..c8f63e3 --- /dev/null +++ b/ZuneXml/ZuneHDAppGenre.cs @@ -0,0 +1,25 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ZuneHDAppGenre +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; + +namespace ZuneXml +{ + internal class ZuneHDAppGenre : AppGenre + { + internal static XmlDataProviderObject ConstructZuneHDAppGenreObject( + DataProviderQuery owner, + object objectTypeCookie) + { + return (XmlDataProviderObject)new ZuneHDAppGenre(owner, objectTypeCookie); + } + + internal ZuneHDAppGenre(DataProviderQuery owner, object resultTypeCookie) + : base(owner, resultTypeCookie) + { + } + } +} diff --git a/ZuneXml/ZuneServiceQuery.cs b/ZuneXml/ZuneServiceQuery.cs new file mode 100644 index 0000000..1fa5c97 --- /dev/null +++ b/ZuneXml/ZuneServiceQuery.cs @@ -0,0 +1,93 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ZuneServiceQuery +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using Microsoft.Iris; +using System.Collections.Generic; + +namespace ZuneXml +{ + internal class ZuneServiceQuery : XmlDataProviderQuery + { + private static IDictionary _queryTypeToHelper; + private ZuneServiceQueryHelper _helper; + + private static void RegisterZuneServiceQueryConstructors( + IDictionary queryTypeToHelper) + { + queryTypeToHelper.Add("Marketplace", new ZuneServiceQuery.ConstructQueryHelper(CatalogServiceQueryHelper.ConstructMusicCatalogQueryHelper)); + queryTypeToHelper.Add("MarketplaceSearch", new ZuneServiceQuery.ConstructQueryHelper(CatalogSearchQueryHelper.ConstructSearchQueryHelper)); + queryTypeToHelper.Add("Messaging", new ZuneServiceQuery.ConstructQueryHelper(MessagingQueryHelper.ConstructMessagingQueryHelper)); + queryTypeToHelper.Add("PodcastMarketplace", new ZuneServiceQuery.ConstructQueryHelper(PodcastCatalogServiceQueryHelper.ConstructPodcastCatalogQueryHelper)); + queryTypeToHelper.Add("PodcastMarketplaceSearch", new ZuneServiceQuery.ConstructQueryHelper(CatalogSearchQueryHelper.ConstructSearchQueryHelper)); + queryTypeToHelper.Add("PrefixSearch", new ZuneServiceQuery.ConstructQueryHelper(CatalogPrefixSearchQueryHelper.ConstructPrefixSearchQueryHelper)); + queryTypeToHelper.Add("Recommendations", new ZuneServiceQuery.ConstructQueryHelper(RecommendationsQueryHelper.ConstructRecommendationsQueryHelper)); + queryTypeToHelper.Add("Social", new ZuneServiceQuery.ConstructQueryHelper(SocialQueryHelper.ConstructSocialQueryHelper)); + queryTypeToHelper.Add("TopListeners", new ZuneServiceQuery.ConstructQueryHelper(TopListenersQueryHelper.ConstructTopListenersQueryHelper)); + queryTypeToHelper.Add("UriResource", new ZuneServiceQuery.ConstructQueryHelper(ZuneServiceQueryHelper.ConstructZuneServiceQueryHelper)); + queryTypeToHelper.Add("VideoMarketplace", new ZuneServiceQuery.ConstructQueryHelper(VideoCatalogServiceQueryHelper.ConstructVideoCatalogQuery)); + queryTypeToHelper.Add("VideoMarketplaceSearch", new ZuneServiceQuery.ConstructQueryHelper(CatalogSearchQueryHelper.ConstructSearchQueryHelper)); + queryTypeToHelper.Add("AppDetails", new ZuneServiceQuery.ConstructQueryHelper(AppDetailsQueryHelper.ConstructAppDetailsQueryHelper)); + queryTypeToHelper.Add("AppGenres", new ZuneServiceQuery.ConstructQueryHelper(AppGenresQueryHelper.ConstructAppGenresQueryHelper)); + queryTypeToHelper.Add("Reviews", new ZuneServiceQuery.ConstructQueryHelper(ReviewsQueryHelper.ConstructReviewsQueryHelper)); + queryTypeToHelper.Add("SubscriptionHistory", new ZuneServiceQuery.ConstructQueryHelper(SubscriptionHistoryQueryHelper.ConstructSubscriptionHistoryQueryHelper)); + queryTypeToHelper.Add("PurchaseHistory", new ZuneServiceQuery.ConstructQueryHelper(PurchaseHistoryQueryHelper.ConstructPurchaseHistoryQueryHelper)); + } + + internal static DataProviderQuery ConstructZuneServiceQuery( + object queryTypeCookie) + { + return (DataProviderQuery)new ZuneServiceQuery(queryTypeCookie); + } + + internal ZuneServiceQuery(object queryTypeCookie) + : base(queryTypeCookie) + => this._acceptGZipEncoding = true; + + internal ZuneServiceQueryHelper Helper + { + get + { + if (this._helper == null) + { + if (ZuneServiceQuery._queryTypeToHelper == null) + { + ZuneServiceQuery._queryTypeToHelper = (IDictionary)new Dictionary(17); + ZuneServiceQuery.RegisterZuneServiceQueryConstructors(ZuneServiceQuery._queryTypeToHelper); + } + string property = base.GetProperty("QueryType") as string; + this._helper = ZuneServiceQuery._queryTypeToHelper[property](this); + } + return this._helper; + } + } + + public override object GetProperty(string propertyName) => this.Helper.GetComputedProperty(propertyName) ?? base.GetProperty(propertyName); + + protected override string GetResourceUri() => this.Helper.GetResourceUri(); + + protected override string GetPostBody() => this.Helper.GetQueryPostBody(); + + protected override void BeginExecute() + { + if (this.Helper.HandleQueryBeginExecute()) + return; + base.BeginExecute(); + } + + internal override bool FilterDataProviderObject(XmlDataProviderObject dataObject) => this.Helper.OnQueryFilterDataProviderObject(dataObject); + + protected override void OnPropertyChanged(string propertyName) + { + if (!this.Initialized) + return; + base.OnPropertyChanged(propertyName); + this.Helper.OnQueryPropertyChanged(propertyName); + } + + private delegate ZuneServiceQueryHelper ConstructQueryHelper( + ZuneServiceQuery query); + } +} diff --git a/ZuneXml/ZuneServiceQueryHelper.cs b/ZuneXml/ZuneServiceQueryHelper.cs new file mode 100644 index 0000000..e7b4071 --- /dev/null +++ b/ZuneXml/ZuneServiceQueryHelper.cs @@ -0,0 +1,52 @@ +// Decompiled with JetBrains decompiler +// Type: ZuneXml.ZuneServiceQueryHelper +// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 +// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264 +// Assembly location: C:\Program Files\Zune\ZuneShell.dll + +using System.Text; + +namespace ZuneXml +{ + internal class ZuneServiceQueryHelper + { + private ZuneServiceQuery _query; + + internal static ZuneServiceQueryHelper ConstructZuneServiceQueryHelper( + ZuneServiceQuery query) + { + return new ZuneServiceQueryHelper(query); + } + + internal ZuneServiceQueryHelper(ZuneServiceQuery query) => this._query = query; + + internal ZuneServiceQuery Query => this._query; + + internal virtual string GetResourceUri() => this.Query.GetProperty("URI") as string; + + internal virtual object GetComputedProperty(string propertyName) => (object)null; + + internal virtual string GetQueryPostBody() => (string)null; + + internal virtual bool HandleQueryBeginExecute() => false; + + internal virtual void OnQueryPropertyChanged(string propertyName) + { + } + + internal virtual bool OnQueryFilterDataProviderObject(XmlDataProviderObject dataObject) => false; + + protected static void AppendParam( + StringBuilder requestUri, + string name, + string value, + ref bool fFirst) + { + requestUri.Append(fFirst ? "?" : "&"); + requestUri.Append(name); + requestUri.Append("="); + requestUri.Append(value); + fFirst = false; + } + } +} diff --git a/lib/UIX.dll b/lib/UIX.dll new file mode 100644 index 0000000..5cf8d2d Binary files /dev/null and b/lib/UIX.dll differ diff --git a/lib/UIXControls.dll b/lib/UIXControls.dll new file mode 100644 index 0000000..737b09c Binary files /dev/null and b/lib/UIXControls.dll differ diff --git a/lib/ZuneDBApi.dll b/lib/ZuneDBApi.dll new file mode 100644 index 0000000..426291c Binary files /dev/null and b/lib/ZuneDBApi.dll differ