-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathConverters.cs
More file actions
240 lines (206 loc) · 8.39 KB
/
Copy pathConverters.cs
File metadata and controls
240 lines (206 loc) · 8.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// Copyright © 2020 Paddy Xu, Frank Becker
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Data;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using QuickLook.Common.ExtensionMethods;
namespace QuickLook.Plugin.FolderViewer
{
public class Percent100ToVisibilityVisibleConverter : DependencyObject, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
value = 0;
var percent = (double)value;
return Math.Abs(percent - 100) < 0.00001 ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class Percent100ToVisibilityCollapsedConverter : DependencyObject, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
value = 0;
var percent = (double)value;
return Math.Abs(percent - 100) < 0.00001 ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class SizePrettyPrintConverter : DependencyObject, IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var size = (ulong)values[0];
var isFolder = (bool)values[1];
return isFolder ? "" : ((long)size).ToPrettySize(2);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class DatePrintConverter : DependencyObject, IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var date = (DateTime)values[0];
var isFolder = (bool)values[1];
return isFolder ? "" : date.ToString(CultureInfo.CurrentCulture);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class FileToIconConverter : DependencyObject, IMultiValueConverter
{
// FB: I have no idea what I'm doing here...
// A bunch gratuitously copied from WindowsThumbnailProvider.cs
[Flags]
internal enum ThumbnailOptions
{
None = 0x00,
BiggerSizeOk = 0x01,
InMemoryOnly = 0x02,
IconOnly = 0x04,
ThumbnailOnly = 0x08,
InCacheOnly = 0x10,
IconBackground = 0x80,
ScaleUp = 0x100
}
internal enum HResult
{
Ok = 0x0000,
False = 0x0001,
InvalidArguments = unchecked((int)0x80070057),
OutOfMemory = unchecked((int)0x8007000E),
NoInterface = unchecked((int)0x80004002),
Fail = unchecked((int)0x80004005),
ElementNotFound = unchecked((int)0x80070490),
TypeElementNotFound = unchecked((int)0x8002802B),
NoObject = unchecked((int)0x800401E5),
Win32ErrorCanceled = 1223,
Canceled = unchecked((int)0x800704C7),
ResourceInUse = unchecked((int)0x800700AA),
AccessDenied = unchecked((int)0x80030005)
}
internal enum SIGDN : uint
{
NORMALDISPLAY = 0,
PARENTRELATIVEPARSING = 0x80018001,
PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
DESKTOPABSOLUTEPARSING = 0x80028000,
PARENTRELATIVEEDITING = 0x80031001,
DESKTOPABSOLUTEEDITING = 0x8004c000,
FILESYSPATH = 0x80058000,
URL = 0x80068000
}
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
internal interface IShellItem
{
void BindToHandler(IntPtr pbc,
[MarshalAs(UnmanagedType.LPStruct)] Guid bhid,
[MarshalAs(UnmanagedType.LPStruct)] Guid riid,
out IntPtr ppv);
void GetParent(out IShellItem ppsi);
void GetDisplayName(SIGDN sigdnName, out IntPtr ppszName);
void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
void Compare(IShellItem psi, uint hint, out int piOrder);
}
[ComImport]
[Guid("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IShellItemImageFactory
{
[PreserveSig]
HResult GetImage(
[In][MarshalAs(UnmanagedType.Struct)] NativeSize size,
[In] ThumbnailOptions flags,
[Out] out IntPtr phbm);
}
[StructLayout(LayoutKind.Sequential)]
internal struct NativeSize
{
private int width;
private int height;
public int Width
{
set => width = value;
}
public int Height
{
set => height = value;
}
}
private const string IShellItem2Guid = "7E9FB0D3-919F-4307-AB2E-9B1860310C93";
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int SHCreateItemFromParsingName(
[MarshalAs(UnmanagedType.LPWStr)] string path,
// The following parameter is not used - binding context.
IntPtr pbc,
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)] out IShellItem shellItem);
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject([In] IntPtr hObject);
private static IntPtr GetHBitmap(string fileName, int width, int height, ThumbnailOptions options)
{
var shellItem2Guid = new Guid(IShellItem2Guid);
var retCode =
SHCreateItemFromParsingName(fileName, IntPtr.Zero, ref shellItem2Guid, out var nativeShellItem);
if (retCode != 0)
return IntPtr.Zero;
var nativeSize = new NativeSize
{
Width = width,
Height = height
};
var hr = ((IShellItemImageFactory)nativeShellItem).GetImage(nativeSize, options, out var hBitmap);
Marshal.ReleaseComObject(nativeShellItem);
return hr == HResult.Ok ? hBitmap : IntPtr.Zero;
}
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var fullPath = (string)values[0];
// HBitmap to BitmapSource - See https://stackoverflow.com/a/35274172
var bitmapHandle = GetHBitmap(fullPath, 16, 16, ThumbnailOptions.None);
try
{
return Imaging.CreateBitmapSourceFromHBitmap(bitmapHandle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally { DeleteObject(bitmapHandle); }
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}