
Similar to stored queries, files of the virtual directory type behave like directories -- i.e. they open in a list-mode Tracker window and show up as an item with submenu in navigation menus. The file itself is a plain text file in driver settings format. It can have an arbitrary number of "directory" entries, which specify the paths of (actual) directories for which the virtual directory provides a merged view. The view will not show duplicate entries. For non-directory entries the first one encountered (according to the order the directory paths are specified in the file) will be shown. A subdirectory entry will again behave like a virtual directory. The support in Tracker isn't perfect yet. I'm afraid major refactoring would be necessary to get it there. The virtual directory file type uses a differently colored version of the folder icon. Alternatives welcome.
118 lines
2.9 KiB
C++
118 lines
2.9 KiB
C++
/*
|
|
* Copyright 2013, Haiku, Inc.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Ingo Weinhold, ingo_weinhold@gmx.de
|
|
*/
|
|
#ifndef VIRTUAL_DIRECTORY_MANAGER_H
|
|
#define VIRTUAL_DIRECTORY_MANAGER_H
|
|
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <map>
|
|
|
|
#include <Locker.h>
|
|
#include <Node.h>
|
|
|
|
|
|
class BStringList;
|
|
|
|
|
|
namespace BPrivate {
|
|
|
|
|
|
class Model;
|
|
|
|
|
|
class VirtualDirectoryManager {
|
|
public:
|
|
static VirtualDirectoryManager* Instance();
|
|
|
|
bool Lock() { return fLock.Lock(); }
|
|
void Unlock() { fLock.Unlock(); }
|
|
|
|
status_t ResolveDirectoryPaths(
|
|
const node_ref& definitionFileNodeRef,
|
|
const entry_ref& definitionFileEntryRef,
|
|
BStringList& _directoryPaths,
|
|
node_ref* _definitionFileNodeRef = NULL,
|
|
entry_ref* _definitionFileEntryRef = NULL);
|
|
|
|
bool GetDefinitionFileChangeTime(
|
|
const node_ref& definitionFileRef,
|
|
bigtime_t& _time) const;
|
|
|
|
bool GetRootDefinitionFile(
|
|
const node_ref& definitionFileRef,
|
|
node_ref& _rootDefinitionFileRef);
|
|
bool GetSubDirectoryDefinitionFile(
|
|
const node_ref& baseDefinitionRef,
|
|
const char* subDirName,
|
|
entry_ref& _entryRef, node_ref& _nodeRef);
|
|
bool GetParentDirectoryDefinitionFile(
|
|
const node_ref& subDirDefinitionRef,
|
|
entry_ref& _entryRef, node_ref& _nodeRef);
|
|
|
|
status_t TranslateDirectoryEntry(
|
|
const node_ref& definitionFileRef,
|
|
dirent* buffer);
|
|
status_t TranslateDirectoryEntry(
|
|
const node_ref& definitionFileRef,
|
|
entry_ref& entryRef, node_ref& _nodeRef);
|
|
|
|
bool DefinitionFileChanged(
|
|
const node_ref& definitionFileRef);
|
|
// returns whether the directory still
|
|
// exists
|
|
status_t DirectoryRemoved(
|
|
const node_ref& definitionFileRef);
|
|
|
|
static bool GetEntry(const BStringList& directoryPaths,
|
|
const char* name, entry_ref* _ref,
|
|
struct stat* _st);
|
|
|
|
private:
|
|
class Info;
|
|
class RootInfo;
|
|
|
|
typedef std::map<node_ref, Info*> NodeRefInfoMap;
|
|
|
|
private:
|
|
VirtualDirectoryManager();
|
|
|
|
Info* _InfoForNodeRef(const node_ref& nodeRef) const;
|
|
|
|
bool _AddInfo(Info* info);
|
|
void _RemoveInfo(Info* info);
|
|
|
|
void _UpdateTree(RootInfo* root);
|
|
void _UpdateTree(Info* info);
|
|
|
|
void _RemoveDirectory(Info* info);
|
|
|
|
status_t _ResolveUnknownDefinitionFile(
|
|
const node_ref& definitionFileNodeRef,
|
|
const entry_ref& definitionFileEntryRef,
|
|
Info*& _info);
|
|
status_t _CreateRootInfo(
|
|
const node_ref& definitionFileNodeRef,
|
|
const entry_ref& definitionFileEntryRef,
|
|
Info*& _info);
|
|
status_t _ReadSubDirectoryDefinitionFileInfo(
|
|
const entry_ref& entryRef,
|
|
entry_ref& _rootDefinitionFileEntryRef,
|
|
BString& _subDirPath);
|
|
|
|
private:
|
|
BLocker fLock;
|
|
NodeRefInfoMap fInfos;
|
|
};
|
|
|
|
|
|
} // namespace BPrivate
|
|
|
|
|
|
#endif // VIRTUAL_DIRECTORY_MANAGER_H
|