Merge branch 'qPCR4vir-nana_exp_filesystem' into hotfixes-1.0.2
This commit is contained in:
commit
62b55740df
@ -177,6 +177,7 @@
|
||||
<ClCompile Include="..\..\source\deploy.cpp" />
|
||||
<ClCompile Include="..\..\source\detail\win32\platform_spec.cpp" />
|
||||
<ClCompile Include="..\..\source\exceptions.cpp" />
|
||||
<ClCompile Include="..\..\source\filesystem\filesystem.cpp" />
|
||||
<ClCompile Include="..\..\source\filesystem\file_iterator.cpp" />
|
||||
<ClCompile Include="..\..\source\filesystem\fs_utility.cpp" />
|
||||
<ClCompile Include="..\..\source\gui\animation.cpp" />
|
||||
@ -247,6 +248,9 @@
|
||||
<ClCompile Include="..\..\source\traits.cpp" />
|
||||
<ClCompile Include="..\..\source\unicode_bidi.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\nana\filesystem\filesystem.hpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
@ -300,5 +300,13 @@
|
||||
<ClCompile Include="..\..\source\gui\widgets\spinbox.cpp">
|
||||
<Filter>Source Files\nana\gui\widgets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\source\filesystem\filesystem.cpp">
|
||||
<Filter>Source Files\nana\filesystem</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\include\nana\filesystem\filesystem.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -4,7 +4,10 @@
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
namespace nana{ namespace audio
|
||||
{ /// play an audio file in Windows WAV format
|
||||
{ /// class player
|
||||
/// \brief play an audio file in PCM Windows WAV format
|
||||
///
|
||||
/// \include audio_player.cpp
|
||||
class player
|
||||
: private nana::noncopyable
|
||||
{
|
||||
|
||||
@ -13,6 +13,25 @@
|
||||
#ifndef NANA_CONFIG_HPP
|
||||
#define NANA_CONFIG_HPP
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#pragma warning(disable : 4996)
|
||||
#if (_MSC_VER < 1900)
|
||||
// is this a good idea?
|
||||
#define NOT_IMPLEMENTED_KEYWORD_noexcept
|
||||
#endif // _MSC_VER < 1900
|
||||
#if (_MSC_VER == 1900)
|
||||
// google: break any code that tries to use codecvt<char16_t> or codecvt<char32_t>.
|
||||
// google: It appears the C++ libs haven't been compiled with native char16_t/char32_t support.
|
||||
// google: Those definitions are for codecvt<wchar_t>::id, codecvt<unsigned short>::id and codecvt<char>::id respectively.
|
||||
// However, the codecvt<char16_t>::id and codecvt<char32_t>::id definitions aren't there, and indeed, if you look at locale0.cpp in the CRT source code you'll see they're not defined at all.
|
||||
// google: That's a known issue, tracked by an active bug (DevDiv#1060849). We were able to update the STL's headers in response to char16_t/char32_t, but we still need to update the separately compiled sources.
|
||||
#define STD_CODECVT_NOT_SUPPORTED
|
||||
#endif // _MSC_VER == 1900
|
||||
#endif // _MSVC
|
||||
|
||||
//Select platform automatically
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
//Windows:
|
||||
@ -35,7 +54,7 @@
|
||||
#define PLATFORM_SPEC_HPP <nana/detail/linux_X11/platform_spec.hpp>
|
||||
#define STD_CODECVT_NOT_SUPPORTED
|
||||
#else
|
||||
# static_assert(false, "Only Windows and Unix are support now");
|
||||
# static_assert(false, "Only Windows and Unix are supported now");
|
||||
#endif
|
||||
|
||||
#if defined(NANA_MINGW) || defined(NANA_LINUX)
|
||||
|
||||
469
include/nana/filesystem/filesystem.hpp
Normal file
469
include/nana/filesystem/filesystem.hpp
Normal file
@ -0,0 +1,469 @@
|
||||
/*
|
||||
* A filesystem Implementation
|
||||
* Copyright(C) 2003 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: stdex/filesystem/filesystem.hpp
|
||||
* @description:
|
||||
* file_iterator is a toolkit for applying each file and directory in a
|
||||
* specified path.
|
||||
* Modiffied by Ariel Vina-Rodriguez:
|
||||
* Now mimic std::experimental::filesystem::v1 (boost v3)
|
||||
* and need VC2015 or a C++11 compiler. With a few correction will be compiler by VC2013
|
||||
*/
|
||||
|
||||
// http://en.cppreference.com/w/cpp/experimental/fs
|
||||
// http://cpprocks.com/introduction-to-tr2-filesystem-library-in-vs2012/ --- TR2 filesystem in VS2012
|
||||
// https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.140%29.aspx --- C++ 14, the <filesystem> header VS2015
|
||||
// https://msdn.microsoft.com/en-us/library/hh874694%28v=vs.120%29.aspx --- <filesystem> header VS2013
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf --- last pdf of std draft N4100 2014-07-04
|
||||
// http://cplusplus.github.io/filesystem-ts/working-draft.html --- in html format
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4099.html --- in html format
|
||||
// http://article.gmane.org/gmane.comp.lib.boost.devel/256220 --- The filesystem TS unanimously approved by ISO.
|
||||
// http://theboostcpplibraries.com/boost.filesystem --- Boost docs
|
||||
// http://www.boost.org/doc/libs/1_58_0/libs/filesystem/doc/index.htm ---
|
||||
// http://www.boost.org/doc/libs/1_34_0/libs/filesystem/doc/index.htm
|
||||
// http://www.boost.org/doc/libs/1_58_0/boost/filesystem.hpp
|
||||
// https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.200x --- Table 1.4. g++ C++ Technical Specifications Implementation Status
|
||||
|
||||
#ifndef NANA_FILESYSTEM_HPP
|
||||
#define NANA_FILESYSTEM_HPP
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
|
||||
#include <nana/deploy.hpp>
|
||||
|
||||
#ifdef NANA_WINDOWS
|
||||
#include <windows.h>
|
||||
typedef HANDLE find_handle_t;
|
||||
#elif defined(NANA_LINUX)
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
typedef DIR* find_handle_t;
|
||||
#endif
|
||||
|
||||
// namespace std { namespace experimental { namespace filesystem { inline namespace v1 {
|
||||
|
||||
namespace nana { namespace experimental
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
enum class file_type
|
||||
{
|
||||
none = 0, ///< has not been determined or an error occurred while trying to determine
|
||||
not_found = -1, ///< Pseudo-type: file was not found. Is not considered an error
|
||||
regular = 1,
|
||||
directory = 2 ,
|
||||
symlink =3, ///< Symbolic link file
|
||||
block =4, ///< Block special file
|
||||
character= 5 , ///< Character special file
|
||||
fifo = 6 , ///< FIFO or pipe file
|
||||
socket =7,
|
||||
unknown= 8 ///< The file does exist, but is of an operating system dependent type not covered by any of the other
|
||||
};
|
||||
|
||||
enum class perms
|
||||
{
|
||||
none =0, ///< There are no permissions set for the file.
|
||||
unknown = 0xFFFF ///< not known, such as when a file_status object is created without specifying the permissions
|
||||
};
|
||||
//enum class copy_options;
|
||||
//enum class directory_options;
|
||||
|
||||
// class filesystem_error;
|
||||
enum class error { none = 0 }; // deprecate ??
|
||||
|
||||
struct attribute // deprecate ??
|
||||
{
|
||||
uintmax_t size {};
|
||||
bool directory{};
|
||||
tm modified {};
|
||||
|
||||
attribute() {} ;
|
||||
attribute( uintmax_t size, bool is_directory) :size{size}, directory{is_directory} {}
|
||||
};
|
||||
|
||||
struct space_info
|
||||
{
|
||||
uintmax_t capacity;
|
||||
uintmax_t free;
|
||||
uintmax_t available;
|
||||
};
|
||||
using file_time_type = std::chrono::time_point< std::chrono::system_clock>;// trivial-clock> ;
|
||||
|
||||
class file_status
|
||||
{
|
||||
file_type m_ft = file_type::none;
|
||||
perms m_prms = perms::unknown;
|
||||
|
||||
public:
|
||||
explicit file_status(file_type ft = file_type::none, perms prms = perms::unknown)
|
||||
:m_ft{ft}, m_prms{prms}
|
||||
{}
|
||||
|
||||
file_status(const file_status& fs) : m_ft{fs.m_ft}, m_prms{fs.m_prms}{} // = default;
|
||||
file_status(file_status&& fs) : m_ft{fs.m_ft}, m_prms{fs.m_prms}{} // = default;
|
||||
|
||||
~file_status(){};
|
||||
file_status& operator=(const file_status&) = default;
|
||||
file_status& operator=(file_status&&fs) // = default;
|
||||
{
|
||||
m_ft=fs.m_ft; m_prms = fs.m_prms;
|
||||
return *this;
|
||||
}
|
||||
// observers
|
||||
file_type type() const { return m_ft;}
|
||||
perms permissions() const { return m_prms;}
|
||||
// modifiers
|
||||
void type (file_type ft) { m_ft=ft ;}
|
||||
void permissions(perms prms) { m_prms = prms; }
|
||||
};
|
||||
|
||||
/// concerned only with lexical and syntactic aspects and does not necessarily exist in
|
||||
/// external storage, and the pathname is not necessarily valid for the current operating system
|
||||
/// or for a particular file system
|
||||
/// A sequence of elements that identify the location of a file within a filesystem.
|
||||
/// The elements are the:
|
||||
/// rootname (opt), root-directory (opt), and an optional sequence of filenames.
|
||||
/// The maximum number of elements in the sequence is operating system dependent.
|
||||
class path
|
||||
{
|
||||
public:
|
||||
path();
|
||||
path(const nana::string&);
|
||||
|
||||
bool empty() const;
|
||||
path root() const;
|
||||
file_type what() const;
|
||||
|
||||
nana::string filename() const;
|
||||
#if defined(NANA_WINDOWS)
|
||||
public:
|
||||
nana::string to_string() const { return text_; }
|
||||
operator nana::string() const { return text_; }
|
||||
private:
|
||||
nana::string text_;
|
||||
#else
|
||||
public:
|
||||
std::string to_string() const { return text_; }
|
||||
operator std::string() const { return text_; }
|
||||
private:
|
||||
std::string text_;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct directory_entry
|
||||
{
|
||||
path m_path;
|
||||
|
||||
attribute attr{};
|
||||
//file_status m_status;
|
||||
|
||||
directory_entry(){}
|
||||
directory_entry(const nana::string& filename_, bool is_directory, uintmax_t size)
|
||||
:m_path{filename_}, attr{size, is_directory}
|
||||
{}
|
||||
|
||||
void assign (const path& p){ m_path=p;}
|
||||
void replace_filename(const path& p){ m_path=p;}
|
||||
|
||||
//file_status status() const;
|
||||
|
||||
operator const path&() const {return m_path;};
|
||||
const path& path() const {return m_path;}
|
||||
|
||||
};
|
||||
|
||||
/// an iterator for a sequence of directory_entry elements representing the files in a directory, not an recursive_directory_iterator
|
||||
//template<typename FileInfo>
|
||||
class directory_iterator :public std::iterator<std::input_iterator_tag, directory_entry>
|
||||
{
|
||||
public:
|
||||
using value_type = directory_entry ;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef const directory_entry* pointer;
|
||||
typedef const directory_entry& reference;
|
||||
typedef std::input_iterator_tag iterator_category;
|
||||
|
||||
directory_iterator():end_(true), handle_(nullptr){}
|
||||
|
||||
directory_iterator(const nana::string& file_path) { _m_prepare(file_path); }
|
||||
//directory_iterator(const path& file_path) { _m_prepare(file_path.filename()); }
|
||||
|
||||
const value_type&
|
||||
operator*() const { return value_; }
|
||||
|
||||
const value_type*
|
||||
operator->() const { return &(operator*()); }
|
||||
|
||||
directory_iterator& operator++()
|
||||
{ _m_read(); return *this; }
|
||||
|
||||
directory_iterator operator++(int)
|
||||
{
|
||||
directory_iterator tmp = *this;
|
||||
_m_read();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool equal(const directory_iterator& x) const
|
||||
{
|
||||
if(end_ && (end_ == x.end_)) return true;
|
||||
return (value_.path().filename() == x.value_.path().filename());
|
||||
}
|
||||
|
||||
|
||||
// enable directory_iterator range-based for statements
|
||||
directory_iterator begin( ) { return *this; }
|
||||
directory_iterator end( ) { return {}; }
|
||||
|
||||
private:
|
||||
template<typename Char>
|
||||
static bool _m_ignore(const Char * p)
|
||||
{
|
||||
while(*p == '.')
|
||||
++p;
|
||||
return (*p == 0);
|
||||
}
|
||||
|
||||
void _m_prepare(const nana::string& file_path)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
path_ = file_path;
|
||||
auto pat = file_path;
|
||||
DWORD attr = ::GetFileAttributes(pat.data());
|
||||
if((attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
pat += STR("\\*");
|
||||
|
||||
::HANDLE handle = ::FindFirstFile(pat.data(), &wfd_);
|
||||
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
end_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
while(_m_ignore(wfd_.cFileName))
|
||||
{
|
||||
if(::FindNextFile(handle, &wfd_) == 0)
|
||||
{
|
||||
end_ = true;
|
||||
::FindClose(handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
value_ = value_type(wfd_.cFileName,
|
||||
(FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
|
||||
wfd_.nFileSizeLow);
|
||||
|
||||
#elif defined(NANA_LINUX)
|
||||
path_ = nana::charset(file_path);
|
||||
if(path_.size() && (path_[path_.size() - 1] != '/'))
|
||||
path_ += '/';
|
||||
find_handle_t handle = opendir(path_.c_str());
|
||||
end_ = true;
|
||||
if(handle)
|
||||
{
|
||||
struct dirent * dnt = readdir(handle);
|
||||
if(dnt)
|
||||
{
|
||||
while(_m_ignore(dnt->d_name))
|
||||
{
|
||||
dnt = readdir(handle);
|
||||
if(dnt == 0)
|
||||
{
|
||||
closedir(handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
struct stat fst;
|
||||
if(stat((path_ + dnt->d_name).c_str(), &fst) == 0)
|
||||
{
|
||||
value_ = value_type(nana::charset(dnt->d_name), 0 != S_ISDIR(fst.st_mode), fst.st_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
value_.m_path = nana::charset(dnt->d_name);
|
||||
value_.size = 0;
|
||||
value_.directory = false;
|
||||
}
|
||||
end_ = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(false == end_)
|
||||
{
|
||||
find_ptr_ = std::shared_ptr<find_handle_t>(new find_handle_t(handle), inner_handle_deleter());
|
||||
handle_ = handle;
|
||||
}
|
||||
}
|
||||
|
||||
void _m_read()
|
||||
{
|
||||
if(handle_)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
if(::FindNextFile(handle_, &wfd_) != 0)
|
||||
{
|
||||
while(_m_ignore(wfd_.cFileName))
|
||||
{
|
||||
if(::FindNextFile(handle_, &wfd_) == 0)
|
||||
{
|
||||
end_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
value_ = value_type(wfd_.cFileName,
|
||||
(FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
|
||||
wfd_.nFileSizeLow);
|
||||
}
|
||||
else
|
||||
end_ = true;
|
||||
#elif defined(NANA_LINUX)
|
||||
struct dirent * dnt = readdir(handle_);
|
||||
if(dnt)
|
||||
{
|
||||
while(_m_ignore(dnt->d_name))
|
||||
{
|
||||
dnt = readdir(handle_);
|
||||
if(dnt == 0)
|
||||
{
|
||||
end_ = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
struct stat fst;
|
||||
if(stat((path_ + "/" + dnt->d_name).c_str(), &fst) == 0)
|
||||
value_ = value_type(wfd_.cFileName,
|
||||
(FILE_ATTRIBUTE_DIRECTORY & wfd_.dwFileAttributes) == FILE_ATTRIBUTE_DIRECTORY,
|
||||
wfd_.nFileSizeLow);
|
||||
else
|
||||
value_.m_path = nana::charset(dnt->d_name);
|
||||
}
|
||||
else
|
||||
end_ = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
private:
|
||||
struct inner_handle_deleter
|
||||
{
|
||||
void operator()(find_handle_t * handle)
|
||||
{
|
||||
if(handle && *handle)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
::FindClose(*handle);
|
||||
#elif defined(NANA_LINUX)
|
||||
::closedir(*handle);
|
||||
#endif
|
||||
}
|
||||
delete handle;
|
||||
}
|
||||
};
|
||||
private:
|
||||
bool end_{false};
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
WIN32_FIND_DATA wfd_;
|
||||
nana::string path_;
|
||||
#elif defined(NANA_LINUX)
|
||||
std::string path_;
|
||||
#endif
|
||||
std::shared_ptr<find_handle_t> find_ptr_;
|
||||
|
||||
find_handle_t handle_{nullptr};
|
||||
value_type value_;
|
||||
};
|
||||
|
||||
|
||||
//class recursive_directory_iterator;
|
||||
//// enable recursive_directory_iterator range-based for statements
|
||||
//recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
|
||||
//recursive_directory_iterator end(const recursive_directory_iterator&) noexcept;
|
||||
|
||||
//template<typename Value_Type>
|
||||
inline bool operator==(const directory_iterator/*<Value_Type>*/ & x, const directory_iterator/*<Value_Type>*/ & y)
|
||||
{
|
||||
return x.equal(y);
|
||||
}
|
||||
|
||||
//template<typename Value_Type>
|
||||
inline bool operator!=(const directory_iterator/*<Value_Type>*/ & x, const directory_iterator/*<Value_Type>*/ & y)
|
||||
{
|
||||
return !x.equal(y);
|
||||
}
|
||||
|
||||
|
||||
// file_status status(const path& p);
|
||||
bool file_attrib(const nana::string& file, attribute&);
|
||||
|
||||
inline bool is_directory(file_status s) { return s.type() == file_type::directory ;}
|
||||
inline bool is_directory(const path& p) { return directory_iterator{ p }->attr.directory; }//works??
|
||||
inline bool is_directory(const directory_entry& d) { return d.attr.directory; }
|
||||
//bool is_directory(const path& p, error_code& ec) noexcept;
|
||||
|
||||
//bool is_regular_file(file_status s) noexcept;
|
||||
|
||||
inline bool is_empty(const path& p)
|
||||
{
|
||||
directory_iterator d(p) ;
|
||||
return d->attr.directory ? d == directory_iterator()
|
||||
: d->attr.size == 0;
|
||||
}
|
||||
//bool is_empty(const path& p, error_code& ec) noexcept;
|
||||
|
||||
uintmax_t file_size(const nana::string& file); // deprecate?
|
||||
inline uintmax_t file_size(const path& p){return file_size(p.filename());}
|
||||
//uintmax_t file_size(const path& p, error_code& ec) noexcept;
|
||||
//long long filesize(const nana::string& file);
|
||||
|
||||
|
||||
bool create_directories(const path& p);
|
||||
//bool create_directories(const path& p, error_code& ec) noexcept;
|
||||
bool create_directory(const path& p);
|
||||
//bool create_directory(const path& p, error_code& ec) noexcept;
|
||||
bool create_directory(const path& p, const path& attributes);
|
||||
//bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept;
|
||||
bool create_directory(const nana::string& dir, bool & if_exist);
|
||||
inline bool create_directory(const path& p, bool & if_exist)
|
||||
{
|
||||
return create_directory(p.filename(), if_exist);
|
||||
};
|
||||
|
||||
|
||||
bool modified_file_time(const nana::string& file, struct tm&);
|
||||
|
||||
|
||||
nana::string path_user();
|
||||
|
||||
|
||||
path current_path();
|
||||
//path current_path(error_code& ec);
|
||||
void current_path(const path& p);
|
||||
//void current_path(const path& p, error_code& ec) noexcept;
|
||||
//nana::string path_current();
|
||||
|
||||
|
||||
//bool remove(const path& p);
|
||||
//bool remove(const path& p, error_code& ec) noexcept;
|
||||
bool rmfile(const nana::char_t* file);
|
||||
|
||||
//uintmax_t remove_all(const path& p);
|
||||
//uintmax_t remove_all(const path& p, error_code& ec) noexcept;
|
||||
bool rmdir(const nana::char_t* dir, bool fails_if_not_empty);
|
||||
nana::string root(const nana::string& path);
|
||||
|
||||
|
||||
}//end namespace filesystem
|
||||
} //end namespace experimental
|
||||
}//end namespace nana
|
||||
|
||||
#endif
|
||||
@ -34,27 +34,38 @@ namespace nana
|
||||
virtual const ::nana::rectangle& workarea() const = 0;
|
||||
};
|
||||
|
||||
/// Provides some functions to get the metrics of the monitors \include screen.cpp
|
||||
class screen
|
||||
{
|
||||
struct implement;
|
||||
public:
|
||||
static ::nana::size desktop_size();
|
||||
static ::nana::size primary_monitor_size();
|
||||
/// gets the size in pixel of the whole virtual desktop
|
||||
static ::nana::size desktop_size();
|
||||
|
||||
/// gets the resolution in pixel of the primary monitor,
|
||||
/// if there is only one monitor installed in the system,
|
||||
/// the return value of primary_monitor_size is equal to desktop_size's.
|
||||
static ::nana::size primary_monitor_size();
|
||||
|
||||
|
||||
screen();
|
||||
|
||||
/// Reload has no preconditions, it's safe to call on moved-from
|
||||
void reload();
|
||||
|
||||
/// Returns the number of display monitors
|
||||
/// Returns the number of display monitors installed in the system
|
||||
std::size_t count() const;
|
||||
|
||||
/// gets the display monitor that contains the specified point
|
||||
display& from_point(const point&);
|
||||
|
||||
/// gets the display monitor that contains the specified window
|
||||
display& from_window(window);
|
||||
|
||||
display& get_display(std::size_t index) const;
|
||||
display& get_primary() const;
|
||||
|
||||
/// applies a given function to all display monitors
|
||||
void for_each(std::function<void(display&)>) const;
|
||||
private:
|
||||
std::shared_ptr<implement> impl_;
|
||||
|
||||
@ -8,7 +8,8 @@ namespace nana{ namespace audio
|
||||
//class audio_stream
|
||||
bool audio_stream::open(const nana::string& file)
|
||||
{
|
||||
fs_.open(static_cast<std::string>(nana::charset(file)), std::ios::binary);
|
||||
std::string fname{nana::charset(file)};//static_cast<std::string>()
|
||||
fs_.open(fname, std::ios::binary);
|
||||
if(fs_)
|
||||
{
|
||||
wave_spec::master_riff_chunk riff;
|
||||
|
||||
444
source/filesystem/filesystem.cpp
Normal file
444
source/filesystem/filesystem.cpp
Normal file
@ -0,0 +1,444 @@
|
||||
/*
|
||||
* A FileSystem Utility Implementation
|
||||
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: nana/filesystem/filesystem.cpp
|
||||
* @description:
|
||||
* provide some interface for file managment
|
||||
*/
|
||||
|
||||
#include <nana/filesystem/filesystem.hpp>
|
||||
#include <vector>
|
||||
#if defined(NANA_WINDOWS)
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(NANA_MINGW)
|
||||
#ifndef _WIN32_IE
|
||||
#define _WIN32_IE 0x0500
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <shlobj.h>
|
||||
#include <nana/datetime.hpp>
|
||||
#elif defined(NANA_LINUX)
|
||||
#include <nana/charset.hpp>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
namespace nana {
|
||||
namespace experimental
|
||||
{
|
||||
namespace filesystem
|
||||
{
|
||||
//Because of No wide character version of POSIX
|
||||
#if defined(NANA_LINUX)
|
||||
typedef std::string string_t;
|
||||
const char* splstr = "/\\";
|
||||
#else
|
||||
typedef nana::string string_t;
|
||||
const nana::char_t* splstr = STR("/\\");
|
||||
#endif
|
||||
//class path
|
||||
path::path() {}
|
||||
|
||||
path::path(const nana::string& text)
|
||||
#if defined(NANA_WINDOWS)
|
||||
: text_(text)
|
||||
{
|
||||
#else
|
||||
:text_(nana::charset(text))
|
||||
{
|
||||
#endif
|
||||
auto pos = text_.find_last_of(splstr);
|
||||
for (; (pos != string_t::npos) && (pos + 1 == text_.size()); pos = text_.find_last_of(splstr))
|
||||
text_.erase(pos);
|
||||
}
|
||||
|
||||
bool path::empty() const
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
return (::GetFileAttributes(text_.c_str()) == INVALID_FILE_ATTRIBUTES);
|
||||
#elif defined(NANA_LINUX)
|
||||
struct stat sta;
|
||||
return (::stat(text_.c_str(), &sta) == -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
path path::root() const
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
return path(filesystem::root(text_));
|
||||
#elif defined(NANA_LINUX)
|
||||
return path(filesystem::root(nana::charset(text_)));
|
||||
#endif
|
||||
}
|
||||
|
||||
file_type path::what() const
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
unsigned long attr = ::GetFileAttributes(text_.c_str());
|
||||
if (INVALID_FILE_ATTRIBUTES == attr)
|
||||
return file_type::not_found; //??
|
||||
|
||||
if (FILE_ATTRIBUTE_DIRECTORY & attr)
|
||||
return file_type::directory;
|
||||
|
||||
return file_type::regular;
|
||||
#elif defined(NANA_LINUX)
|
||||
struct stat sta;
|
||||
if (-1 == ::stat(text_.c_str(), &sta))
|
||||
return file_type::not_found; //??
|
||||
|
||||
if ((S_IFDIR & sta.st_mode) == S_IFDIR)
|
||||
return file_type::directory;
|
||||
|
||||
if ((S_IFREG & sta.st_mode) == S_IFREG)
|
||||
return file_type::regular;
|
||||
|
||||
return file_type::none;
|
||||
#endif
|
||||
}
|
||||
|
||||
nana::string path::filename() const
|
||||
{
|
||||
string_t::size_type pos = text_.find_last_of(splstr);
|
||||
#if defined(NANA_WINDOWS)
|
||||
return text_.substr(pos + 1);
|
||||
#else
|
||||
return nana::charset(text_.substr(pos + 1));
|
||||
#endif
|
||||
}
|
||||
//end class path
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//rm_dir_recursive
|
||||
//@brief: remove a directory, if it is not empty, recursively remove it's subfiles and sub directories
|
||||
bool rm_dir_recursive(nana::string&& dir)
|
||||
{
|
||||
std::vector<directory_iterator::value_type> files;
|
||||
nana::string path = dir;
|
||||
path += '\\';
|
||||
|
||||
std::copy(directory_iterator(dir), directory_iterator(), std::back_inserter(files));
|
||||
|
||||
for (auto & f : files)
|
||||
{
|
||||
if (f.attr.directory)
|
||||
rm_dir_recursive(path + f.path().filename());
|
||||
else
|
||||
rmfile((path + f.path().filename()).c_str());
|
||||
}
|
||||
|
||||
return rmdir(dir.c_str(), true);
|
||||
}
|
||||
|
||||
bool mkdir_helper(const nana::string& dir, bool & if_exist)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
if (::CreateDirectory(dir.c_str(), 0))
|
||||
{
|
||||
if_exist = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if_exist = (::GetLastError() == ERROR_ALREADY_EXISTS);
|
||||
#elif defined(NANA_LINUX)
|
||||
if (0 == ::mkdir(static_cast<std::string>(nana::charset(dir)).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
|
||||
{
|
||||
if_exist = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if_exist = (errno == EEXIST);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
void filetime_to_c_tm(FILETIME& ft, struct tm& t)
|
||||
{
|
||||
FILETIME local_file_time;
|
||||
if (::FileTimeToLocalFileTime(&ft, &local_file_time))
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
::FileTimeToSystemTime(&local_file_time, &st);
|
||||
t.tm_year = st.wYear - 1900;
|
||||
t.tm_mon = st.wMonth - 1;
|
||||
t.tm_mday = st.wDay;
|
||||
t.tm_wday = st.wDayOfWeek - 1;
|
||||
t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay);
|
||||
|
||||
t.tm_hour = st.wHour;
|
||||
t.tm_min = st.wMinute;
|
||||
t.tm_sec = st.wSecond;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}//end namespace detail
|
||||
|
||||
bool file_attrib(const nana::string& file, attribute& attr)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||
if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &fad))
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
li.u.LowPart = fad.nFileSizeLow;
|
||||
li.u.HighPart = fad.nFileSizeHigh;
|
||||
attr.size = li.QuadPart;
|
||||
attr.directory = (0 != (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
|
||||
detail::filetime_to_c_tm(fad.ftLastWriteTime, attr.modified);
|
||||
return true;
|
||||
}
|
||||
#elif defined(NANA_LINUX)
|
||||
struct stat fst;
|
||||
if (0 == ::stat(static_cast<std::string>(nana::charset(file)).c_str(), &fst))
|
||||
{
|
||||
attr.bytes = fst.st_size;
|
||||
attr.is_directory = (0 != (040000 & fst.st_mode));
|
||||
attr.modified = *(::localtime(&fst.st_ctime));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
uintmax_t file_size(const nana::string& file)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
//Some compilation environment may fail to link to GetFileSizeEx
|
||||
typedef BOOL(__stdcall *GetFileSizeEx_fptr_t)(HANDLE, PLARGE_INTEGER);
|
||||
GetFileSizeEx_fptr_t get_file_size_ex = reinterpret_cast<GetFileSizeEx_fptr_t>(::GetProcAddress(::GetModuleHandleA("Kernel32.DLL"), "GetFileSizeEx"));
|
||||
if (get_file_size_ex)
|
||||
{
|
||||
HANDLE handle = ::CreateFile(file.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (INVALID_HANDLE_VALUE != handle)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
if (!get_file_size_ex(handle, &li))
|
||||
li.QuadPart = 0;
|
||||
|
||||
::CloseHandle(handle);
|
||||
return li.QuadPart;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#elif defined(NANA_LINUX)
|
||||
FILE * stream = ::fopen(static_cast<std::string>(nana::charset(file)).c_str(), "rb");
|
||||
long long size = 0;
|
||||
if (stream)
|
||||
{
|
||||
fseeko64(stream, 0, SEEK_END);
|
||||
size = ftello64(stream);
|
||||
fclose(stream);
|
||||
}
|
||||
return size;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool modified_file_time(const nana::string& file, struct tm& t)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
WIN32_FILE_ATTRIBUTE_DATA attr;
|
||||
if (::GetFileAttributesEx(file.c_str(), GetFileExInfoStandard, &attr))
|
||||
{
|
||||
FILETIME local_file_time;
|
||||
if (::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &local_file_time))
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
::FileTimeToSystemTime(&local_file_time, &st);
|
||||
t.tm_year = st.wYear - 1900;
|
||||
t.tm_mon = st.wMonth - 1;
|
||||
t.tm_mday = st.wDay;
|
||||
t.tm_wday = st.wDayOfWeek - 1;
|
||||
t.tm_yday = nana::date::day_in_year(st.wYear, st.wMonth, st.wDay);
|
||||
|
||||
t.tm_hour = st.wHour;
|
||||
t.tm_min = st.wMinute;
|
||||
t.tm_sec = st.wSecond;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#elif defined(NANA_LINUX)
|
||||
struct stat attr;
|
||||
if (0 == ::stat(static_cast<std::string>(nana::charset(file)).c_str(), &attr))
|
||||
{
|
||||
t = *(::localtime(&attr.st_ctime));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool create_directory(const nana::string& path, bool & if_exist)
|
||||
{
|
||||
if_exist = false;
|
||||
if (path.size() == 0) return false;
|
||||
|
||||
nana::string root;
|
||||
#if defined(NANA_WINDOWS)
|
||||
if (path.size() > 3 && path[1] == STR(':'))
|
||||
root = path.substr(0, 3);
|
||||
#elif defined(NANA_LINUX)
|
||||
if (path[0] == STR('/'))
|
||||
root = '/';
|
||||
#endif
|
||||
bool mkstat = false;
|
||||
std::size_t beg = root.size();
|
||||
|
||||
while (true)
|
||||
{
|
||||
beg = path.find_first_not_of(STR("/\\"), beg);
|
||||
if (beg == path.npos)
|
||||
break;
|
||||
|
||||
std::size_t pos = path.find_first_of(STR("/\\"), beg + 1);
|
||||
if (pos != path.npos)
|
||||
{
|
||||
root += path.substr(beg, pos - beg);
|
||||
|
||||
mkstat = detail::mkdir_helper(root, if_exist);
|
||||
if (mkstat == false && if_exist == false)
|
||||
return false;
|
||||
|
||||
#if defined(NANA_WINDOWS)
|
||||
root += STR('\\');
|
||||
#elif defined(NANA_LINUX)
|
||||
root += STR('/');
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (beg + 1 < path.size())
|
||||
{
|
||||
root += path.substr(beg);
|
||||
mkstat = detail::mkdir_helper(root, if_exist);
|
||||
}
|
||||
break;
|
||||
}
|
||||
beg = pos + 1;
|
||||
}
|
||||
return mkstat;
|
||||
}
|
||||
|
||||
bool rmfile(const nana::char_t* file)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
bool ret = false;
|
||||
if (file)
|
||||
{
|
||||
ret = (::DeleteFile(file) == TRUE);
|
||||
if (!ret)
|
||||
ret = (ERROR_FILE_NOT_FOUND == ::GetLastError());
|
||||
}
|
||||
|
||||
return ret;
|
||||
#elif defined(NANA_LINUX)
|
||||
if (std::remove(static_cast<std::string>(nana::charset(file)).c_str()))
|
||||
return (errno == ENOENT);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool rmdir(const nana::char_t* dir, bool fails_if_not_empty)
|
||||
{
|
||||
bool ret = false;
|
||||
if (dir)
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
ret = (::RemoveDirectory(dir) == TRUE);
|
||||
if (!fails_if_not_empty && (::GetLastError() == ERROR_DIR_NOT_EMPTY))
|
||||
ret = detail::rm_dir_recursive(dir);
|
||||
#elif defined(NANA_LINUX)
|
||||
std::string mbstr = nana::charset(dir);
|
||||
if (::rmdir(mbstr.c_str()))
|
||||
{
|
||||
if (!fails_if_not_empty && (errno == EEXIST || errno == ENOTEMPTY))
|
||||
ret = detail::rm_dir_recursive(dir);
|
||||
}
|
||||
else
|
||||
ret = true;
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
nana::string root(const nana::string& path)
|
||||
{
|
||||
std::size_t index = path.size();
|
||||
|
||||
if (index)
|
||||
{
|
||||
const nana::char_t * str = path.c_str();
|
||||
|
||||
for (--index; index > 0; --index)
|
||||
{
|
||||
nana::char_t c = str[index];
|
||||
if (c != '\\' && c != '/')
|
||||
break;
|
||||
}
|
||||
|
||||
for (--index; index > 0; --index)
|
||||
{
|
||||
nana::char_t c = str[index];
|
||||
if (c == '\\' || c == '/')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return index ? path.substr(0, index + 1) : nana::string();
|
||||
}
|
||||
|
||||
nana::string path_user()
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
nana::char_t path[MAX_PATH];
|
||||
if (SUCCEEDED(SHGetFolderPath(0, CSIDL_PROFILE, 0, SHGFP_TYPE_CURRENT, path)))
|
||||
return path;
|
||||
#elif defined(NANA_LINUX)
|
||||
const char * s = ::getenv("HOME");
|
||||
if (s)
|
||||
return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8);
|
||||
#endif
|
||||
return nana::string();
|
||||
}
|
||||
|
||||
path current_path()
|
||||
{
|
||||
#if defined(NANA_WINDOWS)
|
||||
nana::char_t buf[MAX_PATH];
|
||||
DWORD len = ::GetCurrentDirectory(MAX_PATH, buf);
|
||||
if (len)
|
||||
{
|
||||
if (len > MAX_PATH)
|
||||
{
|
||||
nana::char_t * p = new nana::char_t[len + 1];
|
||||
::GetCurrentDirectory(len + 1, p);
|
||||
nana::string s = p;
|
||||
delete[] p;
|
||||
return s;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
#elif defined(NANA_LINUX)
|
||||
const char * s = ::getenv("PWD");
|
||||
if (s)
|
||||
return nana::charset(std::string(s, std::strlen(s)), nana::unicode::utf8);
|
||||
#endif
|
||||
return nana::string();
|
||||
}
|
||||
}//end namespace filesystem
|
||||
} //end namespace experimental
|
||||
}//end namespace nana
|
||||
@ -18,6 +18,8 @@
|
||||
#include <nana/gui/widgets/skeletons/text_editor.hpp>
|
||||
#include <nana/gui/widgets/skeletons/textbase_export_interface.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace nana
|
||||
{
|
||||
arg_combox::arg_combox(combox& wdg): widget(wdg)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user