OSDN Git Service

An attempt to reduce build time
[winmerge-jp/winmerge-jp.git] / Src / ClipboardHistory.cpp
1 /** 
2  * @file  ClipboardHistory.cpp
3  *
4  * @brief Implementation for Clipboard history functions
5  */
6
7 #include "StdAfx.h"
8 #include "ClipboardHistory.h"
9 #include "ClipBoard.h"
10 #include "Concurrent.h"
11 #include "UniFile.h"
12
13 #if __has_include(<winrt/windows.applicationmodel.datatransfer.h>) && _MSC_VER >= 1930
14
15 #include <winrt/windows.foundation.collections.h>
16 #include <winrt/windows.applicationmodel.datatransfer.h>
17 #include <winrt/windows.graphics.imaging.h>
18 #include <winrt/windows.storage.streams.h>
19
20 #if !__has_include(<winrt/windows.applicationmodel.holographic.h>)
21 #pragma comment(lib, "windowsapp.lib") // < Windows SDK 10.0.22000.0
22 #endif
23
24 using namespace winrt::Windows::ApplicationModel::DataTransfer;
25 using namespace winrt::Windows::Graphics::Imaging;
26 using namespace winrt::Windows::Storage;
27
28 #define USE_WINRT
29
30 #endif
31
32 namespace ClipboardHistory
33 {
34         namespace impl
35         {
36                 std::shared_ptr<TempFile> CreateTempTextFile(const String& text)
37                 {
38                         auto pTempFile = std::make_shared<TempFile>(TempFile());
39                         pTempFile->Create(_T("CLP"), L".txt");
40                         String path = pTempFile->GetPath();
41                         UniStdioFile file;
42                         if (file.OpenCreateUtf8(path))
43                         {
44                                 file.WriteString(text);
45                                 file.Close();
46                         }
47                         return pTempFile;
48                 }
49
50                 String GetClipboardText()
51                 {
52                         String text;
53                         GetFromClipboard(text);
54                         return text;
55                 }
56
57 #ifdef USE_WINRT
58                 std::shared_ptr<TempFile> CreateTempBitmapFile(const DataPackageView& dataPackageView)
59                 {
60                         std::shared_ptr<TempFile> pTempFile(new TempFile());
61                         pTempFile->Create(_T("CLP"), _T(".png"));
62
63                         auto streamReference = dataPackageView.GetBitmapAsync().get();
64                         auto inputStream = streamReference.OpenReadAsync().get();
65                         auto decoder = BitmapDecoder::CreateAsync(inputStream).get();
66                         auto bitmap = decoder.GetSoftwareBitmapAsync().get();
67
68                         auto outputFile = StorageFile::GetFileFromPathAsync(pTempFile->GetPath()).get();
69                         auto outputStream = outputFile.OpenAsync(FileAccessMode::ReadWrite).get();
70                         auto encoder = BitmapEncoder::CreateAsync(BitmapEncoder::PngEncoderId(), outputStream).get();
71                         encoder.SetSoftwareBitmap(bitmap);
72                         encoder.FlushAsync().get();
73
74                         return pTempFile;
75                 }
76 #endif
77
78                 std::vector<Item> GetItems(unsigned num)
79                 {
80                         std::vector<Item> result;
81 #ifdef USE_WINRT
82                         try
83                         {
84                                 auto historyItems = Clipboard::GetHistoryItemsAsync().get();
85                                 auto items = historyItems.Items();
86                                 for (unsigned int i = 0; i < num; ++i)
87                                 {
88                                         result.emplace_back();
89                                         auto& item = result.back();
90                                         if (i < items.Size())
91                                         {
92                                                 try
93                                                 {
94                                                         auto dataPackageView = items.GetAt(i).Content();
95                                                         item.timestamp = winrt::clock::to_time_t(items.GetAt(i).Timestamp());
96                                                         if (dataPackageView.Contains(StandardDataFormats::Text()))
97                                                         {
98                                                                 item.pTextTempFile = CreateTempTextFile(dataPackageView.GetTextAsync().get().c_str());
99                                                         }
100                                                         if (dataPackageView.Contains(StandardDataFormats::Bitmap()))
101                                                         {
102                                                                 item.pBitmapTempFile = CreateTempBitmapFile(dataPackageView);
103                                                         }
104                                                         if (!item.pTextTempFile && !item.pBitmapTempFile)
105                                                         {
106                                                                 item.pTextTempFile = CreateTempTextFile(_T(""));
107                                                         }
108                                                 }
109                                                 catch (const winrt::hresult_error& e)
110                                                 {
111                                                         item.pTextTempFile = CreateTempTextFile(e.message().c_str());
112                                                 }
113                                         }
114                                         else
115                                         {
116                                                 if (i == 0)
117                                                         time(&item.timestamp);
118                                                 item.pTextTempFile = CreateTempTextFile(i == 0 ?
119                                                                 GetClipboardText() :
120                                                                 (!Clipboard::IsHistoryEnabled() ? _("Clipboard history is disabled.\r\nTo enable clipboard history, press Windows logo key + V and then click the Turn on button.") : _T("")));
121                                         }
122                                 }
123                         }
124                         catch (const winrt::hresult_error&)
125                         {
126                                 for (unsigned int i = 0; i < num; ++i)
127                                 {
128                                         result.emplace_back();
129                                         auto& item = result.back();
130                                         if (i == 0)
131                                                 time(&item.timestamp);
132                                         item.pTextTempFile = CreateTempTextFile(
133                                                 i == 0 ? GetClipboardText() : _("This system does not support clipboard history."));
134                                 }
135                         }
136 #else
137                         for (unsigned int i = 0; i < num; ++i)
138                         {
139                                 result.emplace_back();
140                                 auto& item = result.back();
141                                 if (i == 0)
142                                         time(&item.timestamp);
143                                 item.pTextTempFile = CreateTempTextFile(
144                                         i == 0 ? GetClipboardText() : _("The 32-bit version of WinMerge does not support Clipboard Compare"));
145                         }
146 #endif
147                         return result;
148                 }
149         }
150
151         std::vector<Item> GetItems(unsigned num)
152         {
153                 auto task = Concurrent::CreateTask([num] {
154                         return impl::GetItems(num);
155                 });
156                 return task.Get();
157         }
158 }