diff --git a/NzbDrone.Core/Repository/Quality/QualityProfile.cs b/NzbDrone.Core/Repository/Quality/QualityProfile.cs index c12cc0ca0..43e0c7f00 100644 --- a/NzbDrone.Core/Repository/Quality/QualityProfile.cs +++ b/NzbDrone.Core/Repository/Quality/QualityProfile.cs @@ -9,6 +9,7 @@ namespace NzbDrone.Core.Repository.Quality { [SubSonicPrimaryKey(true)] public int ProfileId { get; set; } + [DisplayName("Name")] public string Name { get; set; } public bool UserProfile { get; set; } //Allows us to tell the difference between default and user profiles @@ -17,6 +18,11 @@ namespace NzbDrone.Core.Repository.Quality [DisplayName("Allowed Qualities")] public List Allowed { get; set; } + [SubSonicIgnore] + [DisplayName("Allowed Qualities String")] + public string AllowedString { get; set; } + + [DisplayName("Cutoff")] public QualityTypes Cutoff { get; set; } [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/NzbDrone.Web/Controllers/SettingsController.cs b/NzbDrone.Web/Controllers/SettingsController.cs index a046f03f2..fa73ab99a 100644 --- a/NzbDrone.Web/Controllers/SettingsController.cs +++ b/NzbDrone.Web/Controllers/SettingsController.cs @@ -98,8 +98,6 @@ namespace NzbDrone.Web.Controllers { ViewData["viewName"] = "Quality"; - var userProfiles = _qualityProvider.GetAllProfiles().Where(q => q.UserProfile).ToList(); - var profiles = _qualityProvider.GetAllProfiles().ToList(); var qualityTypes = new List(); foreach (QualityTypes qual in Enum.GetValues(typeof(QualityTypes))) @@ -107,6 +105,11 @@ namespace NzbDrone.Web.Controllers qualityTypes.Add(qual); } + ViewData["Qualities"] = qualityTypes; + + var userProfiles = _qualityProvider.GetAllProfiles().Where(q => q.UserProfile).ToList(); + var profiles = _qualityProvider.GetAllProfiles().ToList(); + var defaultQualityProfileId = Convert.ToInt32(_configProvider.GetValue("DefaultQualityProfile", profiles[0].ProfileId, true)); var selectList = new SelectList(profiles, "ProfileId", "Name"); @@ -115,7 +118,6 @@ namespace NzbDrone.Web.Controllers { Profiles = profiles, UserProfiles = userProfiles, - Qualities = qualityTypes, DefaultProfileId = defaultQualityProfileId, SelectList = selectList }; diff --git a/NzbDrone.Web/Helpers/HtmlPrefixScopeExtensions.cs b/NzbDrone.Web/Helpers/HtmlPrefixScopeExtensions.cs new file mode 100644 index 000000000..41a380bf1 --- /dev/null +++ b/NzbDrone.Web/Helpers/HtmlPrefixScopeExtensions.cs @@ -0,0 +1,63 @@ +using System; +using System.Web.Mvc; +using System.Web; +using System.Collections.Generic; + +namespace NzbDrone.Web.Helpers +{ + public static class HtmlPrefixScopeExtensions + { + private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_"; + + public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName) + { + var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName); + string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString(); + + // autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync. + html.ViewContext.Writer.WriteLine(string.Format("", collectionName, itemIndex)); + + return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex)); + } + + public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix) + { + return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix); + } + + private static Queue GetIdsToReuse(HttpContextBase httpContext, string collectionName) + { + // We need to use the same sequence of IDs following a server-side validation failure, + // otherwise the framework won't render the validation error messages next to each item. + string key = idsToReuseKey + collectionName; + var queue = (Queue)httpContext.Items[key]; + if (queue == null) { + httpContext.Items[key] = queue = new Queue(); + var previouslyUsedIds = httpContext.Request[collectionName + ".index"]; + if (!string.IsNullOrEmpty(previouslyUsedIds)) + foreach (string previouslyUsedId in previouslyUsedIds.Split(',')) + queue.Enqueue(previouslyUsedId); + } + return queue; + } + + private class HtmlFieldPrefixScope : IDisposable + { + private readonly TemplateInfo templateInfo; + private readonly string previousHtmlFieldPrefix; + + public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix) + { + this.templateInfo = templateInfo; + + previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix; + templateInfo.HtmlFieldPrefix = htmlFieldPrefix; + } + + public void Dispose() + { + templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix; + } + } + } +} \ No newline at end of file diff --git a/NzbDrone.Web/Models/QualityModel.cs b/NzbDrone.Web/Models/QualityModel.cs index 18ef5f6d4..4f000944a 100644 --- a/NzbDrone.Web/Models/QualityModel.cs +++ b/NzbDrone.Web/Models/QualityModel.cs @@ -12,7 +12,7 @@ namespace NzbDrone.Web.Models { public List Profiles { get; set; } public List UserProfiles { get; set; } - public List Qualities { get; set; } + //public List Qualities { get; set; } [DisplayName("Default Quality Profile")] public int DefaultProfileId { get; set; } diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index 8acdd5879..ab6e86e82 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -82,11 +82,13 @@ Global.asax + + @@ -267,10 +269,9 @@ + - - diff --git a/NzbDrone.Web/Views/Settings/Index.aspx b/NzbDrone.Web/Views/Settings/Index.aspx index 7edad835d..7778e955e 100644 --- a/NzbDrone.Web/Views/Settings/Index.aspx +++ b/NzbDrone.Web/Views/Settings/Index.aspx @@ -1,4 +1,5 @@ <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> +<%@ Import Namespace="NzbDrone.Core.Repository.Quality" %> Settings @@ -10,6 +11,5 @@ - <% Html.RenderPartial(ViewData["viewName"].ToString()); %> diff --git a/NzbDrone.Web/Views/Settings/Quality.ascx b/NzbDrone.Web/Views/Settings/Quality.ascx index f73fd1fcb..c2649ca86 100644 --- a/NzbDrone.Web/Views/Settings/Quality.ascx +++ b/NzbDrone.Web/Views/Settings/Quality.ascx @@ -1,5 +1,6 @@ <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <%@ Import Namespace="NzbDrone.Core.Repository.Quality" %> +<%@ Import Namespace="NzbDrone.Web.Helpers" %> --%> - \ No newline at end of file diff --git a/NzbDrone.Web/Views/Settings/UserProfileSection.ascx b/NzbDrone.Web/Views/Settings/UserProfileSection.ascx index 9a9f892fd..dc5c93513 100644 --- a/NzbDrone.Web/Views/Settings/UserProfileSection.ascx +++ b/NzbDrone.Web/Views/Settings/UserProfileSection.ascx @@ -1,9 +1,87 @@ <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> +<%@ Import Namespace="NzbDrone.Web.Helpers" %> +<%@ Import Namespace="NzbDrone.Core.Repository.Quality" %> -
- <%= Html.LabelFor(m => m.Name) %> -
-
- <%: Html.TextBoxFor(m => m.Name)%> - <%= Html.ValidationMessageFor(m => m.Name)%> -
\ No newline at end of file +<% using (Html.BeginCollectionItem("UserProfiles")) + { %> + + + + + +
+ +
+ + <%= Html.TextBoxFor(m => m.AllowedString, new { @id = "allowedString", @style = "display:none" })%> + <%--<%= Html.TextBoxFor(m => m.AllowedString, new { @id = "allowedString" })%>--%> + + + + +
+ <%= Html.LabelFor(x => x.Name)%> +
+
+ <%= Html.TextBoxFor(x => x.Name) %> + <%= Html.ValidationMessageFor(x => x.Name)%> +
+ +
+ <%= Html.TextBoxFor(x => x.ProfileId, new { @style = "display:none" })%> + <%= Html.CheckBoxFor(x => x.UserProfile, new { @style = "display:none" })%> +
+ +
+ +
+
    + <%for (int i = 0; i < Model.Allowed.Count(); i++){%> +
  • + <%= Html.DisplayTextFor(c => c.Allowed[i]) %> +
  • + <%}%> +
+
+ +
+
    + <% var qualitiesList = (List) ViewData["Qualities"]; %> + + <%for (int i = 0; i < qualitiesList.Count(); i++){%> + <% + //Skip Unknown and any item that is in the allowed list + if (qualitiesList[i].ToString() == "Unknown") + continue; + if (Model.Allowed.Contains(qualitiesList[i])) + continue; + %> + +
  • + <%= Html.Label(qualitiesList[i].ToString()) %> + <%--<%= Html.RenderPartial("ProfileAllowedQualities", Model.Allowed[i]) %>--%> +
  • + + <% } %> +
+
+
+
+<% } %> \ No newline at end of file diff --git a/NzbDrone.Web/Views/Shared/Site.Master b/NzbDrone.Web/Views/Shared/Site.Master index 1a6749e59..9fdc083f8 100644 --- a/NzbDrone.Web/Views/Shared/Site.Master +++ b/NzbDrone.Web/Views/Shared/Site.Master @@ -58,7 +58,9 @@ .Add("jquery.jgrowl.js") .Add("Notification.js") .Add("jquery-tgc-countdown-1.0.js") - .Add("jquery.simpledropdown.js")) + .Add("jquery.simpledropdown.js") + .Add("MicrosoftAjax.js") + .Add("MicrosoftMvcValidation.js")) .Render(); %>