Mixxx
|
00001 #if defined (__WINDOWS__) 00002 #include <windows.h> 00003 #include <Shellapi.h> 00004 #include <Shobjidl.h> 00005 #else 00006 #include <sys/types.h> 00007 #include <sys/stat.h> 00008 #include <dirent.h> 00009 #include <unistd.h> 00010 #include <errno.h> 00011 #endif 00012 00013 #include <QtGui> 00014 #include <QDirModel> 00015 #include <QStringList> 00016 #include <QFileInfo> 00017 #include <QDesktopServices> 00018 00019 #include "library/treeitem.h" 00020 #include "library/browse/foldertreemodel.h" 00021 #include "library/browse/browsefeature.h" 00022 00023 FolderTreeModel::FolderTreeModel(QObject *parent) 00024 : TreeItemModel(parent) { 00025 } 00026 00027 FolderTreeModel::~FolderTreeModel() { 00028 } 00029 00030 /* A tree model of the filesystem should be initialized lazy. 00031 * It will take the universe to iterate over all files over filesystem 00032 * hasChildren() returns true if a folder has subfolders although 00033 * we do not know the precise number of subfolders. 00034 * 00035 * Note that BrowseFeature inserts folder trees dynamically and rowCount() 00036 * is only called if necessary. 00037 */ 00038 bool FolderTreeModel::hasChildren( const QModelIndex & parent) const 00039 { 00040 00041 TreeItem *item = static_cast<TreeItem*>(parent.internalPointer()); 00042 /* Usually the child count is 0 becuase we do lazy initalization 00043 * However, for, buid-in items such as 'Quick Links' there exist 00044 * child items at init time 00045 */ 00046 if(item->dataPath().toString() == QUICK_LINK_NODE) 00047 return true; 00048 //Can only happen on Windows 00049 if(item->dataPath().toString() == DEVICE_NODE) 00050 return true; 00051 00052 //In all other cases the dataPath() points to a folder 00053 00054 QString folder = item->dataPath().toString(); 00055 00056 /* 00057 * The following code is too expensive, general and SLOW since 00058 * QDIR::EntryInfoList returns a full QFileInfolist 00059 * 00060 * 00061 * QDir dir(item->dataPath().toString()); 00062 * QFileInfoList all = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); 00063 * return (all.count() > 0); 00064 * 00065 * We can benefit from low-level filesystem APIs, i.e., 00066 * Windows API or SystemCalls 00067 */ 00068 00069 #if defined (__WINDOWS__) 00070 folder.replace("/","\\"); 00071 00072 //quick subfolder test 00073 SHFILEINFOW sfi; 00074 SHGetFileInfo((LPCWSTR) folder.constData(), NULL, &sfi, sizeof(sfi), SHGFI_ATTRIBUTES); 00075 return (sfi.dwAttributes & SFGAO_HASSUBFOLDER); 00076 #else 00077 // For OS X and Linux 00078 // http://stackoverflow.com/questions/2579948/checking-if-subfolders-exist-linux 00079 00080 std::string dot("."), dotdot(".."); 00081 bool found_subdir = false; 00082 QByteArray ba = folder.toLocal8Bit(); 00083 DIR *directory = opendir(ba); 00084 00085 if (directory == NULL){ 00086 return false; 00087 } 00088 struct dirent *entry; 00089 while (!found_subdir && ((entry = readdir(directory)) != NULL)) { 00090 if (entry->d_name != dot && entry->d_name != dotdot) 00091 { 00092 found_subdir = (entry->d_type == DT_DIR || entry->d_type == DT_LNK); 00093 //qDebug() << "Subfolder of " << folder << " : " << entry->d_name << "type :" << entry->d_type; 00094 00095 } 00096 } 00097 closedir(directory); 00098 return found_subdir; 00099 00100 #endif 00101 00102 } 00103