Skip to content

Commit 21fae1f

Browse files
committed
Merge branch 'dev'
2 parents 2f99ccd + f39144c commit 21fae1f

28 files changed

+699
-332
lines changed

Plugins/Wox.Plugin.Folder/Main.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,14 @@ private List<Result> QueryInternal_Directory_Exists(Query query)
191191
if (incompleteName.StartsWith(">"))
192192
{
193193
searchOption = SearchOption.AllDirectories;
194-
incompleteName = incompleteName.Substring(1);
194+
195+
// match everything before and after search term using supported wildcard '*', ie. *searchterm*
196+
incompleteName = "*" + incompleteName.Substring(1);
195197
}
196-
198+
199+
var folderList = new List<Result>();
200+
var fileList = new List<Result>();
201+
197202
try
198203
{
199204
// search folder and add results
@@ -204,11 +209,14 @@ private List<Result> QueryInternal_Directory_Exists(Query query)
204209
{
205210
if ((fileSystemInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue;
206211

207-
var result =
208-
fileSystemInfo is DirectoryInfo
209-
? CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName, query)
210-
: CreateFileResult(fileSystemInfo.FullName, query);
211-
results.Add(result);
212+
if(fileSystemInfo is DirectoryInfo)
213+
{
214+
folderList.Add(CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName, query));
215+
}
216+
else
217+
{
218+
fileList.Add(CreateFileResult(fileSystemInfo.FullName, query));
219+
}
212220
}
213221
}
214222
catch (Exception e)
@@ -223,7 +231,8 @@ fileSystemInfo is DirectoryInfo
223231
throw;
224232
}
225233

226-
return results;
234+
// Intial ordering, this order can be updated later by UpdateResultView.MainViewModel based on history of user selection.
235+
return results.Concat(folderList.OrderBy(x => x.Title)).Concat(fileList.OrderBy(x => x.Title)).ToList();
227236
}
228237

229238
private static Result CreateFileResult(string filePath, Query query)

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
WoX
22
===
33

