26
26
#include < algorithm>
27
27
#include < CommDlg.h>
28
28
#include < ShlObj.h>
29
+ #include < Shlwapi.h>
30
+ #include < stdio.h>
31
+ #include < sys/stat.h>
29
32
30
33
// Forward declarations for functions at the bottom of this file
31
- void FixFilename (ExtensionString& filename);
34
+ void ConvertToNativePath (ExtensionString& filename);
35
+ void ConvertToUnixPath (ExtensionString& filename);
32
36
int ConvertErrnoCode (int errorCode, bool isReading = true );
33
37
int ConvertWinErrorCode (int errorCode, bool isReading = true );
34
38
@@ -52,8 +56,6 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
52
56
wchar_t szFile[MAX_PATH];
53
57
szFile[0 ] = 0 ;
54
58
55
- FixFilename (initialDirectory);
56
-
57
59
// TODO (issue #64) - This method should be using IFileDialog instead of the
58
60
/* outdated SHGetPathFromIDList and GetOpenFileName.
59
61
@@ -103,8 +105,6 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
103
105
ofn.lpstrFile = szFile;
104
106
ofn.nMaxFile = MAX_PATH;
105
107
106
- allowMulitpleSelection = false ; // TODO: Raymond, please implement.
107
-
108
108
// TODO (issue #65) - Use passed in file types. Note, when fileTypesStr is null, all files should be shown
109
109
/* findAndReplaceString( fileTypesStr, std::string(" "), std::string(";*."));
110
110
LPCWSTR allFilesFilter = L"All Files\0*.*\0\0";*/
@@ -119,23 +119,21 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
119
119
if (GetOpenFileName (&ofn)) {
120
120
if (allowMulitpleSelection) {
121
121
// Multiple selection encodes the files differently
122
- /*
122
+
123
123
// If multiple files are selected, the first null terminator
124
124
// signals end of directory that the files are all in
125
125
std::wstring dir (szFile);
126
126
127
127
// Check for two null terminators, which signal that only one file
128
128
// was selected
129
129
if (szFile[dir.length () + 1 ] == ' \0 ' ) {
130
- // Escape the single file path and add it to the JSON array
131
- std::wstring escaped;
132
- EscapeJSONString(dir, escaped);
133
- results += L"\"" + escaped + L"\"";
130
+ ExtensionString filePath (dir);
131
+ ConvertToUnixPath (filePath);
132
+ selectedFiles->SetString (0 , filePath);
134
133
} else {
135
134
// Multiple files are selected
136
135
wchar_t fullPath[MAX_PATH];
137
- bool firstFile = true;
138
- for (int i = dir.length() + 1;;) {
136
+ for (int i = (dir.length () + 1 ), fileIndex = 0 ; ; fileIndex++) {
139
137
// Get the next file name
140
138
std::wstring file (&szFile[i]);
141
139
@@ -145,25 +143,17 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
145
143
146
144
// The filename is relative to the directory that was specified as
147
145
// the first string
148
- if (PathCombine(fullPath, dir.c_str(), file.c_str()) != NULL)
149
- {
150
- // Append a comma separator if it is not the first file in the list
151
- if (firstFile)
152
- firstFile = false;
153
- else
154
- results += L",";
155
-
156
- // Escape the path and add it to the list
157
- std::wstring escaped;
158
- EscapeJSONString(std::wstring(fullPath), escaped);
159
- results += L"\"" + escaped + L"\"";
160
- }
146
+ if (PathCombine (fullPath, dir.c_str (), file.c_str ()) != NULL ) {
147
+ ExtensionString filePath (fullPath);
148
+ ConvertToUnixPath (filePath);
149
+ selectedFiles->SetString (fileIndex, filePath);
150
+ }
161
151
162
152
// Go to the start of the next file name
163
153
i += file.length () + 1 ;
164
154
}
165
155
}
166
- */
156
+
167
157
} else {
168
158
// If multiple files are not allowed, add the single file
169
159
selectedFiles->SetString (0 , szFile);
@@ -176,9 +166,10 @@ int32 ShowOpenDialog(bool allowMulitpleSelection,
176
166
177
167
int32 ReadDir (ExtensionString path, CefRefPtr<CefListValue>& directoryContents)
178
168
{
179
- FixFilename (path);
169
+ if (path.length () && path[path.length () - 1 ] != ' /' )
170
+ path += ' /' ;
180
171
181
- path += L" \\ * " ;
172
+ path += ' * ' ;
182
173
183
174
WIN32_FIND_DATA ffd;
184
175
HANDLE hFind = FindFirstFile (path.c_str (), &ffd);
@@ -219,8 +210,6 @@ int32 ReadDir(ExtensionString path, CefRefPtr<CefListValue>& directoryContents)
219
210
220
211
int32 GetFileModificationTime (ExtensionString filename, uint32& modtime, bool & isDir)
221
212
{
222
- FixFilename (filename);
223
-
224
213
DWORD dwAttr = GetFileAttributes (filename.c_str ());
225
214
226
215
if (dwAttr == INVALID_FILE_ATTRIBUTES) {
@@ -229,6 +218,11 @@ int32 GetFileModificationTime(ExtensionString filename, uint32& modtime, bool& i
229
218
230
219
isDir = ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) != 0 );
231
220
221
+ // Remove trailing "/", if present. _wstat will fail with a "file not found"
222
+ // error if a directory has a trailing '/' in the name.
223
+ if (filename[filename.length () - 1 ] == ' /' )
224
+ filename[filename.length () - 1 ] = 0 ;
225
+
232
226
struct _stat buffer;
233
227
if (_wstat (filename.c_str (), &buffer) == -1 ) {
234
228
return ConvertErrnoCode (errno);
@@ -241,8 +235,6 @@ int32 GetFileModificationTime(ExtensionString filename, uint32& modtime, bool& i
241
235
242
236
int32 ReadFile (ExtensionString filename, ExtensionString encoding, std::string& contents)
243
237
{
244
- FixFilename (filename);
245
-
246
238
if (encoding != L" utf8" )
247
239
return ERR_UNSUPPORTED_ENCODING;
248
240
@@ -282,8 +274,6 @@ int32 ReadFile(ExtensionString filename, ExtensionString encoding, std::string&
282
274
283
275
int32 WriteFile (ExtensionString filename, std::string contents, ExtensionString encoding)
284
276
{
285
- FixFilename (filename);
286
-
287
277
if (encoding != L" utf8" )
288
278
return ERR_UNSUPPORTED_ENCODING;
289
279
@@ -306,22 +296,45 @@ int32 WriteFile(ExtensionString filename, std::string contents, ExtensionString
306
296
307
297
int32 SetPosixPermissions (ExtensionString filename, int32 mode)
308
298
{
309
- // TODO: Raymond, please implement
299
+ DWORD dwAttr = GetFileAttributes (filename.c_str ());
300
+
301
+ if (dwAttr == INVALID_FILE_ATTRIBUTES)
302
+ return ERR_NOT_FOUND;
303
+
304
+ if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) != 0 )
305
+ return NO_ERROR;
306
+
307
+ bool write = (mode & 0200 ) != 0 ;
308
+ bool read = (mode & 0400 ) != 0 ;
309
+ int mask = (write ? _S_IWRITE : 0 ) | (read ? _S_IREAD : 0 );
310
+
311
+ if (_wchmod (filename.c_str (), mask) == -1 ) {
312
+ return ConvertErrnoCode (errno);
313
+ }
314
+
310
315
return NO_ERROR;
311
316
}
312
317
313
318
int32 DeleteFileOrDirectory (ExtensionString filename)
314
319
{
315
- // TODO: Raymond, please implement
320
+ if (!DeleteFile (filename.c_str ()))
321
+ return ConvertWinErrorCode (GetLastError ());
322
+
316
323
return NO_ERROR;
317
324
}
318
325
319
- void FixFilename (ExtensionString& filename)
326
+ void ConvertToNativePath (ExtensionString& filename)
320
327
{
321
328
// Convert '/' to '\'
322
329
replace (filename.begin (), filename.end (), ' /' , ' \\ ' );
323
330
}
324
331
332
+ void ConvertToUnixPath (ExtensionString& filename)
333
+ {
334
+ // Convert '\\' to '/'
335
+ replace (filename.begin (), filename.end (), ' \\ ' , ' /' );
336
+ }
337
+
325
338
// Maps errors from errno.h to the brackets error codes
326
339
// found in brackets_extensions.js
327
340
int ConvertErrnoCode (int errorCode, bool isReading)
0 commit comments