From 37ba3103c263f33bad81520eda53ad8cd962c12a Mon Sep 17 00:00:00 2001 From: libgenapps <33476799+libgenapps@users.noreply.github.com> Date: Wed, 23 May 2018 05:39:01 +0300 Subject: [PATCH] xslt update --- LibgenDesktop.Setup/AppFiles.cs | 3 +- LibgenDesktop.Setup/Constants.cs | 4 +- LibgenDesktop/Common/Constants.cs | 6 +- LibgenDesktop/LibgenDesktop.csproj | 9 +- .../Localizators/LibraryWindowLocalizator.cs | 24 +++- .../Models/Localization/Translation.cs | 11 ++ LibgenDesktop/Models/MainModel.cs | 90 +++++++++------ .../ProgressArgs/ScanCompleteProgress.cs | 4 +- .../Models/ProgressArgs/ScanProgress.cs | 5 +- LibgenDesktop/Resources/Languages/English.lng | 13 ++- LibgenDesktop/Resources/Languages/Russian.lng | 13 ++- .../Resources/Mirrors/booksc_org_step1.xslt | 9 ++ .../Resources/Mirrors/booksc_org_step2.xslt | 9 ++ .../Resources/Mirrors/mirrors.config | 4 +- .../Library/ScanResultItemViewModel.cs | 25 ++++ .../Windows/LibraryWindowViewModel.cs | 109 ++++++++++++++++-- .../Views/Windows/LibraryWindow.xaml | 78 +++++++++++-- 17 files changed, 342 insertions(+), 74 deletions(-) create mode 100644 LibgenDesktop/Resources/Mirrors/booksc_org_step1.xslt create mode 100644 LibgenDesktop/Resources/Mirrors/booksc_org_step2.xslt create mode 100644 LibgenDesktop/ViewModels/Library/ScanResultItemViewModel.cs diff --git a/LibgenDesktop.Setup/AppFiles.cs b/LibgenDesktop.Setup/AppFiles.cs index 3de509e..2c2f7c2 100644 --- a/LibgenDesktop.Setup/AppFiles.cs +++ b/LibgenDesktop.Setup/AppFiles.cs @@ -42,7 +42,8 @@ static AppFiles() AddFile(@"Mirrors\bookfi_net.xslt"); AddFile(@"Mirrors\b_ok_xyz_step1.xslt"); AddFile(@"Mirrors\b_ok_xyz_step2.xslt"); - AddFile(@"Mirrors\booksc_org.xslt"); + AddFile(@"Mirrors\booksc_org_step1.xslt"); + AddFile(@"Mirrors\booksc_org_step2.xslt"); } public static string GetBinariesDirectoryPath(bool is64Bit) diff --git a/LibgenDesktop.Setup/Constants.cs b/LibgenDesktop.Setup/Constants.cs index 67c382f..e39a086 100644 --- a/LibgenDesktop.Setup/Constants.cs +++ b/LibgenDesktop.Setup/Constants.cs @@ -2,8 +2,8 @@ { internal static class Constants { - public const string CURRENT_VERSION = "1.1.3"; - public const string TITLE_VERSION = "1.1.3"; + public const string CURRENT_VERSION = "1.1.4"; + public const string TITLE_VERSION = "1.1.4"; public const string PRODUCT_TITLE_FORMAT = "Libgen Desktop " + TITLE_VERSION + " ({0}-bit)"; public const string SHORTCUT_TITLE_FORMAT = "Libgen Desktop ({0}-bit)"; public const string PRODUCT_COMPANY = "Libgen Apps"; diff --git a/LibgenDesktop/Common/Constants.cs b/LibgenDesktop/Common/Constants.cs index 046099f..f34d362 100644 --- a/LibgenDesktop/Common/Constants.cs +++ b/LibgenDesktop/Common/Constants.cs @@ -4,9 +4,9 @@ namespace LibgenDesktop.Common { internal static class Constants { - public const string CURRENT_VERSION = "1.1.3"; - public const string CURRENT_GITHUB_RELEASE_NAME = "1.1.3"; - public static readonly DateTime CURRENT_GITHUB_RELEASE_DATE = new DateTime(2018, 5, 22); + public const string CURRENT_VERSION = "1.1.4"; + public const string CURRENT_GITHUB_RELEASE_NAME = "1.1.4"; + public static readonly DateTime CURRENT_GITHUB_RELEASE_DATE = new DateTime(2018, 5, 23); public const string CURRENT_DATABASE_VERSION = "1.0"; public const string APP_SETTINGS_FILE_NAME = "libgen.config"; diff --git a/LibgenDesktop/LibgenDesktop.csproj b/LibgenDesktop/LibgenDesktop.csproj index ad5a37f..545e133 100644 --- a/LibgenDesktop/LibgenDesktop.csproj +++ b/LibgenDesktop/LibgenDesktop.csproj @@ -237,6 +237,7 @@ + @@ -701,9 +702,13 @@ PreserveNewest Mirrors\b_ok_xyz_step2.xslt - + PreserveNewest - Mirrors\booksc_org.xslt + Mirrors\booksc_org_step1.xslt + + + PreserveNewest + Mirrors\booksc_org_step2.xslt PreserveNewest diff --git a/LibgenDesktop/Models/Localization/Localizators/LibraryWindowLocalizator.cs b/LibgenDesktop/Models/Localization/Localizators/LibraryWindowLocalizator.cs index 2bb5f0e..36437f3 100644 --- a/LibgenDesktop/Models/Localization/Localizators/LibraryWindowLocalizator.cs +++ b/LibgenDesktop/Models/Localization/Localizators/LibraryWindowLocalizator.cs @@ -12,22 +12,38 @@ public LibraryWindowLocalizator(List prioritizedTranslationList, La Scan = Format(translation => translation?.Scan); BrowseDirectoryDialogTitle = Format(translation => translation?.BrowseDirectoryDialogTitle); CreatingIndexes = Format(translation => translation?.CreatingIndexes); - NotFound = Format(translation => translation?.NotFound); + ScanLog = Format(translation => translation?.ScanLog); + Error = Format(translation => translation?.Error); + ColumnsFile = Format(translation => translation?.File); + ColumnsAuthors = Format(translation => translation?.Authors); + ColumnsTitle = Format(translation => translation?.Title); } public string WindowTitle { get; } public string Scan { get; } public string BrowseDirectoryDialogTitle { get; } public string CreatingIndexes { get; } - public string NotFound { get; } + public string ScanLog { get; } + public string Error { get; } + public string ColumnsFile { get; } + public string ColumnsAuthors { get; } + public string ColumnsTitle { get; } public string GetScanStartedString(string directory) => Format(translation => translation?.ScanStarted, new { directory }); - public string GetScanCompleteString(int found, int notFound) => Format(translation => translation?.ScanComplete, - new { found = Formatter.ToFormattedString(found), notFound = Formatter.ToFormattedString(notFound) }); + public string GetFoundString(int count) => Format(translation => translation?.Found, new { count }); + public string GetNotFoundString(int count) => Format(translation => translation?.NotFound, new { count }); + public string GetScanCompleteString(int found, int notFound, int errors) => Format(translation => translation?.ScanComplete, + new { found = Formatter.ToFormattedString(found), notFound = Formatter.ToFormattedString(notFound), + errors = Formatter.ToFormattedString(errors) }); private string Format(Func field, object templateArguments = null) { return Format(translation => field(translation?.Library), templateArguments); } + + private string Format(Func field, object templateArguments = null) + { + return Format(translation => field(translation?.Library?.Columns), templateArguments); + } } } diff --git a/LibgenDesktop/Models/Localization/Translation.cs b/LibgenDesktop/Models/Localization/Translation.cs index fa75097..b5106cc 100644 --- a/LibgenDesktop/Models/Localization/Translation.cs +++ b/LibgenDesktop/Models/Localization/Translation.cs @@ -544,6 +544,13 @@ internal class SynchronizationTranslation public SynchronizationLogMessagesTranslation LogMessages { get; set; } } + internal class LibraryColumnsTranslation + { + public string File { get; set; } + public string Authors { get; set; } + public string Title { get; set; } + } + internal class LibraryTranslation { public string WindowTitle { get; set; } @@ -551,8 +558,12 @@ internal class LibraryTranslation public string BrowseDirectoryDialogTitle { get; set; } public string ScanStarted { get; set; } public string CreatingIndexes { get; set; } + public string Found { get; set; } public string NotFound { get; set; } + public string ScanLog { get; set; } + public string Error { get; set; } public string ScanComplete { get; set; } + public LibraryColumnsTranslation Columns { get; set; } } internal class DatabaseTranslation diff --git a/LibgenDesktop/Models/MainModel.cs b/LibgenDesktop/Models/MainModel.cs index 54e7153..8c82038 100644 --- a/LibgenDesktop/Models/MainModel.cs +++ b/LibgenDesktop/Models/MainModel.cs @@ -489,6 +489,7 @@ public Task ScanAsync(string scanDirectory, IProgress progressHandler) { int found = 0; int notFound = 0; + int errors = 0; if (NonFictionBookCount > 0) { Logger.Debug("Retrieving the list of non-fiction table indexes."); @@ -499,9 +500,9 @@ public Task ScanAsync(string scanDirectory, IProgress progressHandler) progressHandler.Report(new GenericProgress(GenericProgress.Event.SCAN_CREATING_INDEXES)); localDatabase.CreateNonFictionMd5HashIndex(); } - ScanDirectory(scanDirectory.ToLower(), scanDirectory, progressHandler, ref found, ref notFound); + ScanDirectory(scanDirectory.ToLower(), scanDirectory, progressHandler, ref found, ref notFound, ref errors); } - progressHandler.Report(new ScanCompleteProgress(found, notFound)); + progressHandler.Report(new ScanCompleteProgress(found, notFound, errors)); }); } @@ -909,50 +910,73 @@ private TableType DetectImportTableType(SqlDumpReader.ParsedTableDefinition pars return TableType.UNKNOWN; } - private void ScanDirectory(string rootScanDirectory, string scanDirectory, IProgress progressHandler, ref int found, ref int notFound) + private void ScanDirectory(string rootScanDirectory, string scanDirectory, IProgress progressHandler, ref int found, ref int notFound, + ref int errors) { - foreach (string filePath in Directory.EnumerateFiles(scanDirectory)) + try { - string md5Hash; - try + foreach (string filePath in Directory.EnumerateFiles(scanDirectory)) { - using (MD5 md5 = MD5.Create()) - using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + string relativeFilePath = filePath; + if (relativeFilePath.ToLower().StartsWith(rootScanDirectory)) { - byte[] md5HashArray = md5.ComputeHash(fileStream); - md5Hash = BitConverter.ToString(md5HashArray).Replace("-", String.Empty).ToLowerInvariant(); + relativeFilePath = relativeFilePath.Substring(rootScanDirectory.Length + 1); + } + string md5Hash; + try + { + using (MD5 md5 = MD5.Create()) + using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + byte[] md5HashArray = md5.ComputeHash(fileStream); + md5Hash = BitConverter.ToString(md5HashArray).Replace("-", String.Empty).ToLowerInvariant(); + } + } + catch (Exception exception) + { + Logger.Debug($"Couldn't calculate MD5 hash for the file: {filePath}"); + Logger.Exception(exception); + progressHandler.Report(new ScanProgress(relativeFilePath, error: true)); + errors++; + continue; + } + try + { + NonFictionBook book = localDatabase.GetNonFictionBookByMd5Hash(md5Hash); + if (book != null) + { + progressHandler.Report(new ScanProgress(relativeFilePath, book.Authors, book.Title)); + found++; + } + else + { + progressHandler.Report(new ScanProgress(relativeFilePath)); + notFound++; + } + } + catch (Exception exception) + { + Logger.Debug($"Couldn't lookup the MD5 hash: {md5Hash} in the database for the file: {filePath}"); + Logger.Exception(exception); + progressHandler.Report(new ScanProgress(relativeFilePath, error: true)); + errors++; + continue; } } - catch (Exception exception) - { - Logger.Debug($"Couldn't calculate MD5 hash for the file: {filePath}"); - Logger.Exception(exception); - continue; - } - string relativeFilePath = filePath; - if (relativeFilePath.ToLower().StartsWith(rootScanDirectory)) - { - relativeFilePath = relativeFilePath.Substring(rootScanDirectory.Length + 1); - } - NonFictionBook book = localDatabase.GetNonFictionBookByMd5Hash(md5Hash); - if (book != null) - { - progressHandler.Report(new ScanProgress(relativeFilePath, book.Authors, book.Title)); - found++; - } - else + foreach (string directoryPath in Directory.EnumerateDirectories(scanDirectory)) { - progressHandler.Report(new ScanProgress(relativeFilePath)); - notFound++; + ScanDirectory(rootScanDirectory, directoryPath, progressHandler, ref found, ref notFound, ref errors); } } - foreach (string directoryPath in Directory.EnumerateDirectories(scanDirectory)) + catch (Exception exception) { - ScanDirectory(rootScanDirectory, directoryPath, progressHandler, ref found, ref notFound); + Logger.Exception(exception); + progressHandler.Report(new ScanProgress(scanDirectory, error: true)); + errors++; } } - private void CheckAndCreateNonFictionIndexes(IProgress progressHandler, CancellationToken cancellationToken) + private void CheckAndCreateNonFictionIndexes(IProgress progressHandler, CancellationToken cancellationToken) { Logger.Debug("Retrieving the list of non-fiction table indexes."); List nonFictionIndexes = localDatabase.GetNonFictionIndexList(); diff --git a/LibgenDesktop/Models/ProgressArgs/ScanCompleteProgress.cs b/LibgenDesktop/Models/ProgressArgs/ScanCompleteProgress.cs index 3e63fce..71abb47 100644 --- a/LibgenDesktop/Models/ProgressArgs/ScanCompleteProgress.cs +++ b/LibgenDesktop/Models/ProgressArgs/ScanCompleteProgress.cs @@ -2,13 +2,15 @@ { internal class ScanCompleteProgress { - public ScanCompleteProgress(int found, int notFound) + public ScanCompleteProgress(int found, int notFound, int errors) { Found = found; NotFound = notFound; + Errors = errors; } public int Found { get; } public int NotFound { get; } + public int Errors { get; } } } diff --git a/LibgenDesktop/Models/ProgressArgs/ScanProgress.cs b/LibgenDesktop/Models/ProgressArgs/ScanProgress.cs index 15cf70f..3a7edac 100644 --- a/LibgenDesktop/Models/ProgressArgs/ScanProgress.cs +++ b/LibgenDesktop/Models/ProgressArgs/ScanProgress.cs @@ -2,10 +2,11 @@ { internal class ScanProgress { - public ScanProgress(string relativeFilePath) + public ScanProgress(string relativeFilePath, bool error = false) { RelativeFilePath = relativeFilePath; Found = false; + Error = error; Authors = null; Title = null; } @@ -14,12 +15,14 @@ public ScanProgress(string relativeFilePath, string authors, string title) { RelativeFilePath = relativeFilePath; Found = true; + Error = false; Authors = authors; Title = title; } public string RelativeFilePath { get; } public bool Found { get; } + public bool Error { get; } public string Authors { get; } public string Title { get; } } diff --git a/LibgenDesktop/Resources/Languages/English.lng b/LibgenDesktop/Resources/Languages/English.lng index bda19e2..a41bdae 100644 --- a/LibgenDesktop/Resources/Languages/English.lng +++ b/LibgenDesktop/Resources/Languages/English.lng @@ -507,8 +507,17 @@ "BrowseDirectoryDialogTitle": "Scan for non-fiction books in...", "ScanStarted": "Scan started in {directory}", "CreatingIndexes": "Please wait. Creating missing database indexes...", - "NotFound": "not found", - "ScanComplete": "Scan complete: found {found}, not found {notFound}." + "Found": "Found ({count})", + "NotFound": "Not found ({count})", + "ScanLog": "Scan log", + "Error": "error", + "ScanComplete": "Scan complete. Found: {found}, not found: {notFound}, errors: {errors}.", + "Columns": + { + "File": "File", + "Authors": "Authors", + "Title": "Title" + } }, "Database": { diff --git a/LibgenDesktop/Resources/Languages/Russian.lng b/LibgenDesktop/Resources/Languages/Russian.lng index 4a6822c..e103c97 100644 --- a/LibgenDesktop/Resources/Languages/Russian.lng +++ b/LibgenDesktop/Resources/Languages/Russian.lng @@ -507,8 +507,17 @@ "BrowseDirectoryDialogTitle": "Искать известные книги в...", "ScanStarted": "Начато сканирование в {directory}", "CreatingIndexes": "Идет создание отсутствующих индексов. Пожалуйста, подождите...", - "NotFound": "не найдено", - "ScanComplete": "Сканирование завершено: найдено {found}, не найдено {notFound}." + "Found": "Найдено ({count})", + "NotFound": "Не найдено ({count})", + "ScanLog": "Журнал сканирования", + "Error": "ошибка", + "ScanComplete": "Сканирование завершено. Найдено: {found}, не найдено: {notFound}, ошибок: {errors}.", + "Columns": + { + "File": "Файл", + "Authors": "Авторы", + "Title": "Наименование" + } }, "Database": { diff --git a/LibgenDesktop/Resources/Mirrors/booksc_org_step1.xslt b/LibgenDesktop/Resources/Mirrors/booksc_org_step1.xslt new file mode 100644 index 0000000..22de7be --- /dev/null +++ b/LibgenDesktop/Resources/Mirrors/booksc_org_step1.xslt @@ -0,0 +1,9 @@ + + + + + http://booksc.org + + + + diff --git a/LibgenDesktop/Resources/Mirrors/booksc_org_step2.xslt b/LibgenDesktop/Resources/Mirrors/booksc_org_step2.xslt new file mode 100644 index 0000000..ba76800 --- /dev/null +++ b/LibgenDesktop/Resources/Mirrors/booksc_org_step2.xslt @@ -0,0 +1,9 @@ + + + + + http://booksc.org + + + + diff --git a/LibgenDesktop/Resources/Mirrors/mirrors.config b/LibgenDesktop/Resources/Mirrors/mirrors.config index 4640b1f..85bb2f4 100644 --- a/LibgenDesktop/Resources/Mirrors/mirrors.config +++ b/LibgenDesktop/Resources/Mirrors/mirrors.config @@ -43,8 +43,8 @@ }, "booksc.org": { - "SciMagDownloadUrl": "http://booksc.org/s/?q={doi}&t=0", - "SciMagDownloadTransformations": "booksc_org" + "SciMagDownloadUrl": "http://booksc.org/s/?q={md5}&t=0", + "SciMagDownloadTransformations": "booksc_org_step1,booksc_org_step2" }, "GenoType (TOR)": { diff --git a/LibgenDesktop/ViewModels/Library/ScanResultItemViewModel.cs b/LibgenDesktop/ViewModels/Library/ScanResultItemViewModel.cs new file mode 100644 index 0000000..bf1f8d1 --- /dev/null +++ b/LibgenDesktop/ViewModels/Library/ScanResultItemViewModel.cs @@ -0,0 +1,25 @@ +using LibgenDesktop.Models.Entities; + +namespace LibgenDesktop.ViewModels.Library +{ + internal class ScanResultItemViewModel : ViewModel + { + public ScanResultItemViewModel(LibgenObjectType libgenObjectType, int libgenObjectId, string fullFilePath, string relativeFilePath, string authors, + string title) + { + LibgenObjectType = libgenObjectType; + LibgenObjectId = libgenObjectId; + FullFilePath = fullFilePath; + RelativeFilePath = relativeFilePath; + Authors = authors; + Title = title; + } + + public LibgenObjectType LibgenObjectType { get; } + public int LibgenObjectId { get; } + public string FullFilePath { get; } + public string RelativeFilePath { get; } + public string Authors { get; } + public string Title { get; } + } +} diff --git a/LibgenDesktop/ViewModels/Windows/LibraryWindowViewModel.cs b/LibgenDesktop/ViewModels/Windows/LibraryWindowViewModel.cs index 0043f72..5b5a405 100644 --- a/LibgenDesktop/ViewModels/Windows/LibraryWindowViewModel.cs +++ b/LibgenDesktop/ViewModels/Windows/LibraryWindowViewModel.cs @@ -2,15 +2,22 @@ using System.Collections.ObjectModel; using LibgenDesktop.Infrastructure; using LibgenDesktop.Models; +using LibgenDesktop.Models.Entities; using LibgenDesktop.Models.Localization.Localizators; using LibgenDesktop.Models.ProgressArgs; +using LibgenDesktop.ViewModels.Library; namespace LibgenDesktop.ViewModels.Windows { internal class LibraryWindowViewModel : LibgenWindowViewModel { private bool isScanButtonVisible; - private bool isLogPanelVisible; + private bool isResultsPanelVisible; + private string foundTabHeaderTitle; + private string notFoundTabHeaderTitle; + private bool isScanLogTabSelected; + private ObservableCollection foundItems; + private ObservableCollection notFoundItems; private ObservableCollection scanLogs; public LibraryWindowViewModel(MainModel mainModel) @@ -36,15 +43,80 @@ public bool IsScanButtonVisible } } - public bool IsLogPanelVisible + public bool IsResultsPanelVisible { get { - return isLogPanelVisible; + return isResultsPanelVisible; } set { - isLogPanelVisible = value; + isResultsPanelVisible = value; + NotifyPropertyChanged(); + } + } + + public string FoundTabHeaderTitle + { + get + { + return foundTabHeaderTitle; + } + set + { + foundTabHeaderTitle = value; + NotifyPropertyChanged(); + } + } + + public string NotFoundTabHeaderTitle + { + get + { + return notFoundTabHeaderTitle; + } + set + { + notFoundTabHeaderTitle = value; + NotifyPropertyChanged(); + } + } + + public bool IsScanLogTabSelected + { + get + { + return isScanLogTabSelected; + } + set + { + isScanLogTabSelected = value; + NotifyPropertyChanged(); + } + } + + public ObservableCollection FoundItems + { + get + { + return foundItems; + } + set + { + foundItems = value; + NotifyPropertyChanged(); + } + } + + public ObservableCollection NotFoundItems + { + get + { + return notFoundItems; + } + set + { + notFoundItems = value; NotifyPropertyChanged(); } } @@ -67,7 +139,8 @@ public ObservableCollection ScanLogs private void Initialize() { isScanButtonVisible = true; - isLogPanelVisible = false; + isResultsPanelVisible = false; + isScanLogTabSelected = false; scanLogs = new ObservableCollection(); } @@ -80,8 +153,12 @@ private async void Scan() SelectFolderDialogResult selectFolderDialogResult = WindowManager.ShowSelectFolderDialog(selectFolderDialogParameters); if (selectFolderDialogResult.DialogResult) { + FoundItems = new ObservableCollection(); + NotFoundItems = new ObservableCollection(); + UpdateResultTabHeaders(); + IsScanLogTabSelected = true; IsScanButtonVisible = false; - IsLogPanelVisible = true; + IsResultsPanelVisible = true; string scanDirectory = selectFolderDialogResult.SelectedFolderPath; ScanLogs.Add(Localization.GetScanStartedString(scanDirectory)); Progress scanProgressHandler = new Progress(HandleScanProgress); @@ -102,19 +179,31 @@ private void HandleScanProgress(object progress) } break; case ScanProgress scanProgress: - if (scanProgress.Found) + if (scanProgress.Error) + { + ScanLogs.Add($"{scanProgress.RelativeFilePath} — {Localization.Error}."); + } + else if (scanProgress.Found) { - ScanLogs.Add($"{scanProgress.RelativeFilePath}: {scanProgress.Authors} — {scanProgress.Title}"); + FoundItems.Add(new ScanResultItemViewModel(LibgenObjectType.NON_FICTION_BOOK, 0, null, scanProgress.RelativeFilePath, + scanProgress.Authors, scanProgress.Title)); } else { - ScanLogs.Add($"{scanProgress.RelativeFilePath}: {Localization.NotFound}."); + NotFoundItems.Add(scanProgress.RelativeFilePath); } + UpdateResultTabHeaders(); break; case ScanCompleteProgress scanCompleteProgress: - ScanLogs.Add(Localization.GetScanCompleteString(scanCompleteProgress.Found, scanCompleteProgress.NotFound)); + ScanLogs.Add(Localization.GetScanCompleteString(scanCompleteProgress.Found, scanCompleteProgress.NotFound, scanCompleteProgress.Errors)); break; } } + + private void UpdateResultTabHeaders() + { + FoundTabHeaderTitle = Localization.GetFoundString(FoundItems.Count); + NotFoundTabHeaderTitle = Localization.GetNotFoundString(NotFoundItems.Count); + } } } diff --git a/LibgenDesktop/Views/Windows/LibraryWindow.xaml b/LibgenDesktop/Views/Windows/LibraryWindow.xaml index 94a64cb..c60976b 100644 --- a/LibgenDesktop/Views/Windows/LibraryWindow.xaml +++ b/LibgenDesktop/Views/Windows/LibraryWindow.xaml @@ -2,22 +2,78 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:LibgenDesktop.Views.Controls" + xmlns:u="clr-namespace:LibgenDesktop.Views.Utils" Title="{Binding Localization.WindowTitle}" Style="{StaticResource LibraryWindow}"> -