diff --git a/src/Common/SIPackages/Atom.cs b/src/Common/SIPackages/Atom.cs index bf8393eb..e8b23372 100644 --- a/src/Common/SIPackages/Atom.cs +++ b/src/Common/SIPackages/Atom.cs @@ -1,7 +1,6 @@ using SIPackages.Core; using System.ComponentModel; using System.Diagnostics; -using System.Text; namespace SIPackages; @@ -9,7 +8,7 @@ namespace SIPackages; /// Defines a question scenario minimal item. /// [Obsolete] -internal sealed class Atom : PropertyChangedNotifier, ITyped, IEquatable +internal sealed class Atom { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string _type = AtomTypes.Text; @@ -36,9 +35,7 @@ public string Type { if (_type != value) { - var oldValue = _type; _type = value; - OnPropertyChanged(oldValue); } } } @@ -54,9 +51,7 @@ public int AtomTime { if (_atomTime != value) { - var oldValue = _atomTime; _atomTime = value; - OnPropertyChanged(oldValue); } } } @@ -71,44 +66,8 @@ public string Text { if (_text != value) { - var oldValue = _text; _text = value; - OnPropertyChanged(oldValue); } } } - - /// - /// Does the atom text contain specified value. - /// - /// Text value. - public bool Contains(string value) => _text.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) > -1; - - /// - public override string ToString() - { - if (_type == AtomTypes.Text) - { - return _text; - } - - var res = new StringBuilder(); - res.AppendFormat("#{0} ", _type); - res.Append(_text); - - return res.ToString(); - } - - /// - public bool Equals(Atom? other) => - other is not null - && Type.Equals(other.Type) - && AtomTime.Equals(other.AtomTime) - && Text.Equals(other.Text); - - /// - public override bool Equals(object? obj) => Equals(obj as Atom); - - /// - public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), Type, AtomTime, Text); } diff --git a/src/Common/SIPackages/Core/Enums.cs b/src/Common/SIPackages/Core/Enums.cs index d9382a30..967c6cf9 100644 --- a/src/Common/SIPackages/Core/Enums.cs +++ b/src/Common/SIPackages/Core/Enums.cs @@ -1,52 +1,5 @@ namespace SIPackages.Core; -/// -/// Defines search result source kinds. -/// -public enum ResultKind -{ - /// - /// Object name. - /// - Name, - /// - /// Object author. - /// - Author, - /// - /// Object source. - /// - Source, - /// - /// Object comment. - /// - Comment, - /// - /// Object text. - /// - Text, - /// - /// Right answers. - /// - Right, - /// - /// Wrong answers. - /// - Wrong, - /// - /// Question type name. - /// - TypeName, - /// - /// Question type parameter name. - /// - TypeParamName, - /// - /// Question type parameter value. - /// - TypeParamValue -} - /// /// Defines well-known media types. /// diff --git a/src/Common/SIPackages/Core/LinkExtensions.cs b/src/Common/SIPackages/Core/LinkExtensions.cs index b0bcf6f3..af5aedab 100644 --- a/src/Common/SIPackages/Core/LinkExtensions.cs +++ b/src/Common/SIPackages/Core/LinkExtensions.cs @@ -3,7 +3,7 @@ /// /// Provides helper methods for working with document links. /// -public static class LinkExtensions +internal static class LinkExtensions { /// /// Extracts link from value. diff --git a/src/Common/SIPackages/Core/ListExtensions.cs b/src/Common/SIPackages/Core/ListExtensions.cs index a50c75f6..cacda643 100644 --- a/src/Common/SIPackages/Core/ListExtensions.cs +++ b/src/Common/SIPackages/Core/ListExtensions.cs @@ -29,30 +29,4 @@ public static string ToCommonString(this List list) return text.ToString(); } - - /// - /// Checks if any of list items contains the provided pattern. - /// - /// List to check. - /// Pattern to find. - public static bool ContainsQuery(this List list, string pattern) => - list.Any(item => item.IndexOf(pattern, StringComparison.CurrentCultureIgnoreCase) > -1); - - /// - /// Searches pattern in list values. - /// - /// List to search. - /// Searched pattern. - /// Search result. - public static IEnumerable Search(this List list, string pattern) - { - for (int i = 0; i < list.Count; i++) - { - var index = list[i].IndexOf(pattern, StringComparison.CurrentCultureIgnoreCase); - if (index > -1) - { - yield return new SearchData(list[i], index, i); - } - } - } } diff --git a/src/Common/SIPackages/Core/Named.cs b/src/Common/SIPackages/Core/Named.cs index ba21cafb..71b362b8 100644 --- a/src/Common/SIPackages/Core/Named.cs +++ b/src/Common/SIPackages/Core/Named.cs @@ -34,19 +34,6 @@ public Named() { } /// Object name. public Named(string name) => _name = name; - /// - /// Detects if the object contains the specified value. - /// - /// Text value. - public virtual bool Contains(string value) => _name.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) > -1; - - /// - /// Searches a value inside the object. - /// - /// Value to search. - /// Search results. - public virtual IEnumerable Search(string value) => SearchExtensions.Search(ResultKind.Name, _name, value); - /// public override bool Equals(object? obj) => obj is Named named && Name == named.Name; diff --git a/src/Common/SIPackages/Core/QuestionTypeParams.cs b/src/Common/SIPackages/Core/QuestionTypeParams.cs index 78a5f3b4..b6230ceb 100644 --- a/src/Common/SIPackages/Core/QuestionTypeParams.cs +++ b/src/Common/SIPackages/Core/QuestionTypeParams.cs @@ -3,7 +3,8 @@ /// /// Provides well-known question type parameters. /// -public static class QuestionTypeParams +[Obsolete] +internal static class QuestionTypeParams { /// /// Question special theme. diff --git a/src/Common/SIPackages/Core/QuestionTypes.cs b/src/Common/SIPackages/Core/QuestionTypes.cs index 72db8f9a..dce4ef8a 100644 --- a/src/Common/SIPackages/Core/QuestionTypes.cs +++ b/src/Common/SIPackages/Core/QuestionTypes.cs @@ -19,7 +19,7 @@ public static class QuestionTypes /// Stake question type. /// [Obsolete("Use Stake question type")] - public const string Auction = "auction"; + internal const string Auction = "auction"; /// /// Stake question type. @@ -35,7 +35,7 @@ public static class QuestionTypes /// Secret question type. /// [Obsolete("Use Secret question type")] - public const string Cat = "cat"; + internal const string Cat = "cat"; /// /// Secret question type. @@ -56,13 +56,13 @@ public static class QuestionTypes /// Extended secret question type. /// [Obsolete("Use Secret question type")] - public const string BagCat = "bagcat"; + internal const string BagCat = "bagcat"; /// /// No-risk question. /// [Obsolete("Use NoRisk question type")] - public const string Sponsored = "sponsored"; + internal const string Sponsored = "sponsored"; /// /// No-risk question. diff --git a/src/Common/SIPackages/Helpers/InfoOwnerExtensions.cs b/src/Common/SIPackages/Helpers/InfoOwnerExtensions.cs new file mode 100644 index 00000000..9c86c13c --- /dev/null +++ b/src/Common/SIPackages/Helpers/InfoOwnerExtensions.cs @@ -0,0 +1,32 @@ +namespace SIPackages.Helpers; + +internal static class InfoOwnerExtensions +{ + /// + /// Copies info from source object. + /// + /// Target object. + /// Source object. + internal static void SetInfoFromOwner(this InfoOwner target, InfoOwner infoOwner) + { + foreach (string s in infoOwner.Info.Authors) + { + target.Info.Authors.Add(s); + } + + foreach (string s in infoOwner.Info.Sources) + { + target.Info.Sources.Add(s); + } + + target.Info.Comments.Text = infoOwner.Info.Comments.Text; + + if (infoOwner.Info.ShowmanComments != null) + { + target.Info.ShowmanComments ??= new Comments(); + target.Info.ShowmanComments.Text = infoOwner.Info.ShowmanComments.Text; + } + + target.Info.Extension = infoOwner.Info.Extension; + } +} diff --git a/src/Common/SIPackages/Helpers/PackageExtensions.cs b/src/Common/SIPackages/Helpers/PackageExtensions.cs new file mode 100644 index 00000000..0eb9b99a --- /dev/null +++ b/src/Common/SIPackages/Helpers/PackageExtensions.cs @@ -0,0 +1,25 @@ +namespace SIPackages.Helpers; + +/// +/// Provides package helper methods. +/// +public static class PackageExtensions +{ + /// + /// Creates a new round. + /// + /// Package. + /// Round type. + /// Round name. + public static Round CreateRound(this Package package, string type, string? name) + { + var round = new Round + { + Name = name ?? (package.Rounds.Count + 1).ToString(), + Type = type + }; + + package.Rounds.Add(round); + return round; + } +} diff --git a/src/Common/SIPackages/Helpers/RoundExtensions.cs b/src/Common/SIPackages/Helpers/RoundExtensions.cs new file mode 100644 index 00000000..95cb8289 --- /dev/null +++ b/src/Common/SIPackages/Helpers/RoundExtensions.cs @@ -0,0 +1,19 @@ +namespace SIPackages.Helpers; + +/// +/// Provides extension methods for rounds. +/// +public static class RoundExtensions +{ + /// + /// Creates a new theme. + /// + /// Round. + /// Theme name. + public static Theme CreateTheme(this Round round, string? name) + { + var theme = new Theme { Name = name ?? "" }; + round.Themes.Add(theme); + return theme; + } +} diff --git a/src/Common/SIPackages/Helpers/ThemeExtensions.cs b/src/Common/SIPackages/Helpers/ThemeExtensions.cs new file mode 100644 index 00000000..b1bef7fe --- /dev/null +++ b/src/Common/SIPackages/Helpers/ThemeExtensions.cs @@ -0,0 +1,70 @@ +using SIPackages.Core; + +namespace SIPackages.Helpers; + +/// +/// Provides extension methods for the class. +/// +public static class ThemeExtensions +{ + /// + /// Creates a new question in the theme. + /// + /// Theme. + /// Question price. + /// Does the question belong to the final round. + /// Question text. + public static Question CreateQuestion(this Theme theme, int price = -1, bool isFinal = false, string text = "") + { + int qPrice = DetectQuestionPrice(theme, price, isFinal); + + var quest = new Question + { + Price = qPrice + }; + + quest.Parameters[QuestionParameterNames.Question] = new StepParameter + { + Type = StepParameterTypes.Content, + ContentValue = new List + { + new() { Type = ContentTypes.Text, Value = text }, + } + }; + + quest.Right.Add(""); + theme.Questions.Add(quest); + + return quest; + } + + private static int DetectQuestionPrice(Theme theme, int price, bool isFinal) + { + if (price != -1) + { + return price; + } + + var validQuestions = theme.Questions.Where(q => q.Price != Question.InvalidPrice).ToList(); + + var questionCount = validQuestions.Count; + + if (questionCount > 1) + { + var stepValue = validQuestions[1].Price - validQuestions[0].Price; + return Math.Max(0, validQuestions[questionCount - 1].Price + stepValue); + } + + if (questionCount > 0) + { + return validQuestions[0].Price * 2; + } + + if (isFinal) + { + return 0; + } + + return 100; + } +} diff --git a/src/Common/SIPackages/ZipExtractorExtensions.cs b/src/Common/SIPackages/Helpers/ZipExtractorExtensions.cs similarity index 96% rename from src/Common/SIPackages/ZipExtractorExtensions.cs rename to src/Common/SIPackages/Helpers/ZipExtractorExtensions.cs index 79fbd1c6..ffb0079c 100644 --- a/src/Common/SIPackages/ZipExtractorExtensions.cs +++ b/src/Common/SIPackages/Helpers/ZipExtractorExtensions.cs @@ -1,11 +1,11 @@ using ZipUtils; -namespace SIPackages; +namespace SIPackages.Helpers; /// /// Provides method to extract package to folder. /// -internal static class PackageExtractor +internal static class ZipExtractorExtensions { /// /// Extarcts package to folder. diff --git a/src/Common/SIPackages/InfoOwner.cs b/src/Common/SIPackages/InfoOwner.cs index 3b2501dd..8a295e58 100644 --- a/src/Common/SIPackages/InfoOwner.cs +++ b/src/Common/SIPackages/InfoOwner.cs @@ -3,7 +3,6 @@ using SIPackages.Models; using System.ComponentModel; using System.Xml; -using System.Xml.Schema; namespace SIPackages; @@ -20,75 +19,6 @@ public abstract class InfoOwner : Named [DefaultValue(typeof(Info), "")] public Info Info { get; } = new(); - /// - /// Copies info from source object. - /// - /// Source object. - public void SetInfoFromOwner(InfoOwner infoOwner) - { - foreach (string s in infoOwner.Info.Authors) - { - Info.Authors.Add(s); - } - - foreach (string s in infoOwner.Info.Sources) - { - Info.Sources.Add(s); - } - - Info.Comments.Text = infoOwner.Info.Comments.Text; - - if (infoOwner.Info.ShowmanComments != null) - { - Info.ShowmanComments ??= new Comments(); - Info.ShowmanComments.Text = infoOwner.Info.ShowmanComments.Text; - } - - Info.Extension = infoOwner.Info.Extension; - } - - /// - public override bool Contains(string value) => - base.Contains(value) || - Info.Authors.ContainsQuery(value) || - Info.Sources.ContainsQuery(value) || - Info.Comments.Text.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) > -1 || - Info.ShowmanComments != null && Info.ShowmanComments.Text.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) > -1; - - /// - public override IEnumerable Search(string value) - { - foreach (var item in base.Search(value)) - { - yield return item; - } - - foreach (var item in Info.Authors.Search(value)) - { - item.Kind = ResultKind.Author; - yield return item; - } - - foreach (var item in Info.Sources.Search(value)) - { - item.Kind = ResultKind.Source; - yield return item; - } - - foreach (var item in SearchExtensions.Search(ResultKind.Comment, Info.Comments.Text, value)) - { - yield return item; - } - - if (Info.ShowmanComments != null) - { - foreach (var item in SearchExtensions.Search(ResultKind.Comment, Info.ShowmanComments.Text, value)) - { - yield return item; - } - } - } - /// /// Reads data from XML reader. /// diff --git a/src/Common/SIPackages/Package.cs b/src/Common/SIPackages/Package.cs index cbbad2ba..47468310 100644 --- a/src/Common/SIPackages/Package.cs +++ b/src/Common/SIPackages/Package.cs @@ -3,7 +3,6 @@ using SIPackages.Helpers; using SIPackages.Models; using System.ComponentModel; -using System.Diagnostics; using System.Xml; namespace SIPackages; @@ -23,32 +22,15 @@ public sealed class Package : InfoOwner, IEquatable /// public const double MaximumSupportedVersion = 5.0; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private double _version = DefaultVersion; - /// /// Package version. /// - public double Version { get => _version; set { _version = value; } } - - private string _id = ""; + public double Version { get; set; } = DefaultVersion; /// /// Unique package identifier. /// - public string ID - { - get => _id; - set - { - if (_id != value) - { - var oldValue = _id; - _id = value; - OnPropertyChanged(oldValue); - } - } - } + public string ID { get; set; } = ""; private string _restriction = ""; @@ -229,23 +211,6 @@ public string Language /// public override string ToString() => Name; - /// - /// Creates a new round. - /// - /// Round type. - /// Round name. - public Round CreateRound(string type, string? name) - { - var round = new Round - { - Name = name ?? (Rounds.Count + 1).ToString(), - Type = type - }; - - Rounds.Add(round); - return round; - } - /// public override void ReadXml(XmlReader reader, PackageLimits? limits = null) { @@ -260,12 +225,12 @@ public override void ReadXml(XmlReader reader, PackageLimits? limits = null) throw new UnsupportedPackageVersionException(version, MaximumSupportedVersion); } - _version = version; + Version = version; } if (reader.MoveToAttribute("id")) { - _id = reader.Value; + ID = reader.Value; } if (reader.MoveToAttribute("restriction")) @@ -369,9 +334,9 @@ public override void WriteXml(XmlWriter writer) writer.WriteAttributeString("name", Name); writer.WriteAttributeString("version", Math.Max(DefaultVersion, Version).ToString()); - if (!string.IsNullOrEmpty(_id)) + if (!string.IsNullOrEmpty(ID)) { - writer.WriteAttributeString("id", _id); + writer.WriteAttributeString("id", ID); } if (!string.IsNullOrEmpty(_restriction)) diff --git a/src/Common/SIPackages/Question.cs b/src/Common/SIPackages/Question.cs index c7db866d..1ec8fea9 100644 --- a/src/Common/SIPackages/Question.cs +++ b/src/Common/SIPackages/Question.cs @@ -101,42 +101,6 @@ public override string ToString() => [DefaultValue("")] public override string Name => ""; - /// - public override bool Contains(string value) => - base.Contains(value) || - Parameters != null && Parameters.ContainsQuery(value) || - Right.ContainsQuery(value) || - Wrong.ContainsQuery(value); - - /// - public override IEnumerable Search(string value) - { - foreach (var item in base.Search(value)) - { - yield return item; - } - - if (Parameters != null) - { - foreach (var item in Parameters.Search(value)) - { - yield return item; - } - } - - foreach (var item in Right.Search(value)) - { - item.Kind = ResultKind.Right; - yield return item; - } - - foreach (var item in Wrong.Search(value)) - { - item.Kind = ResultKind.Wrong; - yield return item; - } - } - /// public override void ReadXml(XmlReader reader, PackageLimits? limits = null) { diff --git a/src/Common/SIPackages/QuestionType.cs b/src/Common/SIPackages/QuestionType.cs index d0473da1..10bd63e3 100644 --- a/src/Common/SIPackages/QuestionType.cs +++ b/src/Common/SIPackages/QuestionType.cs @@ -1,5 +1,4 @@ using SIPackages.Core; -using SIPackages.Helpers; using SIPackages.TypeConverters; using System.ComponentModel; using System.Diagnostics; @@ -10,7 +9,8 @@ namespace SIPackages; /// Defines a question type. /// [TypeConverter(typeof(QuestionTypeTypeConverter))] -public sealed class QuestionType : Named, IEquatable +[Obsolete] +internal sealed class QuestionType : Named { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly List _parameters = new(); @@ -51,62 +51,4 @@ public string this[string name] } } } - - /// - public override bool Contains(string value) => - Name.Contains(value) - || _parameters.Any(item => item.Name.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) > -1 - || item.Value.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) > -1); - - /// - public override IEnumerable Search(string value) - { - foreach (var item in SearchExtensions.Search(ResultKind.TypeName, Name, value)) - { - yield return item; - } - - for (int i = 0; i < _parameters.Count; i++) - { - var index = _parameters[i].Name.IndexOf(value, StringComparison.CurrentCultureIgnoreCase); - - if (index > -1) - { - yield return new SearchData(_parameters[i].Name, index, i, ResultKind.TypeParamName); - } - - index = _parameters[i].Value.IndexOf(value, StringComparison.CurrentCultureIgnoreCase); - - if (index > -1) - { - yield return new SearchData(_parameters[i].Value, index, i, ResultKind.TypeParamValue); - } - } - } - - /// - public override string ToString() => $"{Name}({string.Join(", ", _parameters.Select(param => param.ToString()))})"; - - /// - public override bool Equals(object? obj) => obj is QuestionType other && Equals(other); - - /// - public bool Equals(QuestionType? other) => other is not null && base.Equals(other) && Params.SequenceEqual(other.Params); - - /// - public override int GetHashCode() => HashCode.Combine(Name, Params.GetCollectionHashCode()); - - /// - /// Checks that two question types are equal to each other. - /// - /// Left question type. - /// Right question type. - public static bool operator ==(QuestionType? left, QuestionType? right) => Equals(left, right); - - /// - /// Checks that two question types are not equal to each other. - /// - /// Left question type. - /// Right question type. - public static bool operator !=(QuestionType? left, QuestionType? right) => !(left == right); } diff --git a/src/Common/SIPackages/Round.cs b/src/Common/SIPackages/Round.cs index fa07d932..da42a580 100644 --- a/src/Common/SIPackages/Round.cs +++ b/src/Common/SIPackages/Round.cs @@ -34,17 +34,6 @@ public string Type /// public override string ToString() => Name; - /// - /// Создание темы - /// - /// Название темы - public Theme CreateTheme(string? name) - { - var theme = new Theme { Name = name ?? "" }; - Themes.Add(theme); - return theme; - } - /// public override void ReadXml(XmlReader reader, PackageLimits? limits = null) { diff --git a/src/Common/SIPackages/SIDocument.cs b/src/Common/SIPackages/SIDocument.cs index 637c903d..3a9fdd40 100644 --- a/src/Common/SIPackages/SIDocument.cs +++ b/src/Common/SIPackages/SIDocument.cs @@ -1,6 +1,7 @@ using EnsureThat; using SIPackages.Containers; using SIPackages.Core; +using SIPackages.Helpers; using SIPackages.Models; using System.Diagnostics; using System.Xml; @@ -216,7 +217,7 @@ public static async Task ExtractToFolderAndLoadAsync( long maxAllowedDataLength = long.MaxValue, CancellationToken cancellationToken = default) { - var extractionMap = await PackageExtractor.ExtractPackageToFolderAsync( + var extractionMap = await ZipExtractorExtensions.ExtractPackageToFolderAsync( sourceFile, folder, maxAllowedDataLength, diff --git a/src/Common/SIPackages/Scenario.cs b/src/Common/SIPackages/Scenario.cs index 4134bab7..4fcdee0b 100644 --- a/src/Common/SIPackages/Scenario.cs +++ b/src/Common/SIPackages/Scenario.cs @@ -1,54 +1,8 @@ -using SIPackages.Core; -using SIPackages.Helpers; - -namespace SIPackages; +namespace SIPackages; /// /// Defines a question scenario. /// /// -internal sealed class Scenario : List, IEquatable -{ - /// - public override string ToString() => string.Join(Environment.NewLine, this.Select(atom => atom.ToString()).ToArray()); - - /// - /// Does the atom text contain specified value. - /// - /// Text value. - public bool ContainsQuery(string value) => this.Any(item => item.Contains(value)); - - /// - /// Adds new atom to this scenario. - /// - /// Atom type. - /// Atom value. - /// Atom time. - public Atom Add(string type, string text, int time = 0) - { - var atom = new Atom - { - Type = type, - Text = text, - AtomTime = time - }; - - Add(atom); - return atom; - } - - /// - /// Adds new text atom to this scenario. - /// - /// Atom text. - public Atom Add(string text) => Add(AtomTypes.Text, text); - - /// - public bool Equals(Scenario? other) => other is not null && this.SequenceEqual(other); - - /// - public override bool Equals(object? obj) => Equals(obj as Scenario); - - /// - public override int GetHashCode() => this.GetCollectionHashCode(); -} +[Obsolete] +internal sealed class Scenario : List { } diff --git a/src/Common/SIPackages/SearchExtensions.cs b/src/Common/SIPackages/SearchExtensions.cs deleted file mode 100644 index 98123982..00000000 --- a/src/Common/SIPackages/SearchExtensions.cs +++ /dev/null @@ -1,50 +0,0 @@ -using SIPackages.Core; - -namespace SIPackages; - -/// -/// Provides search helper methods. -/// -public static class SearchExtensions -{ - /// - /// Searches a value inside the object. - /// - /// Object to search within. - /// Value to search. - /// Search result or null. - public static SearchMatch? SearchFragment(this InfoOwner item, string value) - { - var result = item.Search(value).FirstOrDefault(); - - if (result == null) - { - return null; - } - - var match = result.Item; - var diff = match.Length - result.StartIndex - value.Length; - - return new SearchMatch( - result.StartIndex > 0 ? match[..result.StartIndex] : "", - match.Substring(result.StartIndex, value.Length), - diff > 0 ? match.Substring(result.StartIndex + value.Length, diff) : ""); - } - - internal static IEnumerable Search(ResultKind kind, string str, string text) - { - if (str == null) - { - yield break; - } - - var index = str.IndexOf(text, StringComparison.CurrentCultureIgnoreCase); - - if (index == -1) - { - yield break; - } - - yield return new SearchData(str, index, kind); - } -} diff --git a/src/Common/SIPackages/StepParameter.cs b/src/Common/SIPackages/StepParameter.cs index 03443917..d5a4298d 100644 --- a/src/Common/SIPackages/StepParameter.cs +++ b/src/Common/SIPackages/StepParameter.cs @@ -141,75 +141,6 @@ public bool IsRef } } - /// - /// Does parameter contain specified value. - /// - /// Text value. - public bool ContainsQuery(string value) => _type switch - { - StepParameterTypes.Content => _contentValue != null && _contentValue.Any(item => item.Value.Contains(value)), - StepParameterTypes.Group => _groupValue != null && _groupValue.ContainsQuery(value), - StepParameterTypes.NumberSet => _numberSetValue != null && _numberSetValue.ToString().Contains(value), - _ => _simpleValue.Contains(value), - }; - - /// - /// Searches a value inside the object. - /// - /// Value to search. - /// Search results. - public IEnumerable Search(string value) - { - switch (_type) - { - case StepParameterTypes.Content: - if (_contentValue == null) - { - break; - } - - foreach (var item in _contentValue) - { - foreach (var searchResult in SearchExtensions.Search(ResultKind.Text, item.Value, value)) - { - yield return searchResult; - } - } - break; - - case StepParameterTypes.Group: - if (_groupValue == null) - { - break; - } - - foreach (var searchResult in _groupValue.Search(value)) - { - yield return searchResult; - } - break; - - case StepParameterTypes.NumberSet: - if (_numberSetValue == null) - { - break; - } - - foreach (var searchResult in SearchExtensions.Search(ResultKind.Text, _numberSetValue.ToString(), value)) - { - yield return searchResult; - } - break; - - default: - foreach (var searchResult in SearchExtensions.Search(ResultKind.Text, _simpleValue, value)) - { - yield return searchResult; - } - break; - } - } - /// public override string ToString() { diff --git a/src/Common/SIPackages/StepParameters.cs b/src/Common/SIPackages/StepParameters.cs index 2b342431..a08f846b 100644 --- a/src/Common/SIPackages/StepParameters.cs +++ b/src/Common/SIPackages/StepParameters.cs @@ -1,5 +1,4 @@ -using SIPackages.Core; -using SIPackages.Helpers; +using SIPackages.Helpers; using SIPackages.Models; using System.Xml; @@ -10,28 +9,6 @@ namespace SIPackages; /// public sealed class StepParameters : Dictionary, IEquatable { - /// - /// Does any of parameters contain specified value. - /// - /// Text value. - public bool ContainsQuery(string value) => Values.Any(parameter => parameter.ContainsQuery(value)); - - /// - /// Searches a value inside the object. - /// - /// Value to search. - /// Search results. - public IEnumerable Search(string value) - { - foreach (var parameter in Values) - { - foreach (var item in parameter.Search(value)) - { - yield return item; - } - } - } - /// public bool Equals(StepParameters? other) => other is not null && this.SequenceEqual(other); diff --git a/src/Common/SIPackages/Theme.cs b/src/Common/SIPackages/Theme.cs index 2d84296a..966717db 100644 --- a/src/Common/SIPackages/Theme.cs +++ b/src/Common/SIPackages/Theme.cs @@ -1,5 +1,4 @@ -using SIPackages.Core; -using SIPackages.Helpers; +using SIPackages.Helpers; using SIPackages.Models; using System.Xml; @@ -18,66 +17,6 @@ public sealed class Theme : InfoOwner, IEquatable /// public override string ToString() => Name; - /// - /// Creates a new question in the theme. - /// - /// Question price. - /// Does the question belong to the final round. - /// Question text. - public Question CreateQuestion(int price = -1, bool isFinal = false, string text = "") - { - int qPrice = DetectQuestionPrice(price, isFinal); - - var quest = new Question - { - Price = qPrice - }; - - quest.Parameters[QuestionParameterNames.Question] = new StepParameter - { - Type = StepParameterTypes.Content, - ContentValue = new List - { - new() { Type = ContentTypes.Text, Value = text }, - } - }; - - quest.Right.Add(""); - Questions.Add(quest); - - return quest; - } - - private int DetectQuestionPrice(int price, bool isFinal) - { - if (price != -1) - { - return price; - } - - var validQuestions = Questions.Where(q => q.Price != Question.InvalidPrice).ToList(); - - var questionCount = validQuestions.Count; - - if (questionCount > 1) - { - var stepValue = validQuestions[1].Price - validQuestions[0].Price; - return Math.Max(0, validQuestions[questionCount - 1].Price + stepValue); - } - - if (questionCount > 0) - { - return validQuestions[0].Price * 2; - } - - if (isFinal) - { - return 0; - } - - return 100; - } - /// public override void ReadXml(XmlReader reader, PackageLimits? limits = null) { diff --git a/src/SIQuester/QTxtConverter/QConverter.cs b/src/SIQuester/QTxtConverter/QConverter.cs index 13847030..b8805670 100644 --- a/src/SIQuester/QTxtConverter/QConverter.cs +++ b/src/SIQuester/QTxtConverter/QConverter.cs @@ -5,6 +5,7 @@ using QTxtConverter.Properties; using SIPackages; using SIPackages.Core; +using SIPackages.Helpers; using Spard.Data; using Spard.Exceptions; using System.Diagnostics; diff --git a/src/SIQuester/SIQuester.ViewModel/AnswersViewModel.cs b/src/SIQuester/SIQuester.ViewModel/AnswersViewModel.cs index bc0fdfde..f44e45f6 100644 --- a/src/SIQuester/SIQuester.ViewModel/AnswersViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/AnswersViewModel.cs @@ -59,13 +59,6 @@ public AnswersViewModel(QuestionViewModel owner, IEnumerable collection, UpdateCommands(); UpdateAnswersCommands(); - UpdateQualityCommands(); - } - - public void UpdateQualityCommands() - { - var package = Owner.OwnerTheme?.OwnerRound?.OwnerPackage; - LinkUri.CanBeExecuted = package != null && !package.HasQualityControl; } protected override void OnCurrentItemChanged(string? oldValue, string? newValue) diff --git a/src/SIQuester/SIQuester.ViewModel/ContentItemViewModel.cs b/src/SIQuester/SIQuester.ViewModel/ContentItemViewModel.cs index 530ae24d..f5a0075e 100644 --- a/src/SIQuester/SIQuester.ViewModel/ContentItemViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/ContentItemViewModel.cs @@ -1,5 +1,5 @@ using SIPackages; -using SIPackages.Core; +using SIQuester.ViewModel.Contracts; namespace SIQuester.ViewModel; diff --git a/src/SIQuester/SIQuester.ViewModel/ContentItemsViewModel.cs b/src/SIQuester/SIQuester.ViewModel/ContentItemsViewModel.cs index b189d4b9..f5be1180 100644 --- a/src/SIQuester/SIQuester.ViewModel/ContentItemsViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/ContentItemsViewModel.cs @@ -84,14 +84,6 @@ public ContentItemsViewModel(QuestionViewModel question, List conte LinkUri = new SimpleCommand(LinkUri_Executed); AddFile = new SimpleCommand(AddFile_Executed); IsTopLevel = isTopLevel; - - UpdateQualityCommands(); - } - - public void UpdateQualityCommands() - { - var package = Owner.OwnerTheme?.OwnerRound?.OwnerPackage; - LinkUri.CanBeExecuted = package != null && !package.HasQualityControl; } internal void AddScreenText_Executed(object? arg) => QDocument.ActivatedObject = Add(ContentTypes.Text, "", ContentPlacements.Screen); diff --git a/src/Common/SIPackages/Core/IMedia.cs b/src/SIQuester/SIQuester.ViewModel/Contracts/IMedia.cs similarity index 85% rename from src/Common/SIPackages/Core/IMedia.cs rename to src/SIQuester/SIQuester.ViewModel/Contracts/IMedia.cs index 68000319..34fc9697 100644 --- a/src/Common/SIPackages/Core/IMedia.cs +++ b/src/SIQuester/SIQuester.ViewModel/Contracts/IMedia.cs @@ -1,4 +1,6 @@ -namespace SIPackages.Core; +using SIPackages.Core; + +namespace SIQuester.ViewModel.Contracts; /// /// Defines a package media object. diff --git a/src/SIQuester/SIQuester.ViewModel/Contracts/IMediaOwner.cs b/src/SIQuester/SIQuester.ViewModel/Contracts/IMediaOwner.cs index 400dd050..238f4322 100644 --- a/src/SIQuester/SIQuester.ViewModel/Contracts/IMediaOwner.cs +++ b/src/SIQuester/SIQuester.ViewModel/Contracts/IMediaOwner.cs @@ -1,6 +1,4 @@ -using SIPackages.Core; - -namespace SIQuester.ViewModel.Contracts; +namespace SIQuester.ViewModel.Contracts; /// /// Defines an object which could provide access to some media data. diff --git a/src/SIQuester/SIQuester.ViewModel/Helpers/ContainsExtensions.cs b/src/SIQuester/SIQuester.ViewModel/Helpers/ContainsExtensions.cs new file mode 100644 index 00000000..4fb8c4d0 --- /dev/null +++ b/src/SIQuester/SIQuester.ViewModel/Helpers/ContainsExtensions.cs @@ -0,0 +1,54 @@ +using SIPackages; +using SIPackages.Core; + +namespace SIQuester.ViewModel.Helpers; + +internal static class ContainsExtensions +{ + /// + /// Detects if the object contains the specified value. + /// + /// Text value. + public static bool ContainsNamed(this Named named, string value) => named.Name.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) > -1; + + /// + public static bool ContainsInfoOwner(this InfoOwner infoOwner, string value) => + ContainsNamed(infoOwner, value) || + infoOwner.Info.Authors.ContainsQuery(value) || + infoOwner.Info.Sources.ContainsQuery(value) || + infoOwner.Info.Comments.Text.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) > -1 || + infoOwner.Info.ShowmanComments != null && infoOwner.Info.ShowmanComments.Text.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) > -1; + + /// + /// Checks if any of list items contains the provided pattern. + /// + /// List to check. + /// Pattern to find. + public static bool ContainsQuery(this List list, string pattern) => + list.Any(item => item.IndexOf(pattern, StringComparison.CurrentCultureIgnoreCase) > -1); + + /// + public static bool Contains(this Question question, string value) => + ContainsInfoOwner(question, value) || + question.Parameters.ContainsQuery(value) || + question.Right.ContainsQuery(value) || + question.Wrong.ContainsQuery(value); + + /// + /// Does any of parameters contain specified value. + /// + /// Text value. + public static bool ContainsQuery(this StepParameters stepParameters, string value) => stepParameters.Values.Any(parameter => parameter.ContainsQuery(value)); + + /// + /// Does parameter contain specified value. + /// + /// Text value. + public static bool ContainsQuery(this StepParameter stepParameter, string value) => stepParameter.Type switch + { + StepParameterTypes.Content => stepParameter.ContentValue != null && stepParameter.ContentValue.Any(item => item.Value.Contains(value)), + StepParameterTypes.Group => stepParameter.GroupValue != null && stepParameter.GroupValue.ContainsQuery(value), + StepParameterTypes.NumberSet => stepParameter.NumberSetValue != null && stepParameter.NumberSetValue.ToString().Contains(value), + _ => stepParameter.SimpleValue.Contains(value), + }; +} diff --git a/src/SIQuester/SIQuester.ViewModel/Helpers/ResultKind.cs b/src/SIQuester/SIQuester.ViewModel/Helpers/ResultKind.cs new file mode 100644 index 00000000..e49fb749 --- /dev/null +++ b/src/SIQuester/SIQuester.ViewModel/Helpers/ResultKind.cs @@ -0,0 +1,48 @@ +namespace SIQuester.ViewModel.Helpers; + +/// +/// Defines search result source kinds. +/// +public enum ResultKind +{ + /// + /// Object name. + /// + Name, + /// + /// Object author. + /// + Author, + /// + /// Object source. + /// + Source, + /// + /// Object comment. + /// + Comment, + /// + /// Object text. + /// + Text, + /// + /// Right answers. + /// + Right, + /// + /// Wrong answers. + /// + Wrong, + /// + /// Question type name. + /// + TypeName, + /// + /// Question type parameter name. + /// + TypeParamName, + /// + /// Question type parameter value. + /// + TypeParamValue +} diff --git a/src/Common/SIPackages/Core/SearchData.cs b/src/SIQuester/SIQuester.ViewModel/Helpers/SearchData.cs similarity index 98% rename from src/Common/SIPackages/Core/SearchData.cs rename to src/SIQuester/SIQuester.ViewModel/Helpers/SearchData.cs index 753b947a..370a6422 100644 --- a/src/Common/SIPackages/Core/SearchData.cs +++ b/src/SIQuester/SIQuester.ViewModel/Helpers/SearchData.cs @@ -1,4 +1,4 @@ -namespace SIPackages.Core; +namespace SIQuester.ViewModel.Helpers; /// /// Defines a search result data. diff --git a/src/SIQuester/SIQuester.ViewModel/Helpers/SearchExtensions.cs b/src/SIQuester/SIQuester.ViewModel/Helpers/SearchExtensions.cs new file mode 100644 index 00000000..c1a41093 --- /dev/null +++ b/src/SIQuester/SIQuester.ViewModel/Helpers/SearchExtensions.cs @@ -0,0 +1,207 @@ +using SIPackages; +using SIPackages.Core; + +namespace SIQuester.ViewModel.Helpers; + +/// +/// Provides search helper methods. +/// +public static class SearchExtensions +{ + public static IEnumerable SearchQuestion(this Question question, string value) + { + foreach (var item in SearchInfoOwner(question, value)) + { + yield return item; + } + + foreach (var item in question.Parameters.SearchParameters(value)) + { + yield return item; + } + + foreach (var item in question.Right.SearchList(value)) + { + item.Kind = ResultKind.Right; + yield return item; + } + + foreach (var item in question.Wrong.SearchList(value)) + { + item.Kind = ResultKind.Wrong; + yield return item; + } + } + + /// + /// Searches a value inside the object. + /// + /// Value to search. + /// Search results. + public static IEnumerable SearchParameters(this StepParameters stepParameters, string value) + { + foreach (var parameter in stepParameters.Values) + { + foreach (var item in parameter.SearchParameter(value)) + { + yield return item; + } + } + } + + /// + /// Searches a value inside the object. + /// + /// Value to search. + /// Search results. + public static IEnumerable SearchParameter(this StepParameter stepParameter, string value) + { + switch (stepParameter.Type) + { + case StepParameterTypes.Content: + if (stepParameter.ContentValue == null) + { + break; + } + + foreach (var item in stepParameter.ContentValue) + { + foreach (var searchResult in Search(ResultKind.Text, item.Value, value)) + { + yield return searchResult; + } + } + break; + + case StepParameterTypes.Group: + if (stepParameter.GroupValue == null) + { + break; + } + + foreach (var searchResult in stepParameter.GroupValue.SearchParameters(value)) + { + yield return searchResult; + } + break; + + case StepParameterTypes.NumberSet: + if (stepParameter.NumberSetValue == null) + { + break; + } + + foreach (var searchResult in Search(ResultKind.Text, stepParameter.NumberSetValue.ToString(), value)) + { + yield return searchResult; + } + break; + + default: + foreach (var searchResult in Search(ResultKind.Text, stepParameter.SimpleValue, value)) + { + yield return searchResult; + } + break; + } + } + + /// + /// Searches a value inside the object. + /// + /// Object to search within. + /// Value to search. + /// Search result or null. + public static SearchMatch? SearchFragment(this InfoOwner item, string value) + { + var result = item.SearchInfoOwner(value).FirstOrDefault(); + + if (result == null) + { + return null; + } + + var match = result.Item; + var diff = match.Length - result.StartIndex - value.Length; + + return new SearchMatch( + result.StartIndex > 0 ? match[..result.StartIndex] : "", + match.Substring(result.StartIndex, value.Length), + diff > 0 ? match.Substring(result.StartIndex + value.Length, diff) : ""); + } + + public static IEnumerable SearchInfoOwner(this InfoOwner infoOwner, string value) + { + foreach (var item in SearchNamed(infoOwner, value)) + { + yield return item; + } + + foreach (var item in infoOwner.Info.Authors.SearchList(value)) + { + item.Kind = ResultKind.Author; + yield return item; + } + + foreach (var item in infoOwner.Info.Sources.SearchList(value)) + { + item.Kind = ResultKind.Source; + yield return item; + } + + foreach (var item in Search(ResultKind.Comment, infoOwner.Info.Comments.Text, value)) + { + yield return item; + } + + if (infoOwner.Info.ShowmanComments != null) + { + foreach (var item in Search(ResultKind.Comment, infoOwner.Info.ShowmanComments.Text, value)) + { + yield return item; + } + } + } + + /// + /// Searches a value inside the object. + /// + /// Value to search. + /// Search results. + public static IEnumerable SearchNamed(this Named named, string value) => Search(ResultKind.Name, named.Name, value); + + /// + /// Searches pattern in list values. + /// + /// List to search. + /// Searched pattern. + /// Search result. + public static IEnumerable SearchList(this List list, string pattern) + { + for (int i = 0; i < list.Count; i++) + { + var index = list[i].IndexOf(pattern, StringComparison.CurrentCultureIgnoreCase); + if (index > -1) + { + yield return new SearchData(list[i], index, i); + } + } + } + + internal static IEnumerable Search(ResultKind kind, string str, string text) + { + if (str == null) + { + yield break; + } + + var index = str.IndexOf(text, StringComparison.CurrentCultureIgnoreCase); + + if (index == -1) + { + yield break; + } + + yield return new SearchData(str, index, kind); + } +} diff --git a/src/Common/SIPackages/Core/SearchMatch.cs b/src/SIQuester/SIQuester.ViewModel/Helpers/SearchMatch.cs similarity index 95% rename from src/Common/SIPackages/Core/SearchMatch.cs rename to src/SIQuester/SIQuester.ViewModel/Helpers/SearchMatch.cs index 1ac48800..4fb1c26f 100644 --- a/src/Common/SIPackages/Core/SearchMatch.cs +++ b/src/SIQuester/SIQuester.ViewModel/Helpers/SearchMatch.cs @@ -1,4 +1,4 @@ -namespace SIPackages.Core; +namespace SIQuester.ViewModel.Helpers; /// /// Respresent a string containing search result splitted by this result. diff --git a/src/SIQuester/SIQuester.ViewModel/Items/PackageViewModel.cs b/src/SIQuester/SIQuester.ViewModel/Items/PackageViewModel.cs index fadd0d59..deb37dee 100644 --- a/src/SIQuester/SIQuester.ViewModel/Items/PackageViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/Items/PackageViewModel.cs @@ -1,6 +1,7 @@ using SIPackages; using SIPackages.Core; using SIQuester.Model; +using SIQuester.ViewModel.Contracts; using SIQuester.ViewModel.Helpers; using SIQuester.ViewModel.PlatformSpecific; using SIQuester.ViewModel.Properties; @@ -100,35 +101,6 @@ public bool HasQualityControl Document.Document.HasQualityControl = value; OnPropertyChanged(); - UpdateQualityCommands(); - } - } - } - - private void UpdateQualityCommands() - { - foreach (var round in Rounds) - { - foreach (var theme in round.Themes) - { - foreach (var question in theme.Questions) - { - foreach (var parameter in question.Parameters!) - { - parameter.Value.ContentValue?.UpdateQualityCommands(); - - if (parameter.Value.GroupValue != null) - { - foreach (var item in parameter.Value.GroupValue) - { - item.Value.ContentValue?.UpdateQualityCommands(); - } - } - } - - question.Right.UpdateQualityCommands(); - question.Wrong.UpdateQualityCommands(); - } } } } diff --git a/src/SIQuester/SIQuester.ViewModel/MediaItemViewModel.cs b/src/SIQuester/SIQuester.ViewModel/MediaItemViewModel.cs index 3e4ab0a0..ca9d0f0f 100644 --- a/src/SIQuester/SIQuester.ViewModel/MediaItemViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/MediaItemViewModel.cs @@ -1,4 +1,5 @@ using SIPackages.Core; +using SIQuester.ViewModel.Contracts; namespace SIQuester.ViewModel; diff --git a/src/SIQuester/SIQuester.ViewModel/MediaOwnerViewModel.cs b/src/SIQuester/SIQuester.ViewModel/MediaOwnerViewModel.cs index 86332d94..2a8cb2aa 100644 --- a/src/SIQuester/SIQuester.ViewModel/MediaOwnerViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/MediaOwnerViewModel.cs @@ -1,5 +1,4 @@ using SIPackages; -using SIPackages.Core; using SIQuester.Model; using SIQuester.ViewModel.Contracts; using SIQuester.ViewModel.Properties; diff --git a/src/Common/SIPackages/Core/Media.cs b/src/SIQuester/SIQuester.ViewModel/Model/Media.cs similarity index 92% rename from src/Common/SIPackages/Core/Media.cs rename to src/SIQuester/SIQuester.ViewModel/Model/Media.cs index a209693a..97b4ab1d 100644 --- a/src/Common/SIPackages/Core/Media.cs +++ b/src/SIQuester/SIQuester.ViewModel/Model/Media.cs @@ -1,4 +1,7 @@ -namespace SIPackages.Core; +using SIPackages.Core; +using SIQuester.ViewModel.Contracts; + +namespace SIQuester.ViewModel.Model; /// public sealed class Media : IMedia diff --git a/src/SIQuester/SIQuester.ViewModel/Model/SearchResult.cs b/src/SIQuester/SIQuester.ViewModel/Model/SearchResult.cs index 7a2d1e41..86ad2687 100644 --- a/src/SIQuester/SIQuester.ViewModel/Model/SearchResult.cs +++ b/src/SIQuester/SIQuester.ViewModel/Model/SearchResult.cs @@ -1,4 +1,4 @@ -using SIPackages.Core; +using SIQuester.ViewModel.Helpers; namespace SIQuester.Model; diff --git a/src/SIQuester/SIQuester.ViewModel/PlatformSpecific/PlatformManager.cs b/src/SIQuester/SIQuester.ViewModel/PlatformSpecific/PlatformManager.cs index 6a49ee9e..24c6ae25 100644 --- a/src/SIQuester/SIQuester.ViewModel/PlatformSpecific/PlatformManager.cs +++ b/src/SIQuester/SIQuester.ViewModel/PlatformSpecific/PlatformManager.cs @@ -1,6 +1,6 @@ using SIPackages; -using SIPackages.Core; using SIQuester.Model; +using SIQuester.ViewModel.Contracts; using SIQuester.ViewModel.Model; using System.Diagnostics.CodeAnalysis; using System.Text; diff --git a/src/SIQuester/SIQuester.ViewModel/Properties/Resources.Designer.cs b/src/SIQuester/SIQuester.ViewModel/Properties/Resources.Designer.cs index b91520b7..26422133 100644 --- a/src/SIQuester/SIQuester.ViewModel/Properties/Resources.Designer.cs +++ b/src/SIQuester/SIQuester.ViewModel/Properties/Resources.Designer.cs @@ -1579,24 +1579,6 @@ public static string Success { } } - /// - /// Ищет локализованную строку, похожую на Super Secret question. - /// - public static string SuperSecretQuestion { - get { - return ResourceManager.GetString("SuperSecretQuestion", resourceCulture); - } - } - - /// - /// Ищет локализованную строку, похожую на Television analog of SIGame. - /// - public static string TeleSI { - get { - return ResourceManager.GetString("TeleSI", resourceCulture); - } - } - /// /// Ищет локализованную строку, похожую на Template name. /// @@ -1678,28 +1660,6 @@ public static string ToBase { } } - /// - /// Ищет локализованную строку, похожую на Export to IRC. - /// - public static string ToIRC { - get { - return ResourceManager.GetString("ToIRC", resourceCulture); - } - } - - /// - /// Ищет локализованную строку, похожую на This file is created for playing 'svoyak' in the IRC chat. Please do not manually edit anything in it, as this may lead to unpleasant consequences during the game. - ///For the script to work, you need the sportsi.ini files (the script itself), ssi-load.cmd (script loading), and ssi-restore.cmd (script unloading). They must be placed in the folder of your IRC client. To start the game, load the script with the command - ////play -c ssi-load.cmd - ///Then you can get all the help by pressing the F2 key. - ///After completin [остаток строки не уместился]";. - /// - public static string ToIRCtext { - get { - return ResourceManager.GetString("ToIRCtext", resourceCulture); - } - } - /// /// Ищет локализованную строку, похожую на Total themes imported:. /// diff --git a/src/SIQuester/SIQuester.ViewModel/Properties/Resources.resx b/src/SIQuester/SIQuester.ViewModel/Properties/Resources.resx index 024169e4..c2afdea1 100644 --- a/src/SIQuester/SIQuester.ViewModel/Properties/Resources.resx +++ b/src/SIQuester/SIQuester.ViewModel/Properties/Resources.resx @@ -640,12 +640,6 @@ Humor The input file has been completely read! The entire file header is placed in the package comments. Please sort its content yourself. Total imported themes: - - Super Secret question - - - Television analog of SIGame - Template name @@ -673,34 +667,6 @@ Humor Export to Question Base - - Export to IRC - - - This file is created for playing 'svoyak' in the IRC chat. Please do not manually edit anything in it, as this may lead to unpleasant consequences during the game. -For the script to work, you need the sportsi.ini files (the script itself), ssi-load.cmd (script loading), and ssi-restore.cmd (script unloading). They must be placed in the folder of your IRC client. To start the game, load the script with the command -/play -c ssi-load.cmd -Then you can get all the help by pressing the F2 key. -After completing the game, you can unload the script with the command -/play -c ssi-restore.cmd -Notations in the file: -p - package -r - round -t - topic -q - question -(then the number) -name - name -price - question price -type - type (for round and question) -auth - authors -sour - sources -comm - comments -text - question text -right - correct answers -wrong - incorrect answers -cost - Cat's price -theme - Cat's theme - Total themes imported: diff --git a/src/SIQuester/SIQuester.ViewModel/Properties/Resources.ru-RU.resx b/src/SIQuester/SIQuester.ViewModel/Properties/Resources.ru-RU.resx index fb10a538..1fae4d9b 100644 --- a/src/SIQuester/SIQuester.ViewModel/Properties/Resources.ru-RU.resx +++ b/src/SIQuester/SIQuester.ViewModel/Properties/Resources.ru-RU.resx @@ -123,12 +123,33 @@ Зачёт + + Добавить вопрос + + + Добавить раунд + + + Добавить тему + + + и + Ответ + + Аудио + + + Аудио файл {0} не указан как фоновый + Автор + + Авторы + https://vk.com/si_game @@ -138,24 +159,88 @@ Источник + + Не удалось создать временный файл. Попробуйте отключить антивирус + + + Невозможно включить контроль качества из-за ошибок: + Чемпионат changeGroup уже активирована! + + Закрыть + Комментарий Комментарии + + Общие знания + + + Основные + + + Вы действительно хотите удалить все неиспользуемые в пакете медиафайлы + + + Ошибка конвертации + + + База вопросов + + + Пакет хранится в Базе {0} под именем {1} + + + Автомобили +Алфавит +Аниме +Астрономия +Биология +География +Игры: Консоли, Саундтреки, Настольные игры +Искусство +История +Кино: Режиссёры, Актёры, Премии +Книги: Комиксы +Мемы +Математика +Музыка: Рок, Поп, Рэп, Джаз, Металл, Электроника, Каверы, Русская музыка, Классическая музыка +Мультфильмы +Ребусы +Комиксы +Сериалы +Смешанная (солянка) +Спорт: Футбол +ТВ +Фантастика +Физика +Химия +Эрудиция: ЧГК, Политика, Личности +Юмор + Загрузка документа + + Ошибка сохранения документа + + + Документы DOCX + Пакет {0} был изменён. Вы хотите сохранить его? + + Редакторы + Без имени @@ -165,22 +250,67 @@ Стоп - - {0}-й раунд - В следующей теме обнаружена ошибка нумерации. Ожидается, что текст всех вопросов в каждой теме начинается с номера, последовательно возрастающего от вопроса к вопросу. УБЕДИТЕСЬ, что в тексте нет номеров в начале строки помимо стоимостей вопросов. При необходимости удалите, перенесите или пропустите их + + Попытка вставить привязанный вопрос! + + + Экспорт + + + экспорт и печать + + + Экспорт медиа + + + Ошибка экспорта медиа + + + Экспорт в формат таблицы + + + экспорт в HTML + + + Вопросы "SIGame" + Экспорт в формат СНС + + Внешние ссылки не допускаются + Недостаточное число вопросов + + (файл…) + + + Файл {0} содержится в пакете в разных категориях! + + + Файл {0} содержится в пакете дважды! + Файл доступен только для чтения! + + Ошибка открытия файла + + + Загружено файлов: {0} + + + Поиск файлов + + + Размер файла превышает допустимое значение для игры через Игровой сервер ({0} МБ)! + ФИНАЛ @@ -196,30 +326,90 @@ ИГРА {0} + + Размер файла превышает 100 Мб! + Обнаружены обновления программы от {0}. Загрузить их сейчас? + + Как использовать программу + + + HTML + + + Файлы HTML + + + Изображение + + + Изображения + В столбец + + Инфо + + + Введите адрес мультимедиа-объекта + Произошла ошибка + + Расширение файла {0} ({1}) недопустимо. Допустимые расширения: {2} + + + Размер файла {0} превышает допустимое значение {1} МБ + ОСТАТОК + + (ссылка…) + SIQuester Сохранить необработанную часть файла в: + + Расширение мультимедиа файла не относится к рекомендуемым ({0})! + + + Размер мультимедиа файла превышает рекомендуемое значение ({0} МБ)! + + + звук + + + изображение + + + видео + + + отсутствует файл + + + Отсутствует ссылка + + + Логотип пакета: отсутствует файл {0}! + Имя: Перевод строки + + Новый пакет + Нет @@ -241,6 +431,9 @@ Во входном файле не обнаружены вопросы! Учтите, что вопросы должны иметь стоимость, кратную 10, и каждый вопрос должен начинаться с новой строки. + + Вопрос без риска + Отсутствует источник @@ -250,6 +443,9 @@ Просьба ВНИМАТЕЛЬНО ознакомиться с предложенным форматом. Учтите, что ошибки при прочтении файла могут возникать даже из-за отсутствия символа перевода строки или пробела + + Номер + Число вопросов @@ -259,253 +455,128 @@ Число тем + + Объект создан в новом формате и не может быть присоединён к данному пакету + Следующий объект не обнаружен: {0} - - Входной текст не соответствует нижеприведённому шаблону. Пожалуйста, поправьте шаблон, после чего анализ входного файла продолжится. Кроме того, вы всего-навсего можете поправить входной текст. Проблема: - - - SIQuester + + тем - - Ответ на вопрос + + Открыть папку автосохранений - - Текст вопроса + + Открыть папку с логами - - Вопрос + + Настройки - - ОСТАТОК + + Другой - - Правильный ответ + + Пакет - - Раунд + + Такой же пакет, как и в Телевизионном аналоге SIGame - - Оригинальный файл был изменён. Сохранить его? + + Стандартный пакет для SIGame - - Обычный + + Файл с вопросами повреждён! Попробуйте извлечь данные из него при помощи архиватора (открыв его как архив) - - Нераспознанный кусок текста будет добавлен в комментарии к теме + + или получить данные из автосохранения - - Нераспознанный кусок текста будет добавлен в комментарии к пакету + + Если не получится, отправьте автору программы логи, чтобы можно было избежать проблемы в будущем - - Источник + + Пакет, изначально ничего не содержащий - - В оригинальном тексте чтение закончилось там, где заканчивается подсветка текста. + + Пустой пакет - - Пробел + + Пакет создан в новом формате и не может быть присоединён к данному - - Старт + + в настоящий момент на сервере нет места для принятия новых пакетов - - Входной файл считан полностью! Весь заголовок файла помещён в комментарии к пакету. Просьба самостоятельно рассортировать его содержимое. Всего импортировано тем: + + Пакет, содержащий какое-то иное число раундов, тем или вопросов, чем в стандартной SIGame - - Телевизионный аналог SIGame + + Нестандартный пакет - - Тема + + Просто набор тем - + Коллекция тем - - Экспорт в Базу Вопросов - - - Экспорт в IRC - - - Этот файл создан для игр в свояк в IRC-чате. Убедительная просьба ничего в нём руками не править, ибо это может привести к неприятным последствиям во время игры. -Для работы скрипта вам необходимы файлы sportsi.ini (сам скрипт), ssi-load.cmd (загрузка скрипта) и ssi-restore.cmd (выгрузка скрипта). Они должны быть помещены в папку вашего IRC-клиента. Для начала игры загрузите скрипт командой -/play -c ssi-load.cmd -Далее всю помощь вы можете получить по нажатию клавиши F2. -По завершению игры вы можете выгрузить скрипт командой -/play -c ssi-restore.cmd - -Обозначения в файле: -p - пакет -r - раунд -t - тема -q - вопрос -(далее номер) -name - имя -price - цена у вопроса -type - тип (у раунда и вопроса) -auth - авторы -sour - источники -comm - комментарии -text - текст вопроса -right - правильные ответы -wrong - неправильные ответы -cost - цена Кота -theme - тема Кота - - - Всего импортировано тем: - - - Тур - - - Трансформация - - - Не распознано: - - - Ошибка отмены операции. Обратитесь к разработчику. - - - Не подошедший шаблон - - - Имеется нераспознанный текст - - - Некорректная расстановка скобок - - - Ваши темы: - - - База вопросов - - - Пакет хранится в Базе {0} под именем {1} - - - Редакторы - - - (файл…) - - - Вопрос без риска - - - Другой - - - Вопрос с секретом - - - Простой - - - Библиотека вопросов SIGame - - - Вопрос со ставкой - - - Супервопрос с секретом - - - Попытка вставить привязанный вопрос! - - - Экспорт медиа - - - Ошибка экспорта медиа - - - Введите адрес мультимедиа-объекта - - - Обнаружены файлы, которые не были корректно сохранены при последней работе с программой. Восстановить их? - - - Ошибка сохранения документа + + Входной текст не соответствует нижеприведённому шаблону. Пожалуйста, поправьте шаблон, после чего анализ входного файла продолжится. Кроме того, вы всего-навсего можете поправить входной текст. Проблема: - - Вопросы СИ + + Играно - - Размер файла превышает допустимое значение для игры через Игровой сервер ({0} МБ)! + + SIQuester - - Как использовать программу + + Ответ на вопрос - - Добавить вопрос + + Текст вопроса - - Добавить раунд + + Вопрос - - Добавить тему + + Вопрос для всех Проигрывание вопроса - - Неподдерживаемый фрагмент: {0} - - - Поиск файлов - - - Расширение мультимедиа файла не относится к рекомендуемым ({0})! - - - Размер мультимедиа файла превышает рекомендуемое значение ({0} МБ)! - - - YAML файлы - - - Файлы вопросов (*.txt) | *.txt - - - Файлы вопросов (*.xml) | *.xml + + Вы действительно хотите удалить шаблон "{0}"? - - YAML файлы (*.yaml) | *.yaml + + ОСТАТОК - - Импорт текста + + Обнаружены файлы, которые не были корректно сохранены при последней работе с программой. Восстановить их? - - Безымянный + + Ограничение - - Ошибка при поиске вопросов + + Правильный ответ - - Статистика + + Раунд - - Изображения + + {0}-й раунд - - экспорт и печать + + Документы RTF - - Размер файла превышает 100 Мб! + + Оригинальный файл был изменён. Сохранить его? - - Новый пакет + + Вопрос с секретом без вопроса - - Настройки + + Вопрос с секретом и объявленной стоимостью - - в настоящий момент на сервере нет места для принятия новых пакетов + + Вопрос с секретом Не удалось отправить пакет @@ -516,116 +587,59 @@ theme - тема Кота Отправка пакета в компьютерную игру + + Разделитель + Вопросы SIGame - - выбор тем - - - и - - - Ошибка конвертации - - - Вопрос с секретом без вопроса - - - Вопрос с секретом и объявленной стоимостью - - - Вопрос со ставкой для всех - - - Ошибка открытия файла - - - Закрыть - - - Открыть папку автосохранений - - - Открыть папку с логами - - - Файл с вопросами повреждён! Попробуйте извлечь данные из него при помощи архиватора (открыв его как архив) - - - или получить данные из автосохранения - - - Если не получится, отправьте автору программы логи, чтобы можно было избежать проблемы в будущем - - - Файл {0} содержится в пакете в разных категориях! - - - Файл {0} содержится в пакете дважды! - - - Логотип пакета: отсутствует файл {0}! - - - Внешние ссылки не допускаются - - - отсутствует файл - - - Файл {0} не используется. Удалите его - - - Вы действительно хотите удалить все неиспользуемые в пакете медиафайлы + + Обычный - - Документы DOCX + + Простой - - Экспорт + + Вопросы СИ - - Файлы HTML + + Библиотека вопросов SIGame - - Документы RTF + + Нераспознанный кусок текста будет добавлен в комментарии к теме - - Текстовые файлы + + Нераспознанный кусок текста будет добавлен в комментарии к пакету - - Документы XPS + + Источник - - Авторы + + В оригинальном тексте чтение закончилось там, где заканчивается подсветка текста. Источники - - Такой же пакет, как и в Телевизионном аналоге SIGame - - - Стандартный пакет для SIGame + + Пробел - - Пакет, изначально ничего не содержащий + + Ошибка при поиске вопросов - - Пустой пакет + + Вопрос со ставкой для всех - - Пакет, содержащий какое-то иное число раундов, тем или вопросов, чем в стандартной SIGame + + Вопрос со ставкой - - Нестандартный пакет + + Старт - - Просто набор тем + + Статистика - - Коллекция тем + + Входной файл считан полностью! Весь заголовок файла помещён в комментарии к пакету. Просьба самостоятельно рассортировать его содержимое. Всего импортировано тем: Имя шаблона @@ -633,137 +647,88 @@ theme - тема Кота Шаблон с таким именем уже существует! - - Вы действительно хотите удалить шаблон "{0}"? - - - (ссылка…) + + Текстовые файлы - - экспорт в HTML + + Импорт текста - - Вопросы "SIGame" + + Тема - - Экспорт в формат таблицы + + Коллекция тем - - звук + + выбор тем - - изображение + + Думайте! - - видео + + Экспорт в Базу Вопросов - - Ограничение + + Всего импортировано тем: - - Номер + + Тур - - Разделитель + + Трансформация Мусор - - тем - - - Инфо + + Файлы вопросов (*.txt) | *.txt - - Играно + + Не распознано: - - Аудио файл {0} не указан как фоновый + + Ошибка отмены операции. Обратитесь к разработчику. - - Пакет создан в новом формате и не может быть присоединён к данному + + Не подошедший шаблон - - Объект создан в новом формате и не может быть присоединён к данному пакету + + Имеется нераспознанный текст - - Общие знания + + Неподдерживаемый фрагмент: {0} - - Автомобили -Алфавит -Аниме -Астрономия -Биология -География -Игры: Консоли, Саундтреки, Настольные игры -Искусство -История -Кино: Режиссёры, Актёры, Премии -Книги: Комиксы -Мемы -Математика -Музыка: Рок, Поп, Рэп, Джаз, Металл, Электроника, Каверы, Русская музыка, Классическая музыка -Мультфильмы -Ребусы -Комиксы -Сериалы -Смешанная (солянка) -Спорт: Футбол -ТВ -Фантастика -Физика -Химия -Эрудиция: ЧГК, Политика, Личности -Юмор + + Версия пакета {0} не поддерживается. Максимальная поддерживаемая версия: {1} - - Не удалось создать временный файл. Попробуйте отключить антивирус + + Безымянный - - Основные + + Файл {0} не используется. Удалите его - - Загружено файлов: {0} + + Видео - - Думайте! + + Некорректная расстановка скобок - - Отсутствует ссылка + + Файлы вопросов (*.xml) | *.xml - - Расширение файла {0} ({1}) недопустимо. Допустимые расширения: {2} + + Документы XPS - - Размер файла {0} превышает допустимое значение {1} МБ + + YAML файлы - - Вопрос для всех + + YAML файлы (*.yaml) | *.yaml Ваш ответ? - - Невозможно включить контроль качества из-за ошибок: - - - Аудио - - - HTML - - - Изображение - - - Видео - - - Пакет - - - Версия пакета {0} не поддерживается. Максимальная поддерживаемая версия: {1} + + Ваши темы: \ No newline at end of file diff --git a/src/SIQuester/SIQuester.ViewModel/Workspaces/Dialogs/SelectThemesViewModel.cs b/src/SIQuester/SIQuester.ViewModel/Workspaces/Dialogs/SelectThemesViewModel.cs index 0e44e846..a9614113 100644 --- a/src/SIQuester/SIQuester.ViewModel/Workspaces/Dialogs/SelectThemesViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/Workspaces/Dialogs/SelectThemesViewModel.cs @@ -1,7 +1,7 @@ using SIPackages; using SIPackages.Core; +using SIPackages.Helpers; using SIQuester.Model; -using SIQuester.ViewModel.Configuration; using SIQuester.ViewModel.Contracts; using SIQuester.ViewModel.Properties; using System.Windows.Input; diff --git a/src/SIQuester/SIQuester.ViewModel/Workspaces/ImportDBStorageViewModel.cs b/src/SIQuester/SIQuester.ViewModel/Workspaces/ImportDBStorageViewModel.cs index d190edd8..dbf7aba9 100644 --- a/src/SIQuester/SIQuester.ViewModel/Workspaces/ImportDBStorageViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/Workspaces/ImportDBStorageViewModel.cs @@ -1,6 +1,7 @@ using Notions; using SIPackages; using SIPackages.Core; +using SIPackages.Helpers; using SIQuester.ViewModel.Configuration; using SIQuester.ViewModel.Contracts; using SIQuester.ViewModel.Model; diff --git a/src/SIQuester/SIQuester.ViewModel/Workspaces/NewViewModel.cs b/src/SIQuester/SIQuester.ViewModel/Workspaces/NewViewModel.cs index a2ba73b5..f1e71a52 100644 --- a/src/SIQuester/SIQuester.ViewModel/Workspaces/NewViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/Workspaces/NewViewModel.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using SIPackages; using SIPackages.Core; +using SIPackages.Helpers; using SIQuester.Model; using SIQuester.ViewModel.Contracts; using SIQuester.ViewModel.Model; diff --git a/src/SIQuester/SIQuester.ViewModel/Workspaces/QDocument.cs b/src/SIQuester/SIQuester.ViewModel/Workspaces/QDocument.cs index a62ad8fe..bc0a52a3 100644 --- a/src/SIQuester/SIQuester.ViewModel/Workspaces/QDocument.cs +++ b/src/SIQuester/SIQuester.ViewModel/Workspaces/QDocument.cs @@ -2279,10 +2279,10 @@ private async Task SaveAsAsync() internal void Search(string query, CancellationToken token) { - SearchResults = new SearchResults() { Query = query }; + SearchResults = new SearchResults { Query = query }; var package = Package; - if (package.Model.Contains(query)) + if (package.Model.ContainsInfoOwner(query)) { lock (_searchSync) { @@ -2297,7 +2297,7 @@ internal void Search(string query, CancellationToken token) foreach (var round in package.Rounds) { - if (round.Model.Contains(query)) + if (round.Model.ContainsInfoOwner(query)) { lock (_searchSync) { @@ -2312,7 +2312,7 @@ internal void Search(string query, CancellationToken token) foreach (var theme in round.Themes) { - if (theme.Model.Contains(query)) + if (theme.Model.ContainsInfoOwner(query)) { lock (_searchSync) { diff --git a/src/SIQuester/SIQuester.ViewModel/Workspaces/SearchFolderViewModel.cs b/src/SIQuester/SIQuester.ViewModel/Workspaces/SearchFolderViewModel.cs index 7dfd4928..843ed703 100644 --- a/src/SIQuester/SIQuester.ViewModel/Workspaces/SearchFolderViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/Workspaces/SearchFolderViewModel.cs @@ -1,6 +1,7 @@ using SIPackages; using SIPackages.Core; using SIQuester.Model; +using SIQuester.ViewModel.Helpers; using SIQuester.ViewModel.Properties; using System.Collections.ObjectModel; using System.Windows.Input; diff --git a/src/SIQuester/SIQuester.ViewModel/Workspaces/Sidebar/MediaStorageViewModel.cs b/src/SIQuester/SIQuester.ViewModel/Workspaces/Sidebar/MediaStorageViewModel.cs index b33d9abb..635031ed 100644 --- a/src/SIQuester/SIQuester.ViewModel/Workspaces/Sidebar/MediaStorageViewModel.cs +++ b/src/SIQuester/SIQuester.ViewModel/Workspaces/Sidebar/MediaStorageViewModel.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using SIPackages; using SIPackages.Core; +using SIQuester.ViewModel.Contracts; using SIQuester.ViewModel.Model; using SIQuester.ViewModel.PlatformSpecific; using SIQuester.ViewModel.Properties; diff --git a/src/SIQuester/SIQuester/App.xaml b/src/SIQuester/SIQuester/App.xaml index 215a3bb6..32c3797f 100644 --- a/src/SIQuester/SIQuester/App.xaml +++ b/src/SIQuester/SIQuester/App.xaml @@ -318,15 +318,6 @@ - - - - - - - - - @@ -1483,6 +1474,7 @@ + @@ -1500,6 +1492,7 @@ + @@ -1517,6 +1510,7 @@ + @@ -1535,6 +1529,7 @@ + @@ -1650,6 +1645,7 @@ + @@ -1668,6 +1664,7 @@ + @@ -1686,6 +1683,7 @@ + @@ -1704,6 +1702,7 @@ + diff --git a/src/SIQuester/SIQuester/Converters/ContentCommandsConverter.cs b/src/SIQuester/SIQuester/Converters/ContentCommandsConverter.cs index de8a195a..03a71e85 100644 --- a/src/SIQuester/SIQuester/Converters/ContentCommandsConverter.cs +++ b/src/SIQuester/SIQuester/Converters/ContentCommandsConverter.cs @@ -6,6 +6,9 @@ namespace SIQuester.Converters; +/// +/// Defines a list of commands for content items collection. +/// public sealed class ContentCommandsConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) @@ -13,13 +16,18 @@ public object Convert(object[] values, Type targetType, object parameter, Cultur var contentItems = (IContentCollection)values[0]; var files = (ICollection)values[1]; var contentType = (string)values[2]; + var qualityControl = (bool)values[3]; - var commands = new List(files.Count + 2) + var commands = new List(files.Count + (qualityControl ? 1 : 2)) { - new(contentItems.AddFile, ViewModel.Properties.Resources.File, contentType), - new(contentItems.LinkUri, ViewModel.Properties.Resources.Link, contentType) + new(contentItems.AddFile, ViewModel.Properties.Resources.File, contentType) }; + if (!qualityControl) + { + commands.Add(new UICommand(contentItems.LinkUri, ViewModel.Properties.Resources.Link, contentType)); + } + foreach (var file in files) { commands.Add(new UICommand(contentItems.LinkFile, file.Name, (file, contentType))); diff --git a/src/SIQuester/SIQuester/Implementation/DesktopManager.cs b/src/SIQuester/SIQuester/Implementation/DesktopManager.cs index a62f282d..0e6f08b8 100644 --- a/src/SIQuester/SIQuester/Implementation/DesktopManager.cs +++ b/src/SIQuester/SIQuester/Implementation/DesktopManager.cs @@ -7,6 +7,7 @@ using SIQuester.Properties; using SIQuester.View; using SIQuester.ViewModel; +using SIQuester.ViewModel.Contracts; using SIQuester.ViewModel.Model; using SIQuester.ViewModel.PlatformSpecific; using System.Diagnostics;