diff --git a/src/SIQuester/SIQuester.ViewModel/ContentItemsViewModel.cs b/src/SIQuester/SIQuester.ViewModel/ContentItemsViewModel.cs
index 47c9050f..7e4322b3 100644
--- a/src/SIQuester/SIQuester.ViewModel/ContentItemsViewModel.cs
+++ b/src/SIQuester/SIQuester.ViewModel/ContentItemsViewModel.cs
@@ -1,5 +1,6 @@
using SIPackages;
using SIPackages.Core;
+using SIQuester.Model;
using SIQuester.ViewModel.PlatformSpecific;
using SIQuester.ViewModel.Properties;
using System.Collections.Specialized;
@@ -466,21 +467,33 @@ private bool AddAtomObject(string mediaType)
index = -1;
}
- var atom = new ContentItemViewModel(new ContentItem
+ var contentItem = new ContentItemViewModel(new ContentItem
{
Type = mediaType,
Value = "",
Placement = mediaType == ContentTypes.Audio ? ContentPlacements.Background : ContentPlacements.Screen
});
- Insert(index + 1, atom);
+ Insert(index + 1, contentItem);
var last = collection.Files.LastOrDefault();
if (last != null)
{
- atom.Model.IsRef = true;
- atom.Model.Value = last.Model.Name;
+ contentItem.Model.IsRef = true;
+ contentItem.Model.Value = last.Model.Name;
+
+ if (AppSettings.Default.SetRightAnswerFromFileName)
+ {
+ var question = Owner;
+
+ if (question.Right.Last().Length == 0)
+ {
+ question.Right.RemoveAt(question.Right.Count - 1);
+ }
+
+ question.Right.Add(Path.GetFileNameWithoutExtension(last.Model.Name));
+ }
}
document.ActiveItem = null;
diff --git a/src/SIQuester/SIQuester.ViewModel/Model/AppSettings.cs b/src/SIQuester/SIQuester.ViewModel/Model/AppSettings.cs
index 4f8b879d..b0436617 100644
--- a/src/SIQuester/SIQuester.ViewModel/Model/AppSettings.cs
+++ b/src/SIQuester/SIQuester.ViewModel/Model/AppSettings.cs
@@ -432,6 +432,25 @@ public bool CheckFileSize
}
}
+ private bool _setRightAnswerFromFileName = false;
+
+ ///
+ /// Sets right answer when media file is added to question.
+ ///
+ [DefaultValue(false)]
+ public bool SetRightAnswerFromFileName
+ {
+ get => _setRightAnswerFromFileName;
+ set
+ {
+ if (_setRightAnswerFromFileName != value)
+ {
+ _setRightAnswerFromFileName = value;
+ OnPropertyChanged();
+ }
+ }
+ }
+
private string? _language = null;
///
@@ -559,5 +578,7 @@ internal void Reset()
_flatScale = defaultSettings._flatScale;
FlatLayoutMode = defaultSettings.FlatLayoutMode;
SelectOptionCount = DefaultSelectOptionCount;
+ CheckFileSize = defaultSettings.CheckFileSize;
+ SetRightAnswerFromFileName = defaultSettings.SetRightAnswerFromFileName;
}
}
diff --git a/src/SIQuester/SIQuester.ViewModel/PlatformSpecific/PlatformManager.cs b/src/SIQuester/SIQuester.ViewModel/PlatformSpecific/PlatformManager.cs
index 6e181b32..e2bbc100 100644
--- a/src/SIQuester/SIQuester.ViewModel/PlatformSpecific/PlatformManager.cs
+++ b/src/SIQuester/SIQuester.ViewModel/PlatformSpecific/PlatformManager.cs
@@ -73,4 +73,6 @@ public abstract bool ShowSaveUI(
public abstract bool ConfirmExclWithWindow(string message);
public abstract void Exit();
+
+ public abstract string CompressImage(string imageUri);
}
diff --git a/src/SIQuester/SIQuester.ViewModel/Workspaces/QDocument.cs b/src/SIQuester/SIQuester.ViewModel/Workspaces/QDocument.cs
index 9f39e7bc..97ae728c 100644
--- a/src/SIQuester/SIQuester.ViewModel/Workspaces/QDocument.cs
+++ b/src/SIQuester/SIQuester.ViewModel/Workspaces/QDocument.cs
@@ -1326,7 +1326,7 @@ internal QDocument(
var msvmLogger = loggerFactory.CreateLogger();
- Images = new MediaStorageViewModel(this, Document.Images, Resources.Images, msvmLogger);
+ Images = new MediaStorageViewModel(this, Document.Images, Resources.Images, msvmLogger, true);
Audio = new MediaStorageViewModel(this, Document.Audio, SIPackages.Properties.Resources.Audio, msvmLogger);
Video = new MediaStorageViewModel(this, Document.Video, SIPackages.Properties.Resources.Video, msvmLogger);
Html = new MediaStorageViewModel(this, Document.Html, SIPackages.Properties.Resources.Html, msvmLogger);
diff --git a/src/SIQuester/SIQuester.ViewModel/Workspaces/Sidebar/MediaStorageViewModel.cs b/src/SIQuester/SIQuester.ViewModel/Workspaces/Sidebar/MediaStorageViewModel.cs
index 41be6c0c..319eb255 100644
--- a/src/SIQuester/SIQuester.ViewModel/Workspaces/Sidebar/MediaStorageViewModel.cs
+++ b/src/SIQuester/SIQuester.ViewModel/Workspaces/Sidebar/MediaStorageViewModel.cs
@@ -2,6 +2,7 @@
using SIPackages;
using SIPackages.Core;
using SIQuester.ViewModel.Model;
+using SIQuester.ViewModel.PlatformSpecific;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
@@ -90,6 +91,11 @@ public MediaItemViewModel? CurrentFile
public ICommand DeleteItem { get; private set; }
+ ///
+ /// Compresses media item.
+ ///
+ public ICommand CompressItem { get; private set; }
+
private readonly string _header;
private readonly string _name;
@@ -120,7 +126,7 @@ public string Filter
}
}
- public MediaStorageViewModel(QDocument document, DataCollection collection, string header, ILogger logger)
+ public MediaStorageViewModel(QDocument document, DataCollection collection, string header, ILogger logger, bool canCompress = false)
{
_document = document;
_header = header;
@@ -131,6 +137,7 @@ public MediaStorageViewModel(QDocument document, DataCollection collection, stri
AddItem = new SimpleCommand(AddItem_Executed);
DeleteItem = new SimpleCommand(Delete_Executed);
+ CompressItem = new SimpleCommand(CompressItem_Executed) { CanBeExecuted = canCompress };
}
private void FillFiles(DataCollection collection)
@@ -167,7 +174,7 @@ private void Named_PropertyChanged(object? sender, PropertyChangedEventArgs e)
var newValue = item.Name;
var renamedExisting = !_added.Any(mi => mi.Model == item);
- Tuple tuple = null;
+ Tuple? tuple = null;
if (renamedExisting)
{
@@ -286,25 +293,88 @@ private void Delete_Executed(object? arg)
}
}
- private void PreviewRemove(MediaItemViewModel name)
+ private void CompressItem_Executed(object? arg)
{
- if (!Files.Contains(name))
+ if (arg == null)
{
return;
}
- if (_added.Contains(name))
+ var item = (MediaItemViewModel)arg;
+
+ if (item.MediaSource == null)
{
- _added.Remove(name);
- _removedStreams.Add(name, _streams[name]);
- _streams.Remove(name);
+ return;
+ }
+
+ var sourceUri = item.MediaSource.Uri;
+ var newUri = PlatformManager.Instance.CompressImage(sourceUri);
+
+ if (newUri != sourceUri)
+ {
+ var newItem = CreateItem(item.Name);
+ var currentIndex = Files.IndexOf(item);
+
+ var returnToCurrent = CurrentFile == item;
+
+ PreviewRemove(item);
+ PreviewAdd(newItem, newUri, currentIndex);
+ HasPendingChanges = IsChanged();
+
+ if (returnToCurrent)
+ {
+ CurrentFile = newItem;
+ }
+
+ OnChanged(new CustomChange(
+ () =>
+ {
+ var returnToCurrent = CurrentFile == newItem;
+
+ PreviewRemove(newItem);
+ PreviewAdd(item, sourceUri);
+ HasPendingChanges = IsChanged();
+
+ if (returnToCurrent)
+ {
+ CurrentFile = item;
+ }
+ },
+ () =>
+ {
+ var returnToCurrent = CurrentFile == item;
+
+ PreviewRemove(item);
+ PreviewAdd(newItem, newUri);
+ HasPendingChanges = IsChanged();
+
+ if (returnToCurrent)
+ {
+ CurrentFile = newItem;
+ }
+ }));
+ }
+ }
+
+ private void PreviewRemove(MediaItemViewModel item)
+ {
+ if (!Files.Contains(item))
+ {
+ return;
+ }
+
+ if (_added.Contains(item))
+ {
+ _added.Remove(item);
+ _removedStreams.Add(item, _streams[item]);
+ _streams.Remove(item);
}
else
{
- _removed.Add(name);
+ _removed.Add(item);
}
- Files.Remove(name);
+ Files.Remove(item);
OnPropertyChanged(nameof(Files));
}
@@ -388,7 +458,7 @@ public async Task ApplyToAsync(DataCollection collection, bool final = false)
private void AddItem_Executed(object? arg)
{
- var files = PlatformSpecific.PlatformManager.Instance.ShowMediaOpenUI(_name);
+ var files = PlatformManager.Instance.ShowMediaOpenUI(_name);
if (files == null)
{
@@ -440,7 +510,7 @@ public MediaItemViewModel AddFile(string file, string? name = null)
return item;
}
- private void PreviewAdd(MediaItemViewModel item, string path)
+ private void PreviewAdd(MediaItemViewModel item, string path, int index = -1)
{
if (_removed.Contains(item))
{
@@ -463,9 +533,22 @@ private void PreviewAdd(MediaItemViewModel item, string path)
_added.Add(item);
_streams[item] = Tuple.Create(path, fileStream);
+
+ if (_removedStreams.ContainsKey(item))
+ {
+ _removedStreams.Remove(item);
+ }
+ }
+
+ if (index == -1)
+ {
+ Files.Add(item);
+ }
+ else
+ {
+ Files.Insert(index, item);
}
- Files.Add(item);
OnPropertyChanged(nameof(Files));
HasPendingChanges = IsChanged();
diff --git a/src/SIQuester/SIQuester/Implementation/DesktopManager.cs b/src/SIQuester/SIQuester/Implementation/DesktopManager.cs
index 4c640505..90b125bb 100644
--- a/src/SIQuester/SIQuester/Implementation/DesktopManager.cs
+++ b/src/SIQuester/SIQuester/Implementation/DesktopManager.cs
@@ -14,6 +14,7 @@
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
+using System.Windows.Media.Imaging;
using System.Windows.Shell;
using System.Windows.Xps.Packaging;
using System.Windows.Xps.Serialization;
@@ -1024,6 +1025,55 @@ public override bool ConfirmExclWithWindow(string message)
public override void Exit() => Application.Current.MainWindow?.Close();
+ public override string CompressImage(string imageUri)
+ {
+ var extension = Path.GetExtension(imageUri);
+
+ if (extension != ".jpg" && extension != ".png")
+ {
+ return imageUri;
+ }
+
+ var bitmapImage = new BitmapImage(new Uri(imageUri));
+
+ var width = bitmapImage.PixelWidth;
+ var height = bitmapImage.PixelHeight;
+
+ const double TargetPixelSize = 800.0;
+ const int TargetQualityLevel = 90;
+
+ if (width <= TargetPixelSize && height <= TargetPixelSize)
+ {
+ return imageUri;
+ }
+
+ var widthScale = TargetPixelSize / width;
+ var heightScale = TargetPixelSize / height;
+
+ var scale = Math.Min(widthScale, heightScale);
+
+ var resizedImage = new TransformedBitmap(bitmapImage, new ScaleTransform(scale, scale));
+
+ BitmapEncoder encoder = extension == ".jpg" ? new JpegBitmapEncoder
+ {
+ QualityLevel = TargetQualityLevel
+ } : new PngBitmapEncoder();
+
+ encoder.Frames.Add(BitmapFrame.Create(resizedImage));
+
+ var fileName = Path.GetFileName(imageUri);
+ var outputDir = Path.Combine(Path.GetTempPath(), AppSettings.ProductName, AppSettings.MediaFolderName, Guid.NewGuid().ToString());
+ Directory.CreateDirectory(outputDir);
+ var outputPath = Path.Combine(outputDir, fileName);
+
+ using (var fileStream = new FileStream(outputPath, FileMode.Create))
+ {
+ encoder.Save(fileStream);
+ }
+
+ return outputPath;
+ }
+
public void Dispose()
{
diff --git a/src/SIQuester/SIQuester/Properties/Resources.Designer.cs b/src/SIQuester/SIQuester/Properties/Resources.Designer.cs
index 4d54ab7b..98f1b139 100644
--- a/src/SIQuester/SIQuester/Properties/Resources.Designer.cs
+++ b/src/SIQuester/SIQuester/Properties/Resources.Designer.cs
@@ -2536,6 +2536,15 @@ public static string SetLogo {
}
}
+ ///
+ /// Ищет локализованную строку, похожую на Задавать правильный ответ по имени файла, добавляемого в вопрос.
+ ///
+ public static string SetRightAnswerFromFileName {
+ get {
+ return ResourceManager.GetString("SetRightAnswerFromFileName", resourceCulture);
+ }
+ }
+
///
/// Ищет локализованную строку, похожую на Задать теги.
///
diff --git a/src/SIQuester/SIQuester/Properties/Resources.en-US.resx b/src/SIQuester/SIQuester/Properties/Resources.en-US.resx
index c6d8eaa2..a59cc18f 100644
--- a/src/SIQuester/SIQuester/Properties/Resources.en-US.resx
+++ b/src/SIQuester/SIQuester/Properties/Resources.en-US.resx
@@ -939,6 +939,9 @@
Set logo
+
+ Set right answer by name of file which is added to question
+
Set tags
diff --git a/src/SIQuester/SIQuester/Properties/Resources.resx b/src/SIQuester/SIQuester/Properties/Resources.resx
index 44264931..353a3e68 100644
--- a/src/SIQuester/SIQuester/Properties/Resources.resx
+++ b/src/SIQuester/SIQuester/Properties/Resources.resx
@@ -943,6 +943,9 @@
Задать логотип
+
+ Задавать правильный ответ по имени файла, добавляемого в вопрос
+
Задать теги
diff --git a/src/SIQuester/SIQuester/View/FlatDocView.xaml.cs b/src/SIQuester/SIQuester/View/FlatDocView.xaml.cs
index d39d34d5..a0667d23 100644
--- a/src/SIQuester/SIQuester/View/FlatDocView.xaml.cs
+++ b/src/SIQuester/SIQuester/View/FlatDocView.xaml.cs
@@ -555,6 +555,18 @@ private void TryImportMedia(DragEventArgs e, string filePath, string mediaType)
Value = item.Model.Name,
Placement = contentType == ContentTypes.Audio ? ContentPlacements.Background : ContentPlacements.Screen
}));
+
+ if (AppSettings.Default.SetRightAnswerFromFileName)
+ {
+ var question = contentItemsViewModel.Owner;
+
+ if (question.Right.Last().Length == 0)
+ {
+ question.Right.RemoveAt(question.Right.Count - 1);
+ }
+
+ question.Right.Add(Path.GetFileNameWithoutExtension(item.Model.Name));
+ }
}
internal static void RecountPrices(Theme theme, int pos, bool down)
diff --git a/src/SIQuester/SIQuester/View/MediaStorageView.xaml b/src/SIQuester/SIQuester/View/MediaStorageView.xaml
index 4a0ba3d7..e48ebdf4 100644
--- a/src/SIQuester/SIQuester/View/MediaStorageView.xaml
+++ b/src/SIQuester/SIQuester/View/MediaStorageView.xaml
@@ -214,10 +214,9 @@
Data="{Binding Source={StaticResource app_delete},Path=Data}" />
-
+
+
+
+
+
+
diff --git a/src/SIQuester/SIQuester/View/TreeDocView.xaml.cs b/src/SIQuester/SIQuester/View/TreeDocView.xaml.cs
index fc9a4b63..bd6387b2 100644
--- a/src/SIQuester/SIQuester/View/TreeDocView.xaml.cs
+++ b/src/SIQuester/SIQuester/View/TreeDocView.xaml.cs
@@ -471,6 +471,18 @@ private void TryImportMedia(DragEventArgs e, string filePath, string mediaType)
Value = item.Model.Name,
Placement = contentType == ContentTypes.Audio ? ContentPlacements.Background : ContentPlacements.Screen
}));
+
+ if (AppSettings.Default.SetRightAnswerFromFileName)
+ {
+ var question = contentItemsViewModel.Owner;
+
+ if (question.Right.Last().Length == 0)
+ {
+ question.Right.RemoveAt(question.Right.Count - 1);
+ }
+
+ question.Right.Add(Path.GetFileNameWithoutExtension(item.Model.Name));
+ }
}
private static bool AreEqual(Question question1, Question question2)