Open Tracker License
Terms and Conditions
Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice applies to all licensees
and shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Be Incorporated shall not be
used in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from Be Incorporated.
Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
of Be Incorporated in the United States and other countries. Other brand product
names are registered trademarks or trademarks of their respective holders.
All rights reserved.
*/
#ifndef _NU_MODEL_H
#define _NU_MODEL_H
#include <AppFileInfo.h>
#include <Debug.h>
#include <Mime.h>
#include <StorageDefs.h>
#include <String.h>
#include "IconCache.h"
#include "ObjectList.h"
class BPath;
class BHandler;
class BEntry;
class BQuery;
#if __GNUC__ && __GNUC__ < 3
typedef struct std::stat StatStruct;
#else
typedef struct stat StatStruct;
#endif
namespace BPrivate {
enum {
kDoesNotSupportType,
kSuperhandlerModel,
kModelSupportsSupertype,
kModelSupportsType,
kModelSupportsFile
};
class Model {
public:
Model();
Model(const Model& other);
Model(const BEntry* entry, bool open = false, bool writable = false);
Model(const entry_ref*, bool traverse = false, bool open = false,
bool writable = false);
Model(const node_ref* dirNode, const node_ref* node, const char* name,
bool open = false, bool writable = false);
~Model();
Model& operator=(const Model&);
status_t InitCheck() const;
status_t SetTo(const BEntry*, bool open = false,
bool writable = false);
status_t SetTo(const entry_ref*, bool traverse = false,
bool open = false, bool writable = false);
status_t SetTo(const node_ref* dirNode, const node_ref* node,
const char* name, bool open = false, bool writable = false);
int CompareFolderNamesFirst(const Model* compare) const;
status_t OpenNode(bool writable = false);
void CloseNode();
bool IsNodeOpen() const;
bool IsNodeOpenForWriting() const;
status_t UpdateStatAndOpenNode(bool writable = false);
const char* Name() const;
const entry_ref* EntryRef() const;
const node_ref* NodeRef() const;
const StatStruct* StatBuf() const;
BNode* Node() const;
void GetPath(BPath*) const;
void GetEntry(BEntry*) const;
const char* MimeType() const;
const char* PreferredAppSignature() const;
void SetPreferredAppSignature(const char*);
bool IsContainer() const;
bool IsDesktop() const;
bool IsDirectory() const;
bool IsFile() const;
bool IsQuery() const;
bool IsQueryTemplate() const;
bool IsExecutable() const;
bool IsPrintersDir() const;
bool IsSymLink() const;
bool InRoot() const;
bool IsRoot() const;
bool InTrash() const;
bool IsTrash() const;
bool IsVolume() const;
bool IsVirtualDirectory() const;
IconSource IconFrom() const;
void SetIconFrom(IconSource);
void ResetIconFrom();
const Model* ResolveIfLink() const;
Model* ResolveIfLink();
Model* LinkTo() const;
void SetLinkTo(Model*);
status_t GetLongVersionString(BString &, version_kind);
status_t GetVersionString(BString &, version_kind);
status_t AttrAsString(BString &, int64* value,
const char* attributeName, uint32 attributeType);
void UpdateEntryRef(const node_ref* dirRef, const char* name);
bool AttrChanged(const char* attrName);
bool StatChanged();
status_t WatchVolumeAndMountPoint(uint32, BHandler*);
bool IsDropTarget(const Model* forDocument = 0,
bool traverse = false) const;
bool IsDropTargetForList(const BStringList* list) const;
#if DEBUG
void PrintToStream(int32 level = 1, bool deep = false);
void TrackIconSource(icon_size);
#endif
bool IsSuperHandler() const;
int32 SupportsMimeType(const char* type,
const BStringList* list, bool exactReason = false) const;
ssize_t WriteAttr(const char* attr, type_code type, off_t,
const void* buffer, size_t );
ssize_t WriteAttrKillForeign(const char* attr,
const char* foreignAttr, type_code type, off_t,
const void* buffer, size_t);
bool Mimeset(bool force);
bool HasLocalizedName() const;
private:
status_t OpenNodeCommon(bool writable);
void SetupBaseType();
void FinishSettingUpType();
bool CheckAppIconHint() const;
void DeletePreferredAppVolumeNameLinkTo();
void CacheLocalizedName();
status_t FetchOneQuery(const BQuery*, BHandler* target,
BObjectList<BQuery>*, BVolume*);
enum CanHandleResult {
kCanHandle,
kCannotHandle,
kNeedToCheckType
};
CanHandleResult CanHandleDrops() const;
enum NodeType {
kPlainNode,
kExecutableNode,
kDirectoryNode,
kLinkNode,
kQueryNode,
kQueryTemplateNode,
kVolumeNode,
kRootNode,
kTrashNode,
kDesktopNode,
kVirtualDirectoryNode,
kUnknownNode
};
entry_ref fEntryRef;
StatStruct fStatBuf;
BString fMimeType;
union {
char* fPreferredAppName;
char* fVolumeName;
Model* fLinkTo;
};
uint8 fBaseType;
uint8 fIconFrom;
bool fWritable;
BNode* fNode;
status_t fStatus;
BString fLocalizedName;
bool fHasLocalizedName;
bool fLocalizedNameIsCached;
};
class ModelNodeLazyOpener {
public:
ModelNodeLazyOpener(Model* model, bool writable = false,
bool openLater = true);
~ModelNodeLazyOpener();
bool IsOpen() const;
bool IsOpenForWriting() const;
bool IsOpen(bool forWriting) const;
Model* TargetModel() const;
status_t OpenNode(bool writable = false);
private:
Model* fModel;
bool fWasOpen;
bool fWasOpenForWriting;
};
class BModelOpener : public ModelNodeLazyOpener {
public:
BModelOpener(Model* model)
: ModelNodeLazyOpener(model, false, false)
{
}
};
class BModelWriteOpener : public ModelNodeLazyOpener {
public:
BModelWriteOpener(Model* model)
: ModelNodeLazyOpener(model, true, false)
{
}
};
#if DEBUG
#endif
#ifdef CHECK_OPEN_MODEL_LEAKS
void DumpOpenModels(bool extensive);
void InitOpenModelDumping();
#endif
inline const char*
Model::MimeType() const
{
return fMimeType.String();
}
inline const entry_ref*
Model::EntryRef() const
{
return &fEntryRef;
}
inline const node_ref*
Model::NodeRef() const
{
return (node_ref*)&fStatBuf;
}
inline BNode*
Model::Node() const
{
return fNode;
}
inline const StatStruct*
Model::StatBuf() const
{
return &fStatBuf;
}
inline IconSource
Model::IconFrom() const
{
return (IconSource)fIconFrom;
}
inline void
Model::SetIconFrom(IconSource from)
{
fIconFrom = from;
}
inline Model*
Model::LinkTo() const
{
ASSERT(IsSymLink());
return fLinkTo;
}
inline bool
Model::IsContainer() const
{
return IsQuery() || IsDirectory() || IsVirtualDirectory();
}
inline bool
Model::IsDesktop() const
{
return fBaseType == kDesktopNode;
}
inline bool
Model::IsDirectory() const
{
switch (fBaseType) {
case kDirectoryNode:
case kVolumeNode:
case kRootNode:
case kTrashNode:
case kDesktopNode:
return true;
}
return false;
}
inline bool
Model::IsFile() const
{
switch (fBaseType) {
case kPlainNode:
case kQueryNode:
case kQueryTemplateNode:
case kExecutableNode:
case kVirtualDirectoryNode:
return true;
}
return false;
}
inline bool
Model::IsExecutable() const
{
return fBaseType == kExecutableNode;
}
inline bool
Model::IsQuery() const
{
return fBaseType == kQueryNode;
}
inline bool
Model::IsQueryTemplate() const
{
return fBaseType == kQueryTemplateNode;
}
inline bool
Model::IsSymLink() const
{
return fBaseType == kLinkNode;
}
inline bool
Model::IsRoot() const
{
return fBaseType == kRootNode;
}
inline bool
Model::IsTrash() const
{
return fBaseType == kTrashNode;
}
inline bool
Model::IsVirtualDirectory() const
{
return fBaseType == kVirtualDirectoryNode;
}
inline bool
Model::IsVolume() const
{
return fBaseType == kVolumeNode;
}
inline bool
Model::HasLocalizedName() const
{
return fHasLocalizedName;
}
inline
ModelNodeLazyOpener::ModelNodeLazyOpener(Model* model, bool writable,
bool openLater)
:
fModel(model),
fWasOpen(model->IsNodeOpen()),
fWasOpenForWriting(model->IsNodeOpenForWriting())
{
if (!openLater)
OpenNode(writable);
}
inline
ModelNodeLazyOpener::~ModelNodeLazyOpener()
{
if (!fModel->IsNodeOpen())
return;
if (!fWasOpen)
fModel->CloseNode();
else if (!fWasOpenForWriting)
fModel->OpenNode();
}
inline bool
ModelNodeLazyOpener::IsOpen() const
{
return fModel->IsNodeOpen();
}
inline bool
ModelNodeLazyOpener::IsOpenForWriting() const
{
return fModel->IsNodeOpenForWriting();
}
inline bool
ModelNodeLazyOpener::IsOpen(bool forWriting) const
{
return forWriting ? fModel->IsNodeOpenForWriting() : fModel->IsNodeOpen();
}
inline Model*
ModelNodeLazyOpener::TargetModel() const
{
return fModel;
}
inline status_t
ModelNodeLazyOpener::OpenNode(bool writable)
{
if (writable) {
if (!fModel->IsNodeOpenForWriting())
return fModel->OpenNode(true);
} else if (!fModel->IsNodeOpen())
return fModel->OpenNode();
return B_OK;
}
}
#endif