4-
![Maintenance](https://img.shields.io/maintenance/yes/2019)
4+
![Maintenance](https://img.shields.io/maintenance/yes/2020)
55
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/jjw24/wox)](https://github.com/jjw24/Wox/releases/latest)
66
![GitHub Release Date](https://img.shields.io/github/release-date/jjw24/wox)
77
![GitHub commits since latest release](https://img.shields.io/github/commits-since/jjw24/wox/v1.3.524)
88
[![Build Status](https://dev.azure.com/Wox-Launcher/Wox/_apis/build/status/jjw24.Wox?branchName=master)](https://dev.azure.com/Wox-Launcher/Wox/_build/latest?definitionId=1&branchName=master)
9-
[![Github All Releases](https://img.shields.io/github/downloads/Wox-launcher/Wox/total.svg)](https://github.com/Wox-launcher/Wox/releases)
9+
[![Github All Releases](https://img.shields.io/github/downloads/jjw24/Wox/total.svg)](https://github.com/jjw24/Wox/releases)
1010
[![RamenBless](https://cdn.rawgit.com/LunaGao/BlessYourCodeTag/master/tags/ramen.svg)](https://github.com/LunaGao/BlessYourCodeTag)
1111

1212
**WoX** is a launcher for Windows that simply works. It's an alternative to [Alfred](https://www.alfredapp.com/) and [Launchy](http://www.launchy.net/). You can call it Windows omni-eXecutor if you want a long name.

Wox.Core/Updater.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,23 @@
1616

1717
namespace Wox.Core
1818
{
19-
public static class Updater
19+
public class Updater
2020
{
21-
private static readonly Internationalization Translater = InternationalizationManager.Instance;
21+
public string GitHubRepository { get; }
2222

23-
public static async Task UpdateApp()
23+
public Updater(string gitHubRepository)
24+
{
25+
GitHubRepository = gitHubRepository;
26+
}
27+
28+
public async Task UpdateApp()
2429
{
2530
UpdateManager m;
2631
UpdateInfo u;
2732

2833
try
2934
{
30-
m = await GitHubUpdateManager(Constant.Repository);
35+
m = await GitHubUpdateManager(GitHubRepository);
3136
}
3237
catch (Exception e) when (e is HttpRequestException || e is WebException || e is SocketException)
3338
{
@@ -66,8 +71,8 @@ public static async Task UpdateApp()
6671
await m.ApplyReleases(u);
6772
await m.CreateUninstallerRegistryEntry();
6873

69-
var newVersionTips = Translater.GetTranslation("newVersionTips");
70-
newVersionTips = string.Format(newVersionTips, fr.Version);
74+
var newVersionTips = this.NewVersinoTips(fr.Version.ToString());
75+
7176
MessageBox.Show(newVersionTips);
7277
Log.Info($"|Updater.UpdateApp|Update success:{newVersionTips}");
7378
}
@@ -90,7 +95,7 @@ private class GithubRelease
9095
}
9196

9297
/// https://github.com/Squirrel/Squirrel.Windows/blob/master/src/Squirrel/UpdateManager.Factory.cs
93-
private static async Task<UpdateManager> GitHubUpdateManager(string repository)
98+
private async Task<UpdateManager> GitHubUpdateManager(string repository)
9499
{
95100
var uri = new Uri(repository);
96101
var api = $"https://api.github.com/repos{uri.AbsolutePath}/releases";
@@ -109,7 +114,7 @@ private static async Task<UpdateManager> GitHubUpdateManager(string repository)
109114
return manager;
110115
}
111116

112-
public static string NewVersinoTips(string version)
117+
public string NewVersinoTips(string version)
113118
{
114119
var translater = InternationalizationManager.Instance;
115120
var tips = string.Format(translater.GetTranslation("newVersionTips"), version);

Wox.Infrastructure/Http/Http.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ public static class Http
1313
{
1414
private const string UserAgent = @"Mozilla/5.0 (Trident/7.0; rv:11.0) like Gecko";
1515

16+
static Http()
17+
{
18+
// need to be added so it would work on a win10 machine
19+
ServicePointManager.Expect100Continue = true;
20+
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls
21+
| SecurityProtocolType.Tls11
22+
| SecurityProtocolType.Tls12
23+
| SecurityProtocolType.Ssl3;
24+
}
25+
1626
public static HttpProxy Proxy { private get; set; }
1727
public static IWebProxy WebProxy()
1828
{

Wox.Infrastructure/Image/ImageCache.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ public bool ContainsKey(string key)
3939
var contains = _data.ContainsKey(key);
4040
return contains;
4141
}
42+
43+
public int CacheSize()
44+
{
45+
return _data.Count;
46+
}
47+
48+
/// <summary>
49+
/// return the number of unique images in the cache (by reference not by checking images content)
50+
/// </summary>
51+
public int UniqueImagesInCache()
52+
{
53+
return _data.Values.Distinct().Count();
54+
}
4255
}
4356

4457
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.IO;
3+
using System.Security.Cryptography;
4+
using System.Windows.Media;
5+
using System.Windows.Media.Imaging;
6+
7+
namespace Wox.Infrastructure.Image
8+
{
9+
public interface IImageHashGenerator
10+
{
11+
string GetHashFromImage(ImageSource image);
12+
}
13+
public class ImageHashGenerator : IImageHashGenerator
14+
{
15+
public string GetHashFromImage(ImageSource imageSource)
16+
{
17+
if (!(imageSource is BitmapSource image))
18+
{
19+
return null;
20+
}
21+
22+
try
23+
{
24+
using (var outStream = new MemoryStream())
25+
{
26+
// PngBitmapEncoder enc2 = new PngBitmapEncoder();
27+
// enc2.Frames.Add(BitmapFrame.Create(tt));
28+
29+
var enc = new JpegBitmapEncoder();
30+
var bitmapFrame = BitmapFrame.Create(image);
31+
bitmapFrame.Freeze();
32+
enc.Frames.Add(bitmapFrame);
33+
enc.Save(outStream);
34+
var byteArray = outStream.GetBuffer();
35+
using (var sha1 = new SHA1CryptoServiceProvider())
36+
{
37+
var hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
38+
return hash;
39+
}
40+
}
41+
}
42+
catch
43+
{
44+
return null;
45+
}
46+
47+
}
48+
}
49+
}

Wox.Infrastructure/Image/ImageLoader.cs

Lines changed: 80 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public static class ImageLoader
1414
{
1515
private static readonly ImageCache ImageCache = new ImageCache();
1616
private static BinaryStorage<ConcurrentDictionary<string, int>> _storage;
17+
private static readonly ConcurrentDictionary<string, string> GuidToKey = new ConcurrentDictionary<string, string>();
18+
private static IImageHashGenerator _hashGenerator;
1719

1820

1921
private static readonly string[] ImageExtensions =
@@ -30,7 +32,8 @@ public static class ImageLoader
3032

3133
public static void Initialize()
3234
{
33-
_storage = new BinaryStorage<ConcurrentDictionary<string, int>> ("Image");
35+
_storage = new BinaryStorage<ConcurrentDictionary<string, int>>("Image");
36+
_hashGenerator = new ImageHashGenerator();
3437
ImageCache.Usage = _storage.TryLoad(new ConcurrentDictionary<string, int>());
3538

3639
foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon })
@@ -43,16 +46,12 @@ public static void Initialize()
4346
{
4447
Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () =>
4548
{
46-
ImageCache.Usage.AsParallel().Where(i => !ImageCache.ContainsKey(i.Key)).ForAll(i =>
49+
ImageCache.Usage.AsParallel().ForAll(x =>
4750
{
48-
var img = Load(i.Key);
49-
if (img != null)
50-
{
51-
ImageCache[i.Key] = img;
52-
}
51+
Load(x.Key);
5352
});
5453
});
55-
Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.Usage.Count}>");
54+
Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.Usage.Count}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}");
5655
});
5756
}
5857

@@ -61,31 +60,56 @@ public static void Save()
6160
ImageCache.Cleanup();
6261
_storage.Save(ImageCache.Usage);
6362
}
64-
65-
public static ImageSource Load(string path, bool loadFullImage = false)
63+
64+
private class ImageResult
65+
{
66+
public ImageResult(ImageSource imageSource, ImageType imageType)
67+
{
68+
ImageSource = imageSource;
69+
ImageType = imageType;
70+
}
71+
72+
public ImageType ImageType { get; }
73+
public ImageSource ImageSource { get; }
74+
}
75+
76+
private enum ImageType
77+
{
78+
File,
79+
Folder,
80+
Data,
81+
ImageFile,
82+
Error,
83+
Cache
84+
}
85+
86+
private static ImageResult LoadInternal(string path, bool loadFullImage = false)
6687
{
6788
ImageSource image;
89+
ImageType type = ImageType.Error;
6890
try
6991
{
7092
if (string.IsNullOrEmpty(path))
7193
{
72-
return ImageCache[Constant.ErrorIcon];
94+
return new ImageResult(ImageCache[Constant.ErrorIcon], ImageType.Error);
7395
}
7496
if (ImageCache.ContainsKey(path))
7597
{
76-
return ImageCache[path];
98+
return new ImageResult(ImageCache[path], ImageType.Cache);
7799
}
78-
100+
79101
if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
80102
{
81-
return new BitmapImage(new Uri(path));
103+
var imageSource = new BitmapImage(new Uri(path));
104+
imageSource.Freeze();
105+
return new ImageResult(imageSource, ImageType.Data);
82106
}
83107

84108
if (!Path.IsPathRooted(path))
85109
{
86110
path = Path.Combine(Constant.ProgramDirectory, "Images", Path.GetFileName(path));
87111
}
88-
112+
89113
if (Directory.Exists(path))
90114
{
91115
/* Directories can also have thumbnails instead of shell icons.
@@ -94,14 +118,17 @@ public static ImageSource Load(string path, bool loadFullImage = false)
94118
* Wox responsibility.
95119
* - Solution: just load the icon
96120
*/
121+
type = ImageType.Folder;
97122
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize,
98123
Constant.ThumbnailSize, ThumbnailOptions.IconOnly);
124+
99125
}
100126
else if (File.Exists(path))
101127
{
102128
var extension = Path.GetExtension(path).ToLower();
103129
if (ImageExtensions.Contains(extension))
104130
{
131+
type = ImageType.ImageFile;
105132
if (loadFullImage)
106133
{
107134
image = LoadFullImage(path);
@@ -119,6 +146,7 @@ public static ImageSource Load(string path, bool loadFullImage = false)
119146
}
120147
else
121148
{
149+
type = ImageType.File;
122150
image = WindowsThumbnailProvider.GetThumbnail(path, Constant.ThumbnailSize,
123151
Constant.ThumbnailSize, ThumbnailOptions.None);
124152
}
@@ -128,17 +156,50 @@ public static ImageSource Load(string path, bool loadFullImage = false)
128156
image = ImageCache[Constant.ErrorIcon];
129157
path = Constant.ErrorIcon;
130158
}
131-
ImageCache[path] = image;
132-
image.Freeze();
159+
160+
if (type != ImageType.Error)
161+
{
162+
image.Freeze();
163+
}
133164
}
134165
catch (System.Exception e)
135166
{
136167
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path}", e);
137-
168+
type = ImageType.Error;
138169
image = ImageCache[Constant.ErrorIcon];
139170
ImageCache[path] = image;
140171
}
141-
return image;
172+
return new ImageResult(image, type);
173+
}
174+
175+
private static bool EnableImageHash = true;
176+
177+
public static ImageSource Load(string path, bool loadFullImage = false)
178+
{
179+
var imageResult = LoadInternal(path, loadFullImage);
180+
181+
var img = imageResult.ImageSource;
182+
if (imageResult.ImageType != ImageType.Error && imageResult.ImageType != ImageType.Cache)
183+
{ // we need to get image hash
184+
string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null;
185+
if (hash != null)
186+
{
187+
if (GuidToKey.TryGetValue(hash, out string key))
188+
{ // image already exists
189+
img = ImageCache[key];
190+
}
191+
else
192+
{ // new guid
193+
GuidToKey[hash] = path;
194+
}
195+
}
196+
197+
// update cache
198+
ImageCache[path] = img;
199+
}
200+
201+
202+
return img;
142203
}
143204

144205
private static BitmapImage LoadFullImage(string path)

Wox.Infrastructure/Image/ThumbnailReader.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ public static BitmapSource GetThumbnail(string fileName, int width, int height,
110110

111111
try
112112
{
113-
114113
return Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
115114
}
116115
finally

0 commit comments

Comments
 (0)