1 #ifndef ADM_qtScript_Directory
2 #define ADM_qtScript_Directory
3 
4 #include <QtCore/QDir>
5 #include <QtScript/QScriptable>
6 #include <QtScript/QScriptValue>
7 
8 namespace ADM_qtScript
9 {
10 	/** \brief The Directory %class provides access to directory structures and their contents.
11 	  *
12 	  * A Directory object is used to manipulate path names, access information regarding paths and files,
13 	  * and manipulate the underlying file system.
14 	  *
15 	  * The Directory class uses "/" as a universal directory separator in the same way that "/" is used
16 	  * as a path separator in URLs. If you always use "/" as a directory separator, the Directory class
17 	  * will translate your paths to conform to the underlying operating system.
18 	  *
19 	  * A Directory object can point to a file using either a relative or an absolute path. Absolute
20 	  * paths begin with the directory separator (optionally preceded by a drive specification under
21 	  * Windows). Relative file names begin with a directory name or a file name and specify a path
22 	  * relative to the current directory.
23 	  */
24 	class Directory : public QObject, protected QScriptable
25 	{
26 		Q_OBJECT
27 		Q_ENUMS(Filter Sort)
28 
29 	public:
30 		/** \brief Describes the filtering options available to Directory; e.g. for entryList() and entryInfoList().
31 		 *
32 		 * The filter value is specified by combining values from the following list using the bitwise OR operator:
33 		 */
34 		enum Filter
35 		{
36 			Directories = 0x001, /**< List directories that match the filters. */
37 			Files       = 0x002, /**< List files. */
38 			Drives      = 0x004, /**< List disk drives (ignored under Unix). */
39 			NoSymLinks  = 0x008, /**< Do not list symbolic links (ignored by operating systems that don't support symbolic links). */
40 			AllEntries  = Directories | Files | Drives, /**< List directories, files, drives and symlinks (this does not list broken symlinks unless you specify System). */
41 			Readable    = 0x010, /**< List files for which the application has read access. The Readable value needs to be combined with Directories or Files. */
42 			Writable    = 0x020, /**< List files for which the application has write access. The Writable value needs to be combined with Directories or Files. */
43 			Executable  = 0x040, /**< List files for which the application has execute access. The Executable value needs to be combined with Directories or Files. */
44 			Modified    = 0x080, /**< Only list files that have been modified (ignored under Unix). */
45 			Hidden      = 0x100, /**< List hidden files (on Unix, files starting with a "."). */
46 			System      = 0x200, /**< List system files (on Unix, FIFOs, sockets and device files). */
47 			AllDirectories = 0x400, /**< List all directories; i.e. don't apply the filters to directory names. */
48 			CaseSensitive = 0x800, /**< The filter should be case sensitive. */
49 			NoDotAndDotDot = 0x1000, /**< Do not list the special entries "." and "..". */
50 			NoFilter = -1 /**< List everything. */
51 		};
52 		Q_DECLARE_FLAGS(Filters, Filter)
53 
54 		/** \brief Describes the sort options available to Directory, e.g. for entryList() and entryInfoList().
55 		 *
56 		 * The sort value is specified by combining values from the following list using the bitwise OR operator.
57 		 * You can only specify one of the first four. If you specify both DirectoriesFirst and Reversed,
58 		 * directories are still put first, but in reverse order; the files will be listed after the
59 		 * directories, again in reverse order.
60 		 */
61 		enum Sort
62 		{
63 			Name        = 0x00, /**< Sort by name. */
64 			Time        = 0x01, /**< Sort by time (modification time). */
65 			Size        = 0x02, /**< Sort by file size. */
66 			Type        = 0x80, /**< Sort by file type (extension). */
67 			Unsorted    = 0x03, /**< Do not sort. */
68 			DirectoriesFirst = 0x04, /**< Put the directories first, then the files. */
69 			Reversed    = 0x08, /**< Reverse the sort order. */
70 			IgnoreCase  = 0x10, /**< Sort case-insensitively. */
71 			DirectoriesLast = 0x20, /**< Put the files first, then the directories. */
72 			LocaleAware = 0x40, /**< Sort items appropriately using the current locale settings. */
73 			NoSort = -1 /**< No sorting. */
74 		};
75 		Q_DECLARE_FLAGS(SortFlags, Sort)
76 
77 	private:
78 		Filters getMyFilters(QDir::Filters qtFilters);
79 		SortFlags getMySortFlags(QDir::SortFlags qtSortFlags);
80 		QDir::Filters getQtFilters(Filters myFilters);
81 		QDir::SortFlags getQtSortFlags(SortFlags mySortFlags);
82 
83 		QString getPath();
84 		void setPath(const QString &path);
85 		QString getAbsolutePath();
86 		QString getCanonicalPath();
87 		QString getDirectoryName();
88 		QScriptValue getNameFilters();
89 		void setNameFilters(QScriptValue nameFilters);
90 		Filter getFilter();
91 		void setFilter(Filter filter);
92 		Sort getSorting();
93 		void setSorting(Sort sort);
94 		uint getCount();
95 		bool isReadable();
96 		bool exists();
97 		bool isRoot();
98 		bool isRelative();
99 		bool isAbsolute();
100 		QString getSeparator();
101 		QString getCurrentPath();
102 		bool setCurrentPath(QString path);
103 		QString getHomePath();
104 		QString getRootPath();
105 		QString getTempPath();
106 		QScriptValue getDrives();
107 
108 	public:
109 	    /** \cond */
110 	    QDir _dir;
111 	    /** \endcond */
112 
113 		/** \brief Constructs a Directory object pointing to the given directory path.
114 		 * If path is empty the program's working directory, ("."), is used.
115 		 */
116 		Directory(QString /*% String %*/ path = "");
117 
118 		/** \brief Constructs a Directory object with specified path, that filters its entries by name
119 		 * using nameFilter and by attributes using filter. It also sorts the names using sort.
120 		 *
121 		 * The default nameFilter is an empty string, which excludes nothing; the default filters
122 		 * is AllEntries, which also means exclude nothing. The default sort is Name | IgnoreCase,
123 		 * i.e. sort by name case-insensitively.
124 		 *
125 		 * If path is an empty string, Directory uses "." (the current directory). If nameFilter
126 		 * is an empty string, Directory uses the name filter "*" (all files).
127 		 *
128 		 * Note that path need not exist.
129 		 */
130 		Directory(
131 			QString /*% String %*/ path, QString /*% String %*/ nameFilter,
132 			Sort sort = Sort(Name | IgnoreCase), Filter filter = AllEntries);
133 
134 		/** \cond */
135 		static QScriptValue constructor(QScriptContext *context, QScriptEngine *engine);
136 		/** \endcond */
137 
138 		/** \brief Gets or sets the path of the Directory object.
139 		  *
140 		  * The path is cleaned of redundant ".", ".." and of multiple separators. No check is made
141 		  * to see whether a directory with this path actually exists; but you can check for yourself
142 		  * using exists().
143 		  *
144 		  * The path can be either absolute or relative. Absolute paths begin with the directory
145 		  * separator "/" (optionally preceded by a drive specification under Windows). Relative file
146 		  * names begin with a directory name or a file name and specify a path relative to the current
147 		  * directory. An example of an absolute path is the string "/tmp/quartz", a relative path
148 		  * might look like "src/fatlib".
149 		  */
150 		Q_PROPERTY(QString /*% String %*/ path READ getPath WRITE setPath);
151 
152 		/** \brief Returns the absolute path (a path that starts with "/" or with a drive specification),
153 		 * which may contain symbolic links, but never contains redundant ".", ".." or multiple separators.
154 		 */
155 		Q_PROPERTY(QString /*% String %*/ absolutePath READ getAbsolutePath);
156 
157 		/** \brief Returns the canonical path, i.e. a path without symbolic links or redundant "." or ".."
158 		 * elements.
159 		 *
160 		 * On systems that do not have symbolic links this function will always return the same string
161 		 * that absolutePath returns. If the canonical path does not exist (normally due to dangling
162 		 * symbolic links) canonicalPath returns an empty string.
163 		 */
164 		Q_PROPERTY(QString /*% String %*/ canonicalPath READ getCanonicalPath);
165 
166 		/** \brief Returns the name of the directory.
167 		 *
168 		 * A directory name isn't the same as the path, e.g. a directory with the name "mail", might have
169 		 * the path "/var/spool/mail". If the directory has no name (e.g. it is the root directory) an
170 		 * empty string is returned.
171 		 *
172 		 * No check is made to ensure that a directory with this name actually exists; but see
173 		 * Directory.exists.
174 		 * \sa exists
175 		 */
176 		Q_PROPERTY(QString /*% String %*/ directoryName READ getDirectoryName);
177 
178 		/** \brief Gets or sets the name filters used by entryList() and entryInfoList().
179 		 *
180 		 * Each name filter is a wildcard (globbing) filter that understands * and ? wildcards.
181 		 */
182 		Q_PROPERTY(QScriptValue /*% Array %*/ nameFilters READ getNameFilters WRITE setNameFilters);
183 
184 		/** \brief Gets or sets the filter used by entryList() and entryInfoList().
185 		 *
186 		 * The filter is used to specify the kind of files that should be returned by entryList() and
187 		 * entryInfoList().
188 		 */
189 		Q_PROPERTY(Filter filter READ getFilter WRITE setFilter);
190 
191 		/** \brief Gets or sets the sort order used by entryList() and entryInfoList().
192 		 */
193 		Q_PROPERTY(Sort sorting READ getSorting WRITE setSorting);
194 
195 		/** \brief Returns the total number of directories and files in the directory.
196 		 *
197 		 * Equivalent to entryList().length.
198 		 */
199 		Q_PROPERTY(uint /*% Number %*/ count READ getCount);
200 
201 		/** \brief Returns true if the directory is readable and we can open files by name; otherwise
202 		 * returns false.
203 		 *
204 		 * Warning: A false value from this function isn't a guarantee that files in the directory
205 		 * are not accessible.
206 		 */
207 		Q_PROPERTY(bool /*% Boolean %*/ isReadable READ isReadable);
208 
209 		/** \brief Returns true if the directory exists; otherwise returns false.
210 		 *
211 		 * If a file with the same name is found this function will return false.
212 		 */
213 		Q_PROPERTY(bool /*% Boolean %*/ exists READ exists);
214 
215 		/** \brief Returns true if the directory is the root directory; otherwise returns false.
216 		 *
217 		 * Note: If the directory is a symbolic link to the root directory this function returns false.
218 		 * If you want to test for this use canonicalPath.
219 		 */
220 		Q_PROPERTY(bool /*% Boolean %*/ isRoot READ isRoot);
221 
222 		/** \brief Returns true if the directory path is relative; otherwise returns false.
223 		 */
224 		Q_PROPERTY(bool /*% Boolean %*/ isRelative READ isRelative);
225 
226 		/** \brief Returns true if the directory's path is absolute; otherwise returns false.
227 		 */
228 		Q_PROPERTY(bool /*% Boolean %*/ isAbsolute READ isAbsolute);
229 
230 		/** \brief Returns the native directory separator: "/" under Unix (including Mac OS X) and
231 		 * "\" under Windows.
232 		 *
233 		 * You do not need to use this function to build file paths. If you always use "/", the
234 		 * Directory class will translate your paths to conform to the underlying operating system.
235 		 * If you want to display paths to the user using their operating system's separator use
236 		 * toNativeSeparators()
237 		 */
238 		Q_PROPERTY(QString /*% String %*/ separator READ getSeparator);
239 
240 		/** \brief Gets or sets the current path.
241 		 */
242 		Q_PROPERTY(QString /*% String %*/ currentPath READ getCurrentPath WRITE setCurrentPath);
243 
244 		/** \brief Returns the absolute path of the user's home directory.
245 		 *
246 		 * Under Windows this function will return the directory of the current user's profile.
247 		 * Typically, this is: C:/Documents and Settings/Username
248 		 *
249 		 * Use the toNativeSeparators() function to convert the separators to the ones that are
250 		 * appropriate for the underlying operating system.
251 		 *
252 		 * If the directory of the current user's profile does not exist or cannot be retrieved,
253 		 * the following alternatives will be checked (in the given order) until an existing and
254 		 * available path is found:
255 		 *
256 		 * \li The path specified by the USERPROFILE environment variable.
257 		 * \li The path formed by concatenating the HOMEDRIVE and HOMEPATH environment variables.
258 		 * \li The path specified by the HOME environment variable.
259 		 * \li The path returned by the rootPath property (which uses the SystemDrive environment variable).
260 		 * \li The C:/ directory.
261 		 *
262 		 * Under non-Windows operating systems the HOME environment variable is used if it exists,
263 		 * otherwise the path returned by the rootPath() function is used.
264 		 */
265 		Q_PROPERTY(QString /*% String %*/ homePath READ getHomePath);
266 
267 		/** \brief Returns the absolute path of the root directory.
268 		 *
269 		 * For Unix operating systems this returns "/". For Windows file systems this normally
270 		 * returns "c:/".
271 		 */
272 		Q_PROPERTY(QString /*% String %*/ rootPath READ getRootPath);
273 
274 		/** \brief Returns the absolute path of the system's temporary directory.
275 		 *
276 		 * On Unix/Linux systems this is usually /tmp; on Windows this is usually the path in the
277 		 * TEMP or TMP environment variable. Whether a directory separator is added to the end or not,
278 		 * depends on the operating system.
279 		 */
280 		Q_PROPERTY(QString /*% String %*/ tempPath READ getTempPath);
281 
282 		/** \brief Returns a list of the root directories on this system.
283 		 *
284 		 * On Windows this returns a list of FileInformation objects containing "C:/", "D:/", etc.
285 		 * On other operating systems, it returns a list containing just one root directory (i.e. "/").
286 		 */
287 		Q_PROPERTY(QScriptValue /*% Array %*/ drives READ getDrives);
288 
289 		/** \brief Returns the path name of a file in the directory.
290 		 *
291 		 * Does not check if the file actually exists in the directory; but see Directory.exists.
292 		 * If the Directory object is relative, the returned path name will also be relative.
293 		 * Redundant multiple separators or "." and ".." directories in fileName are not removed
294 		 * (see cleanPath()).
295 		 */
296 		Q_INVOKABLE QString /*% String %*/ filePath(QString /*% String %*/ fileName);
297 
298 		/** \brief Returns the absolute path name of a file in the directory.
299 		 *
300 		 * Does not check if the file actually exists in the directory; but see Directory.exists.
301 		 * Redundant multiple separators or "." and ".." directories in fileName are not removed
302 		 * (see cleanPath()).
303 		 */
304 		Q_INVOKABLE QString /*% String %*/ absoluteFilePath(QString /*% String %*/ fileName);
305 
306 		/** \brief Returns the path to fileName relative to the directory.
307 		 */
308 		Q_INVOKABLE QString /*% String %*/ relativeFilePath(QString /*% String %*/ fileName);
309 
310 		/** \brief Returns pathName with the '/' separators converted to separators that are appropriate
311 		 * for the underlying operating system.
312 		 *
313 		 * On Windows, toNativeSeparators("c:/winnt/system32") returns "c:\winnt\system32". The returned
314 		 * string may be the same as the argument on some operating systems, for example on Unix.
315 		 */
316 		Q_INVOKABLE QString /*% String %*/ toNativeSeparators(QString /*% String %*/ pathName);
317 
318 		/** \brief Returns pathName using '/' as file separator.
319 		 *
320 		 * On Windows, for instance, fromNativeSeparators("c:\\winnt\\system32") returns
321 		 * "c:/winnt/system32". The returned string may be the same as the argument on some operating
322 		 * systems, for example on Unix.
323 		 */
324 		Q_INVOKABLE QString /*% String %*/ fromNativeSeparators(QString /*% String %*/ pathName);
325 
326 		/** \brief Changes the Directory object's directory to dirName.
327 		 *
328 		 * Note that the logical cd() operation is not performed if the new directory does not exist.
329 		 * Calling cd("..") is equivalent to calling cdUp().
330 		 *
331 		 * \return Returns true if the new directory exists and is readable; otherwise returns false.
332 		 */
333 		Q_INVOKABLE bool /*% Boolean %*/ changeDirectory(QString /*% String %*/ dirName);
334 
335 		/** \brief Changes directory by moving one directory up from the Directory object's current
336 		 * directory.
337 		 *
338 		 * Note that the logical changeDirectoryUp() operation is not performed if the new directory
339 		 * does not exist.
340 		 *
341 		 * \return Returns true if the new directory exists and is readable; otherwise returns false.
342 		 */
343 		Q_INVOKABLE bool /*% Boolean %*/ changeDirectoryUp();
344 
345 		/** \brief Returns a list of the names of all the files and directories in the directory.
346 		 *
347 		 * The list is ordered according to the name and attribute filters previously set with the
348 		 * nameFilters and filter properties.  The list is also sorted according to the flags set
349 		 * with the sorting property.
350 		 *
351 		 * The attribute filter and sorting specifications can be overridden using the filters and
352 		 * sort arguments.
353 		 *
354 		 * Note: To list symlinks that point to non existing files, System must be passed to the filter.
355 		 *
356 		 * Returns an empty list if the directory is unreadable, does not exist, or if nothing
357 		 * matches the specification.
358 		 */
359 		Q_INVOKABLE QScriptValue /*% Array %*/ entryList(Filter filters = NoFilter, Sort sort = NoSort);
360 
361 		/** \brief Returns a list of the names of all the files and directories in the directory.
362 		 *
363 		 * The list is ordered according to the name and attribute filters previously set with
364 		 * the nameFilters and filter properties.  The list is also sorted according to the flags set
365 		 * with the sorting property.
366 		 *
367 		 * The name filter, file attribute filter and sorting specification can be overridden using
368 		 * the nameFilters, filters, and sort arguments.
369 		 *
370 		 * Returns an empty list if the directory is unreadable, does not exist, or if nothing
371 		 * matches the specification.
372 		 */
373 		Q_INVOKABLE QScriptValue /*% Array %*/ entryList(QScriptValue /*% Array %*/ nameFilters, Filter filters = NoFilter, Sort sort = NoSort);
374 
375 		/** \brief Returns a list of FileInformation objects for all the files and directories in the directory,
376 		 * ordered according to the name and attribute filters previously set with the nameFilters and filter properties,
377 		 * and sorted according to the flags set with the sorting property.
378 		 *
379 		 * The name filter, file attribute filter, and sorting specification can be overridden using the nameFilters, filters, and sort arguments.
380 		 *
381 		 * Returns an empty list if the directory is unreadable, does not exist, or if nothing matches the specification.
382 		 */
383 		Q_INVOKABLE QScriptValue /*% Array %*/ entryInfoList(Filter filters = NoFilter, Sort sort = NoSort);
384 
385 		/** \brief Returns a list of FileInformation objects for all the files and directories in the directory,
386 		 * ordered according to the name and attribute filters previously set with the nameFilters and filter properties,
387 		 * and sorted according to the flags set with the sorting property.
388 		 *
389 		 * The attribute filter and sorting specifications can be overridden using the filters and sort arguments.
390 		 *
391 		 * Returns an empty list if the directory is unreadable, does not exist, or if nothing matches the specification.
392 		 */
393 		Q_INVOKABLE QScriptValue /*% Array %*/ entryInfoList(QScriptValue /*% Array %*/ nameFilters, Filter filters = NoFilter, Sort sort = NoSort);
394 
395 		/** \brief Creates a sub-directory called dirName.
396 		 * \return Returns true on success; otherwise returns false.
397 		 */
398 		Q_INVOKABLE bool /*% Boolean %*/ makeDirectory(QString /*% String %*/ dirName);
399 
400 		/** \brief Removes the directory specified by dirName.
401 		 *
402 		 * The directory must be empty for removeDirectory() to succeed.
403 		 *
404 		 * \return Returns true if successful; otherwise returns false.
405 		 */
406 		Q_INVOKABLE bool /*% Boolean %*/ removeDirectory(QString /*% String %*/ dirName);
407 
408 		/** \brief Creates the directory path dirPath.
409 		 *
410 		 * The function will create all parent directories necessary to create the directory.
411 		 *
412 		 * \return Returns true if successful; otherwise returns false.
413 		 */
414 		Q_INVOKABLE bool /*% Boolean %*/ makePath(QString /*% String %*/ dirPath);
415 
416 		/** \brief Removes the directory path dirPath.
417 		 *
418 		 * The function will remove all parent directories in dirPath, provided that they are empty.
419 		 * This is the opposite of makePath(dirPath).
420 		 *
421 		 * \return Returns true if successful; otherwise returns false.
422 		 */
423 		Q_INVOKABLE bool /*% Boolean %*/ removePath(QString /*% String %*/ dirPath);
424 
425 		/** \brief Converts the directory path to an absolute path.
426 		 *
427 		 * If it is already absolute nothing happens.
428 		 *
429 		 * \return Returns true if the conversion succeeded; otherwise returns false.
430 		 */
431 		Q_INVOKABLE bool /*% Boolean %*/ makeAbsolute();
432 
433 		/** \brief Removes the file, fileName.
434 		 *
435 		 * \return Returns true if the file is removed successfully; otherwise returns false.
436 		 */
437 		Q_INVOKABLE bool /*% Boolean %*/ remove(QString /*% String %*/ fileName);
438 
439 		/** \brief Renames a file or directory from oldName to newName
440 		 *
441 		 * On most file systems, rename() fails only if oldName does not exist, if newName and oldName
442 		 * are not on the same partition or if a file with the new name already exists. However, there
443 		 * are also other reasons why rename() can fail. For example, on at least one file system rename()
444 		 * fails if newName points to an open file.
445 		 *
446 		 * \return Returns true if successful; otherwise returns false.
447 		 */
448 		Q_INVOKABLE bool /*% Boolean %*/ rename(QString /*% String %*/ oldName, QString /*% String %*/ newName);
449 
450 		/** \brief Returns true if the file called name exists; otherwise returns false.
451 		 *
452 		 * Unless name contains an absolute file path, the file name is assumed to be relative to the
453 		 * current directory.
454 		 */
455 		Q_INVOKABLE bool /*% Boolean %*/ exists(QString /*% String %*/ name);
456 
457 		/** \brief Returns true if the fileName matches any of the wildcard (glob) patterns in the list
458 		 * of filters; otherwise returns false.
459 		 *
460 		 * The matching is case insensitive.
461 		 */
462 		Q_INVOKABLE bool /*% Boolean %*/ match(QScriptValue /*% Array %*/ filters, QString /*% String %*/ fileName);
463 
464 		/** \brief Returns true if the fileName matches the wildcard (glob) pattern filter; otherwise
465 		 * returns false.
466 		 *
467 		 * The filter may contain multiple patterns separated by spaces or semicolons. The matching is
468 		 * case insensitive.
469 		 */
470 		Q_INVOKABLE bool /*% Boolean %*/ match(QString /*% String %*/ filter, QString /*% String %*/ fileName);
471 
472 		/** \brief Removes all multiple directory separators "/" and resolves any "." or ".." found in
473 		 * the path.
474 		 *
475 		 * Symbolic links are kept. This function does not return the canonical path, but rather the
476 		 * simplest version of the input. For example, "./local" becomes "local", "local/../bin" becomes
477 		 * "bin" and "/local/usr/../bin" becomes "/local/bin".
478 		 */
479 		Q_INVOKABLE QString /*% String %*/ cleanPath(QString /*% String %*/ path);
480 
481 		/** \brief Refreshes the directory information.
482 		 */
483 		Q_INVOKABLE void refresh();
484 	};
485 }
486 
487 #endif
488