diff --git a/bin/assets/ui/breeze.css b/bin/assets/ui/breeze.css index 71541faf4..4c09b1e89 100644 --- a/bin/assets/ui/breeze.css +++ b/bin/assets/ui/breeze.css @@ -775,7 +775,7 @@ TreeView { } TreeView > ScrollBar { - background-color: var(--back); + background-color: var(--list-back); } .appbackground { diff --git a/include/eepp/system/fileinfo.hpp b/include/eepp/system/fileinfo.hpp new file mode 100644 index 000000000..e02a30a64 --- /dev/null +++ b/include/eepp/system/fileinfo.hpp @@ -0,0 +1,78 @@ +#ifndef EE_SYSTEM_FILEINFO_HPP +#define EE_SYSTEM_FILEINFO_HPP + +#include +#include +#include +#include + +namespace EE { namespace System { + +class EE_API FileInfo { + public: + static bool exists( const std::string& filePath ); + + static bool isLink( const std::string& filePath ); + + static bool inodeSupported(); + + FileInfo(); + + FileInfo( const std::string& filepath ); + + FileInfo( const std::string& filepath, bool linkInfo ); + + bool operator==( const FileInfo& Other ) const; + + bool operator!=( const FileInfo& Other ) const; + + FileInfo& operator=( const FileInfo& Other ); + + bool isDirectory() const; + + bool isRegularFile() const; + + bool isReadable() const; + + bool sameInode( const FileInfo& Other ) const; + + bool isLink() const; + + std::string linksTo(); + + bool exists(); + + void getInfo(); + + void getRealInfo(); + + const std::string& getFilepath() const; + + const Uint64& getModificationTime() const; + + const Uint64& getSize() const; + + const Uint32& getOwnerId() const; + + const Uint32& getGroupId() const; + + const Uint32& getPermissions() const; + + const Uint64& getInode() const; + + protected: + std::string mFilepath; + Uint64 mModificationTime{0}; + Uint64 mSize{0}; + Uint32 mOwnerId{0}; + Uint32 mGroupId{0}; + Uint32 mPermissions{0}; + Uint64 mInode{0}; +}; + +typedef std::map FileInfoMap; +typedef std::vector FileInfoList; + +}} // namespace EE::System + +#endif diff --git a/include/eepp/system/filesystem.hpp b/include/eepp/system/filesystem.hpp index 400aeaa45..2e60dfe00 100644 --- a/include/eepp/system/filesystem.hpp +++ b/include/eepp/system/filesystem.hpp @@ -72,7 +72,7 @@ class EE_API FileSystem { static bool fileCanWrite( const std::string& filepath ); /** If the directory path not end with a slash, it will add it. */ - static void dirPathAddSlashAtEnd( std::string& path ); + static void dirAddSlashAtEnd( std::string& path ); /** If the directory path ends with a slash, it will remove it. */ static void dirRemoveSlashAtEnd( std::string& dir ); diff --git a/projects/linux/ee.files b/projects/linux/ee.files index e5b2e32a5..9a7ae73fb 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -234,6 +234,7 @@ ../../include/eepp/system/condition.hpp ../../include/eepp/system/container.hpp ../../include/eepp/system/directorypack.hpp +../../include/eepp/system/fileinfo.hpp ../../include/eepp/system/filesystem.hpp ../../include/eepp/system.hpp ../../include/eepp/system/functionstring.hpp @@ -715,6 +716,7 @@ ../../src/eepp/system/compression.cpp ../../src/eepp/system/condition.cpp ../../src/eepp/system/directorypack.cpp +../../src/eepp/system/fileinfo.cpp ../../src/eepp/system/filesystem.cpp ../../src/eepp/system/functionstring.cpp ../../src/eepp/system/inifile.cpp @@ -767,6 +769,7 @@ ../../src/eepp/system/translator.cpp ../../src/eepp/system/virtualfilesystem.cpp ../../src/eepp/system/zip.cpp +../../src/eepp/ui/abstract/filesystemmodel.hpp ../../src/eepp/ui/abstract/model.cpp ../../src/eepp/ui/abstract/modelselection.cpp ../../src/eepp/ui/abstract/uiabstracttableview.cpp diff --git a/src/eepp/graphics/fontbmfont.cpp b/src/eepp/graphics/fontbmfont.cpp index 649c346a8..75b47ca6d 100644 --- a/src/eepp/graphics/fontbmfont.cpp +++ b/src/eepp/graphics/fontbmfont.cpp @@ -100,7 +100,7 @@ bool FontBMFont::loadFromStream( IOStream& stream ) { mFontSize = fontSize; - FileSystem::dirPathAddSlashAtEnd( mFilePath ); + FileSystem::dirAddSlashAtEnd( mFilePath ); { TextureFactory* TF = TextureFactory::instance(); diff --git a/src/eepp/graphics/textureatlasloader.cpp b/src/eepp/graphics/textureatlasloader.cpp index 8a7fc9905..e46e6210d 100644 --- a/src/eepp/graphics/textureatlasloader.cpp +++ b/src/eepp/graphics/textureatlasloader.cpp @@ -397,7 +397,7 @@ bool TextureAtlasLoader::updateTextureAtlas( std::string TextureAtlasPath, std:: Int32 NeedUpdate = ATLAS_IS_UPDATED; Float pixelDensity = 1; - FileSystem::dirPathAddSlashAtEnd( ImagesPath ); + FileSystem::dirAddSlashAtEnd( ImagesPath ); Uint32 z; diff --git a/src/eepp/graphics/texturepacker.cpp b/src/eepp/graphics/texturepacker.cpp index b8452111e..2f81e4cbc 100644 --- a/src/eepp/graphics/texturepacker.cpp +++ b/src/eepp/graphics/texturepacker.cpp @@ -435,7 +435,7 @@ void TexturePacker::createChild() { bool TexturePacker::addTexturesPath( std::string TexturesPath ) { if ( FileSystem::isDirectory( TexturesPath ) ) { - FileSystem::dirPathAddSlashAtEnd( TexturesPath ); + FileSystem::dirAddSlashAtEnd( TexturesPath ); std::vector files = FileSystem::filesGetInPath( TexturesPath ); std::sort( files.begin(), files.end() ); diff --git a/src/eepp/system/fileinfo.cpp b/src/eepp/system/fileinfo.cpp new file mode 100644 index 000000000..fbea92384 --- /dev/null +++ b/src/eepp/system/fileinfo.cpp @@ -0,0 +1,250 @@ +#include +#include +#include + +#ifndef _DARWIN_FEATURE_64_BIT_INODE +#define _DARWIN_FEATURE_64_BIT_INODE +#endif + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 +#endif + +#include + +#include +#include + +#ifdef EE_COMPILER_MSVC +#ifndef S_ISDIR +#define S_ISDIR( f ) ( (f)&_S_IFDIR ) +#endif + +#ifndef S_ISREG +#define S_ISREG( f ) ( (f)&_S_IFREG ) +#endif + +#ifndef S_ISRDBL +#define S_ISRDBL( f ) ( (f)&_S_IREAD ) +#endif +#else +#include + +#ifndef S_ISRDBL +#define S_ISRDBL( f ) ( (f)&S_IRUSR ) +#endif +#endif + +namespace EE { namespace System { + +bool FileInfo::exists( const std::string& filePath ) { + FileInfo fi( filePath ); + return fi.exists(); +} + +bool FileInfo::isLink( const std::string& filePath ) { + FileInfo fi( filePath, true ); + return fi.isLink(); +} + +bool FileInfo::inodeSupported() { +#if EE_PLATFORM != EE_PLATFORM_WIN + return true; +#else + return false; +#endif +} + +FileInfo::FileInfo() : + mModificationTime( 0 ), mOwnerId( 0 ), mGroupId( 0 ), mPermissions( 0 ), mInode( 0 ) {} + +FileInfo::FileInfo( const std::string& filepath ) : + mFilepath( filepath ), + mModificationTime( 0 ), + mOwnerId( 0 ), + mGroupId( 0 ), + mPermissions( 0 ), + mInode( 0 ) { + getInfo(); +} + +FileInfo::FileInfo( const std::string& filepath, bool linkInfo ) : + mFilepath( filepath ), + mModificationTime( 0 ), + mOwnerId( 0 ), + mGroupId( 0 ), + mPermissions( 0 ), + mInode( 0 ) { + if ( linkInfo ) { + getRealInfo(); + } else { + getInfo(); + } +} + +void FileInfo::getInfo() { +#if EE_PLATFORM == EE_PLATFORM_WIN + if ( mFilepath.size() == 3 && mFilepath[1] == ':' && mFilepath[2] == FileSystem::getOSSlash() ) { + mFilepath += FileSystem::getOSSlash(); + } +#endif + + /// Why i'm doing this? stat in mingw32 doesn't work for directories if the dir path ends with a + /// path slash + FileSystem::dirRemoveSlashAtEnd( mFilepath ); + +#if EE_PLATFORM != EE_PLATFORM_WIN + struct stat st; + int res = stat( mFilepath.c_str(), &st ); +#else + struct _stat st; + int res = _wstat( String::fromUtf8( mFilepath ).toWideString().c_str(), &st ); +#endif + + if ( 0 == res ) { + mModificationTime = st.st_mtime; + mSize = st.st_size; + mOwnerId = st.st_uid; + mGroupId = st.st_gid; + mPermissions = st.st_mode; + mInode = st.st_ino; + } + + FileSystem::dirAddSlashAtEnd( mFilepath ); +} + +void FileInfo::getRealInfo() { + FileSystem::dirRemoveSlashAtEnd( mFilepath ); + +#if EE_PLATFORM != EE_PLATFORM_WIN + struct stat st; + int res = lstat( mFilepath.c_str(), &st ); +#else + struct _stat st; + int res = _wstat( String::fromUtf8( mFilepath ).toWideString().c_str(), &st ); +#endif + + if ( 0 == res ) { + mModificationTime = st.st_mtime; + mSize = st.st_size; + mOwnerId = st.st_uid; + mGroupId = st.st_gid; + mPermissions = st.st_mode; + mInode = st.st_ino; + } + + FileSystem::dirAddSlashAtEnd( mFilepath ); +} + +const std::string& FileInfo::getFilepath() const { + return mFilepath; +} + +const Uint64& FileInfo::getModificationTime() const { + return mModificationTime; +} + +const Uint64& FileInfo::getSize() const { + return mSize; +} + +const Uint32& FileInfo::getOwnerId() const { + return mOwnerId; +} + +const Uint32& FileInfo::getGroupId() const { + return mGroupId; +} + +const Uint32& FileInfo::getPermissions() const { + return mPermissions; +} + +const Uint64& FileInfo::getInode() const { + return mInode; +} + +bool FileInfo::operator==( const FileInfo& Other ) const { + return ( mModificationTime == Other.mModificationTime && mSize == Other.mSize && + mOwnerId == Other.mOwnerId && mGroupId == Other.mGroupId && + mPermissions == Other.mPermissions && mInode == Other.mInode ); +} + +bool FileInfo::isDirectory() const { + return 0 != S_ISDIR( mPermissions ); +} + +bool FileInfo::isRegularFile() const { + return 0 != S_ISREG( mPermissions ); +} + +bool FileInfo::isReadable() const { +#if EE_PLATFORM != EE_PLATFORM_WIN + static bool isRoot = getuid() == 0; + return isRoot || 0 != S_ISRDBL( mPermissions ); +#else + return 0 != S_ISRDBL( mPermissions ); +#endif +} + +bool FileInfo::isLink() const { +#if EE_PLATFORM != EE_PLATFORM_WIN + return S_ISLNK( mPermissions ); +#else + return false; +#endif +} + +std::string FileInfo::linksTo() { +#if EE_PLATFORM != EE_PLATFORM_WIN + if ( isLink() ) { + char* ch = realpath( mFilepath.c_str(), NULL ); + + if ( NULL != ch ) { + std::string tstr( ch ); + + free( ch ); + + return tstr; + } + } +#endif + return std::string( "" ); +} + +bool FileInfo::exists() { + FileSystem::dirRemoveSlashAtEnd( mFilepath ); + +#if EE_PLATFORM != EE_PLATFORM_WIN + struct stat st; + int res = stat( mFilepath.c_str(), &st ); +#else + struct _stat st; + int res = _wstat( String::fromUtf8( mFilepath ).toWideString().c_str(), &st ); +#endif + + FileSystem::dirAddSlashAtEnd( mFilepath ); + + return 0 == res; +} + +FileInfo& FileInfo::operator=( const FileInfo& Other ) { + this->mFilepath = Other.mFilepath; + this->mSize = Other.mSize; + this->mModificationTime = Other.mModificationTime; + this->mGroupId = Other.mGroupId; + this->mOwnerId = Other.mOwnerId; + this->mPermissions = Other.mPermissions; + this->mInode = Other.mInode; + return *this; +} + +bool FileInfo::sameInode( const FileInfo& Other ) const { + return inodeSupported() && mInode == Other.mInode; +} + +bool FileInfo::operator!=( const FileInfo& Other ) const { + return !( *this == Other ); +} + +}} // namespace EE::System diff --git a/src/eepp/system/filesystem.cpp b/src/eepp/system/filesystem.cpp index 0f79aa16a..a7927c07b 100644 --- a/src/eepp/system/filesystem.cpp +++ b/src/eepp/system/filesystem.cpp @@ -207,7 +207,7 @@ bool FileSystem::fileCanWrite( const std::string& filepath ) { #endif } -void FileSystem::dirPathAddSlashAtEnd( std::string& path ) { +void FileSystem::dirAddSlashAtEnd( std::string& path ) { if ( path.size() && path[path.size() - 1] != '/' && path[path.size() - 1] != '\\' ) path += getOSSlash(); } @@ -236,13 +236,13 @@ std::string FileSystem::removeLastFolderFromPath( std::string path ) { } if ( sstr.size() ) { - dirPathAddSlashAtEnd( sstr ); + dirAddSlashAtEnd( sstr ); return sstr; } } - dirPathAddSlashAtEnd( path ); + dirAddSlashAtEnd( path ); return path; } @@ -648,7 +648,7 @@ std::string FileSystem::fileGetNumberedFileNameFromPath( std::string directoryPa std::string fileNumName; if ( FileSystem::isDirectory( directoryPath ) ) { - dirPathAddSlashAtEnd( directoryPath ); + dirAddSlashAtEnd( directoryPath ); while ( fileNum < 10000 ) { fileNumName = String::format( diff --git a/src/eepp/system/sys.cpp b/src/eepp/system/sys.cpp index f73a33990..b3e1e371d 100644 --- a/src/eepp/system/sys.cpp +++ b/src/eepp/system/sys.cpp @@ -701,7 +701,7 @@ std::string Sys::getTempPath() { std::string rpath( path ); - FileSystem::dirPathAddSlashAtEnd( rpath ); + FileSystem::dirAddSlashAtEnd( rpath ); return rpath; } diff --git a/src/eepp/system/translator.cpp b/src/eepp/system/translator.cpp index c807819af..4bda3deef 100644 --- a/src/eepp/system/translator.cpp +++ b/src/eepp/system/translator.cpp @@ -15,7 +15,7 @@ Translator::Translator( const std::locale& locale ) : mDefaultLanguage( "en" ) { } void Translator::loadFromDirectory( std::string dirPath, std::string ext ) { - FileSystem::dirPathAddSlashAtEnd( dirPath ); + FileSystem::dirAddSlashAtEnd( dirPath ); if ( FileSystem::isDirectory( dirPath ) ) { std::vector files = FileSystem::filesGetInPath( dirPath, true, true ); diff --git a/src/eepp/ui/tools/textureatlasnew.cpp b/src/eepp/ui/tools/textureatlasnew.cpp index ab51c9076..27815cec1 100644 --- a/src/eepp/ui/tools/textureatlasnew.cpp +++ b/src/eepp/ui/tools/textureatlasnew.cpp @@ -221,11 +221,11 @@ void TextureAtlasNew::onSelectFolder( const Event* Event ) { UIFileDialog* CDL = Event->getNode()->asType(); UIMessageBox* MsgBox; std::string FPath( CDL->getFullPath() ); - FileSystem::dirPathAddSlashAtEnd( FPath ); + FileSystem::dirAddSlashAtEnd( FPath ); if ( !FileSystem::isDirectory( FPath ) ) { FPath = CDL->getCurPath(); - FileSystem::dirPathAddSlashAtEnd( FPath ); + FileSystem::dirAddSlashAtEnd( FPath ); } if ( FileSystem::isDirectory( FPath ) ) { diff --git a/src/eepp/ui/uifiledialog.cpp b/src/eepp/ui/uifiledialog.cpp index 3bbae509a..dbd1b7372 100644 --- a/src/eepp/ui/uifiledialog.cpp +++ b/src/eepp/ui/uifiledialog.cpp @@ -68,7 +68,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa ->setParent( hLayout ) ->setEnabled( false ); - FileSystem::dirPathAddSlashAtEnd( mCurPath ); + FileSystem::dirAddSlashAtEnd( mCurPath ); mPath = UITextInput::New(); mPath->setText( mCurPath ) @@ -198,7 +198,7 @@ void UIFileDialog::setTheme( UITheme* Theme ) { } void UIFileDialog::refreshFolder() { - FileSystem::dirPathAddSlashAtEnd( mCurPath ); + FileSystem::dirAddSlashAtEnd( mCurPath ); std::vector flist = FileSystem::filesGetInPath( String( mCurPath ) ); std::vector files; std::vector folders; @@ -263,7 +263,7 @@ void UIFileDialog::updateClickStep() { void UIFileDialog::setCurPath( const std::string& path ) { mCurPath = path; - FileSystem::dirPathAddSlashAtEnd( mCurPath ); + FileSystem::dirAddSlashAtEnd( mCurPath ); mPath->setText( mCurPath ); refreshFolder(); } @@ -437,7 +437,7 @@ void UIFileDialog::setAllowFolderSelect( const bool& allowFolderSelect ) { std::string UIFileDialog::getFullPath() { std::string tPath = mCurPath; - FileSystem::dirPathAddSlashAtEnd( tPath ); + FileSystem::dirAddSlashAtEnd( tPath ); tPath += getCurFile(); @@ -447,7 +447,7 @@ std::string UIFileDialog::getFullPath() { std::string UIFileDialog::getTempFullPath() { std::string tPath = mCurPath; - FileSystem::dirPathAddSlashAtEnd( tPath ); + FileSystem::dirAddSlashAtEnd( tPath ); tPath += mList->getItemSelectedText().toUtf8(); diff --git a/src/eepp/ui/uitheme.cpp b/src/eepp/ui/uitheme.cpp index 10c06c5b0..643819787 100644 --- a/src/eepp/ui/uitheme.cpp +++ b/src/eepp/ui/uitheme.cpp @@ -147,7 +147,7 @@ UITheme* UITheme::loadFromDirectroy( UITheme* tTheme, const std::string& Path, std::string RPath( Path ); - FileSystem::dirPathAddSlashAtEnd( RPath ); + FileSystem::dirAddSlashAtEnd( RPath ); if ( !FileSystem::isDirectory( RPath ) ) return NULL; diff --git a/src/examples/http_request/http_request.cpp b/src/examples/http_request/http_request.cpp index bc2429f77..057646859 100644 --- a/src/examples/http_request/http_request.cpp +++ b/src/examples/http_request/http_request.cpp @@ -233,7 +233,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { // If output path is a directory guess a file name if ( FileSystem::isDirectory( path ) ) { - FileSystem::dirPathAddSlashAtEnd( path ); + FileSystem::dirAddSlashAtEnd( path ); std::string lastPathSegment = uri.getLastPathSegment(); diff --git a/src/tools/codeeditor/codeeditor.cpp b/src/tools/codeeditor/codeeditor.cpp index eb2d3362d..164777c51 100644 --- a/src/tools/codeeditor/codeeditor.cpp +++ b/src/tools/codeeditor/codeeditor.cpp @@ -241,7 +241,7 @@ void App::loadConfig() { mConfigPath = Sys::getConfigPath( "ecode" ); if ( !FileSystem::fileExists( mConfigPath ) ) FileSystem::makeDir( mConfigPath ); - FileSystem::dirPathAddSlashAtEnd( mConfigPath ); + FileSystem::dirAddSlashAtEnd( mConfigPath ); mKeybindingsPath = mConfigPath + "keybindings.cfg"; mIni.loadFromFile( mConfigPath + "config.cfg" ); mIniState.loadFromFile( mConfigPath + "state.cfg" ); diff --git a/src/tools/texturepacker/texturepacker.cpp b/src/tools/texturepacker/texturepacker.cpp index 8b2420d8c..0323cb11b 100644 --- a/src/tools/texturepacker/texturepacker.cpp +++ b/src/tools/texturepacker/texturepacker.cpp @@ -108,7 +108,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { } std::string texturesPathSafe( texturesPath.Get() ); - FileSystem::dirPathAddSlashAtEnd( texturesPathSafe ); + FileSystem::dirAddSlashAtEnd( texturesPathSafe ); if ( !FileSystem::isDirectory( texturesPathSafe ) && !hasImages ) { std::cout << "textures-path is invalid."; return EXIT_FAILURE; diff --git a/src/tools/uieditor/uieditor.cpp b/src/tools/uieditor/uieditor.cpp index d18fab5a8..f52fc23e2 100644 --- a/src/tools/uieditor/uieditor.cpp +++ b/src/tools/uieditor/uieditor.cpp @@ -86,7 +86,7 @@ void loadConfig() { std::string path( Sys::getConfigPath( "eepp-uieditor" ) ); if ( !FileSystem::fileExists( path ) ) FileSystem::makeDir( path ); - FileSystem::dirPathAddSlashAtEnd( path ); + FileSystem::dirAddSlashAtEnd( path ); path += "config.ini"; ini.loadFromFile( path ); std::string recent = ini.getValue( "UIEDITOR", "recentprojects", "" ); @@ -175,7 +175,7 @@ static void loadFont( std::string path ) { static void loadImagesFromFolder( std::string folderPath ) { std::vector files = FileSystem::filesGetInPath( folderPath ); - FileSystem::dirPathAddSlashAtEnd( folderPath ); + FileSystem::dirAddSlashAtEnd( folderPath ); for ( auto it = files.begin(); it != files.end(); ++it ) { if ( Image::isImageExtension( *it ) ) { @@ -187,7 +187,7 @@ static void loadImagesFromFolder( std::string folderPath ) { static void loadFontsFromFolder( std::string folderPath ) { std::vector files = FileSystem::filesGetInPath( folderPath ); - FileSystem::dirPathAddSlashAtEnd( folderPath ); + FileSystem::dirAddSlashAtEnd( folderPath ); for ( auto it = files.begin(); it != files.end(); ++it ) { if ( isFont( *it ) ) { @@ -199,7 +199,7 @@ static void loadFontsFromFolder( std::string folderPath ) { static void loadLayoutsFromFolder( std::string folderPath ) { std::vector files = FileSystem::filesGetInPath( folderPath ); - FileSystem::dirPathAddSlashAtEnd( folderPath ); + FileSystem::dirAddSlashAtEnd( folderPath ); for ( auto it = files.begin(); it != files.end(); ++it ) { if ( isXML( *it ) ) {