Added libtracker.so to the repository and the build.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12772 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -114,6 +114,7 @@ SubInclude OBOS_TOP src kits screensaver ;
|
|||||||
SubInclude OBOS_TOP src kits support ;
|
SubInclude OBOS_TOP src kits support ;
|
||||||
SubInclude OBOS_TOP src kits textencoding ;
|
SubInclude OBOS_TOP src kits textencoding ;
|
||||||
SubInclude OBOS_TOP src kits translation ;
|
SubInclude OBOS_TOP src kits translation ;
|
||||||
|
SubInclude OBOS_TOP src kits tracker ;
|
||||||
SubInclude OBOS_TOP src kits device ;
|
SubInclude OBOS_TOP src kits device ;
|
||||||
SubInclude OBOS_TOP src kits game ;
|
SubInclude OBOS_TOP src kits game ;
|
||||||
SubInclude OBOS_TOP src kits network ;
|
SubInclude OBOS_TOP src kits network ;
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
Authors (mostly in chronological order):
|
||||||
|
|
||||||
|
Steve Horowitz,
|
||||||
|
Pavel Cisler,
|
||||||
|
Peter Potrebic,
|
||||||
|
Jeff Bush,
|
||||||
|
Robert Chinn,
|
||||||
|
Doug Fulton,
|
||||||
|
Kenny Carruthers,
|
||||||
|
Dianne Hackborn
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// These classes are required for binary compatibility under PPC, because
|
||||||
|
// libtracker used to export the symbols. Note that nothing actually
|
||||||
|
// uses them.
|
||||||
|
|
||||||
|
#if __POWERPC__
|
||||||
|
|
||||||
|
#include <Window.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
class AboutWindow : public BWindow {
|
||||||
|
public:
|
||||||
|
AboutWindow()
|
||||||
|
: BWindow(BRect(), "", B_UNTYPED_WINDOW, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~AboutWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RunAboutWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AboutView : public BView {
|
||||||
|
public:
|
||||||
|
AboutView(BRect frame, const char *name)
|
||||||
|
: BView(frame, name, 0, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~AboutView()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void AttachedToWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Pulse()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Draw(BRect)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void MouseDown(BPoint)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
void
|
||||||
|
do_not_call_me_i_am_only_here_to_get_these_symbols(AboutWindow **win, AboutView **view)
|
||||||
|
{
|
||||||
|
AboutWindow rwin;
|
||||||
|
AboutView rview(BRect(0, 0, 2, 3), "");
|
||||||
|
*win = &rwin;
|
||||||
|
*view = &rview;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,770 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Node.h>
|
||||||
|
#include "AttributeStream.h"
|
||||||
|
|
||||||
|
// ToDo:
|
||||||
|
// lazy Rewind from Drive, only if data is available
|
||||||
|
// BMessage node
|
||||||
|
// partial feeding (part, not the whole buffer)
|
||||||
|
|
||||||
|
AttributeInfo::AttributeInfo(const AttributeInfo &cloneThis)
|
||||||
|
: fName(cloneThis.fName),
|
||||||
|
fInfo(cloneThis.fInfo)
|
||||||
|
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeInfo::AttributeInfo(const char *name, attr_info info)
|
||||||
|
: fName(name),
|
||||||
|
fInfo(info)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AttributeInfo::AttributeInfo(const char *name, uint32 type, off_t size)
|
||||||
|
: fName(name)
|
||||||
|
{
|
||||||
|
fInfo.size = size;
|
||||||
|
fInfo.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
AttributeInfo::Name() const
|
||||||
|
{
|
||||||
|
return fName.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
AttributeInfo::Type() const
|
||||||
|
{
|
||||||
|
return fInfo.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeInfo::Size() const
|
||||||
|
{
|
||||||
|
return fInfo.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeInfo::SetTo(const AttributeInfo &attr)
|
||||||
|
{
|
||||||
|
fName = attr.fName;
|
||||||
|
fInfo = attr.fInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeInfo::SetTo(const char *name, attr_info info)
|
||||||
|
{
|
||||||
|
fName = name;
|
||||||
|
fInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeInfo::SetTo(const char *name, uint32 type, off_t size)
|
||||||
|
{
|
||||||
|
fName = name;
|
||||||
|
fInfo.type = type;
|
||||||
|
fInfo.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AttributeStreamNode::AttributeStreamNode()
|
||||||
|
: fReadFrom(NULL),
|
||||||
|
fWriteTo(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AttributeStreamNode::~AttributeStreamNode()
|
||||||
|
{
|
||||||
|
Detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeStreamNode &
|
||||||
|
AttributeStreamNode::operator<<(AttributeStreamNode &source)
|
||||||
|
{
|
||||||
|
fReadFrom = &source;
|
||||||
|
fReadFrom->fWriteTo = this;
|
||||||
|
if (fReadFrom->CanFeed())
|
||||||
|
fReadFrom->Start();
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeStreamNode::Rewind()
|
||||||
|
{
|
||||||
|
if (fReadFrom)
|
||||||
|
fReadFrom->Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeStreamFileNode::MakeEmpty()
|
||||||
|
{
|
||||||
|
TRESPASS();
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamNode::Contains(const char *name, uint32 type)
|
||||||
|
{
|
||||||
|
if (!fReadFrom)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return fReadFrom->Contains(name, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamNode::Read(const char *name, const char *foreignName, uint32 type,
|
||||||
|
off_t size, void *buffer, void (*swapFunc)(void *))
|
||||||
|
{
|
||||||
|
if (!fReadFrom)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return fReadFrom->Read(name, foreignName, type, size, buffer, swapFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamNode::Write(const char *name, const char *foreignName, uint32 type,
|
||||||
|
off_t size, const void *buffer)
|
||||||
|
{
|
||||||
|
if (!fWriteTo)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return fWriteTo->Write(name, foreignName, type, size, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AttributeStreamNode::Drive()
|
||||||
|
{
|
||||||
|
ASSERT(CanFeed());
|
||||||
|
if (!fReadFrom)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Rewind();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AttributeInfo *
|
||||||
|
AttributeStreamNode::Next()
|
||||||
|
{
|
||||||
|
if (fReadFrom)
|
||||||
|
return fReadFrom->Next();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
AttributeStreamNode::Get()
|
||||||
|
{
|
||||||
|
ASSERT(fReadFrom);
|
||||||
|
if (!fReadFrom)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return fReadFrom->Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AttributeStreamNode::Fill(char *buffer) const
|
||||||
|
{
|
||||||
|
ASSERT(fReadFrom);
|
||||||
|
return fReadFrom->Fill(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AttributeStreamNode::Start()
|
||||||
|
{
|
||||||
|
if (!fWriteTo)
|
||||||
|
// we are at the head of the stream, start drivin'
|
||||||
|
return Drive();
|
||||||
|
|
||||||
|
return fWriteTo->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeStreamNode::Detach()
|
||||||
|
{
|
||||||
|
AttributeStreamNode *tmpFrom = fReadFrom;
|
||||||
|
AttributeStreamNode *tmpTo = fWriteTo;
|
||||||
|
fReadFrom = NULL;
|
||||||
|
fWriteTo = NULL;
|
||||||
|
|
||||||
|
if (tmpFrom)
|
||||||
|
tmpFrom->Detach();
|
||||||
|
if (tmpTo)
|
||||||
|
tmpTo->Detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AttributeStreamFileNode::AttributeStreamFileNode()
|
||||||
|
: fNode(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AttributeStreamFileNode::AttributeStreamFileNode(BNode *node)
|
||||||
|
: fNode(node)
|
||||||
|
{
|
||||||
|
ASSERT(fNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeStreamFileNode::Rewind()
|
||||||
|
{
|
||||||
|
_inherited::Rewind();
|
||||||
|
fNode->RewindAttrs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeStreamFileNode::SetTo(BNode *node)
|
||||||
|
{
|
||||||
|
fNode = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamFileNode::Contains(const char *name, uint32 type)
|
||||||
|
{
|
||||||
|
ASSERT(fNode);
|
||||||
|
attr_info info;
|
||||||
|
if (fNode->GetAttrInfo(name, &info) != B_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (info.type != type)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return info.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamFileNode::Read(const char *name, const char *foreignName, uint32 type,
|
||||||
|
off_t size, void *buffer, void (*swapFunc)(void *))
|
||||||
|
{
|
||||||
|
if (name && fNode->ReadAttr(name, type, 0, buffer, (size_t)size) == size)
|
||||||
|
return size;
|
||||||
|
|
||||||
|
// didn't find the attribute under the native name, try the foreign name
|
||||||
|
if (foreignName && fNode->ReadAttr(foreignName, type, 0, buffer, (size_t)size) == size) {
|
||||||
|
// foreign attribute, swap the data
|
||||||
|
if (swapFunc)
|
||||||
|
(swapFunc)(buffer);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamFileNode::Write(const char *name, const char *foreignName, uint32 type,
|
||||||
|
off_t size, const void *buffer)
|
||||||
|
{
|
||||||
|
ASSERT(fNode);
|
||||||
|
ASSERT(dynamic_cast<BNode *>(fNode));
|
||||||
|
off_t result = fNode->WriteAttr(name, type, 0, buffer, (size_t)size);
|
||||||
|
if (result == size && foreignName)
|
||||||
|
// the write operation worked fine, remove the foreign attribute
|
||||||
|
// to not let stale data hang around
|
||||||
|
fNode->RemoveAttr(foreignName);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AttributeStreamFileNode::Drive()
|
||||||
|
{
|
||||||
|
ASSERT(fNode);
|
||||||
|
if (!_inherited::Drive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const AttributeInfo *attr;
|
||||||
|
while ((attr = fReadFrom->Next()) != 0) {
|
||||||
|
const char *data = fReadFrom->Get();
|
||||||
|
off_t result = fNode->WriteAttr(attr->Name(), attr->Type(), 0,
|
||||||
|
data, (size_t)attr->Size());
|
||||||
|
if (result < attr->Size())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
AttributeStreamFileNode::Get()
|
||||||
|
{
|
||||||
|
ASSERT(fNode);
|
||||||
|
TRESPASS();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AttributeStreamFileNode::Fill(char *buffer) const
|
||||||
|
{
|
||||||
|
ASSERT(fNode);
|
||||||
|
return fNode->ReadAttr(fCurrentAttr.Name(), fCurrentAttr.Type(), 0, buffer,
|
||||||
|
(size_t)fCurrentAttr.Size()) == (ssize_t)fCurrentAttr.Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const AttributeInfo *
|
||||||
|
AttributeStreamFileNode::Next()
|
||||||
|
{
|
||||||
|
ASSERT(fNode);
|
||||||
|
ASSERT(!fReadFrom);
|
||||||
|
char attrName[256];
|
||||||
|
if (fNode->GetNextAttrName(attrName) != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
attr_info info;
|
||||||
|
if (fNode->GetAttrInfo(attrName, &info) != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fCurrentAttr.SetTo(attrName, info);
|
||||||
|
return &fCurrentAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AttributeStreamMemoryNode::AttributeStreamMemoryNode()
|
||||||
|
: fAttributes(5, true),
|
||||||
|
fCurrentIndex(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeStreamMemoryNode::MakeEmpty()
|
||||||
|
{
|
||||||
|
fAttributes.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeStreamMemoryNode::Rewind()
|
||||||
|
{
|
||||||
|
_inherited::Rewind();
|
||||||
|
fCurrentIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
AttributeStreamMemoryNode::Find(const char *name, uint32 type) const
|
||||||
|
{
|
||||||
|
int32 count = fAttributes.CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++)
|
||||||
|
if (strcmp(fAttributes.ItemAt(index)->fAttr.Name(), name) == 0
|
||||||
|
&& fAttributes.ItemAt(index)->fAttr.Type() == type)
|
||||||
|
return index;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamMemoryNode::Contains(const char *name, uint32 type)
|
||||||
|
{
|
||||||
|
int32 index = Find(name, type);
|
||||||
|
if (index < 0)
|
||||||
|
return 0;
|
||||||
|
return fAttributes.ItemAt(index)->fAttr.Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamMemoryNode::Read(const char *name, const char *DEBUG_ONLY(foreignName),
|
||||||
|
uint32 type, off_t bufferSize, void *buffer, void (*DEBUG_ONLY(swapFunc))(void *))
|
||||||
|
{
|
||||||
|
ASSERT(!foreignName);
|
||||||
|
ASSERT(!swapFunc);
|
||||||
|
|
||||||
|
AttrNode *attrNode = NULL;
|
||||||
|
|
||||||
|
int32 index = Find(name, type);
|
||||||
|
if (index < 0) {
|
||||||
|
if (!fReadFrom)
|
||||||
|
return 0;
|
||||||
|
off_t size = fReadFrom->Contains(name, type);
|
||||||
|
if (!size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
attrNode = BufferingGet(name, type, size);
|
||||||
|
if (!attrNode)
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
attrNode = fAttributes.ItemAt(index);
|
||||||
|
|
||||||
|
if (attrNode->fAttr.Size() > bufferSize)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memcpy(buffer, attrNode->fData, (size_t)attrNode->fAttr.Size());
|
||||||
|
return attrNode->fAttr.Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamMemoryNode::Write(const char *name, const char *, uint32 type,
|
||||||
|
off_t size, const void *buffer)
|
||||||
|
{
|
||||||
|
char *newBuffer = new char[size];
|
||||||
|
memcpy(newBuffer, buffer, (size_t)size);
|
||||||
|
|
||||||
|
AttrNode *attrNode = new AttrNode(name, type, size, newBuffer);
|
||||||
|
fAttributes.AddItem(attrNode);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AttributeStreamMemoryNode::Drive()
|
||||||
|
{
|
||||||
|
if (!_inherited::Drive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (BufferingGet())
|
||||||
|
;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeStreamMemoryNode::AttrNode *
|
||||||
|
AttributeStreamMemoryNode::BufferingGet(const char *name, uint32 type, off_t size)
|
||||||
|
{
|
||||||
|
char *newBuffer = new char[size];
|
||||||
|
if (!fReadFrom->Fill(newBuffer)) {
|
||||||
|
delete newBuffer;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttrNode *attrNode = new AttrNode(name, type, size, newBuffer);
|
||||||
|
fAttributes.AddItem(attrNode);
|
||||||
|
return fAttributes.LastItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AttributeStreamMemoryNode::AttrNode *
|
||||||
|
AttributeStreamMemoryNode::BufferingGet()
|
||||||
|
{
|
||||||
|
if (!fReadFrom)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
const AttributeInfo *attr = fReadFrom->Next();
|
||||||
|
if (!attr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return BufferingGet(attr->Name(), attr->Type(), attr->Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
const AttributeInfo *
|
||||||
|
AttributeStreamMemoryNode::Next()
|
||||||
|
{
|
||||||
|
if (fReadFrom)
|
||||||
|
// the buffer is in the middle of the stream, get
|
||||||
|
// one buffer at a time
|
||||||
|
BufferingGet();
|
||||||
|
|
||||||
|
if (fCurrentIndex + 1 >= fAttributes.CountItems())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &fAttributes.ItemAt(++fCurrentIndex)->fAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
AttributeStreamMemoryNode::Get()
|
||||||
|
{
|
||||||
|
ASSERT(fCurrentIndex < fAttributes.CountItems());
|
||||||
|
return fAttributes.ItemAt(fCurrentIndex)->fData;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AttributeStreamMemoryNode::Fill(char *buffer) const
|
||||||
|
{
|
||||||
|
ASSERT(fCurrentIndex < fAttributes.CountItems());
|
||||||
|
memcpy(buffer, fAttributes.ItemAt(fCurrentIndex)->fData,
|
||||||
|
(size_t)fAttributes.ItemAt(fCurrentIndex)->fAttr.Size());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AttributeStreamTemplateNode::AttributeStreamTemplateNode(const AttributeTemplate *
|
||||||
|
attrTemplates, int32 count)
|
||||||
|
: fAttributes(attrTemplates),
|
||||||
|
fCurrentIndex(-1),
|
||||||
|
fCount(count)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamTemplateNode::Contains(const char *name, uint32 type)
|
||||||
|
{
|
||||||
|
int32 index = Find(name, type);
|
||||||
|
if (index < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return fAttributes[index].fSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AttributeStreamTemplateNode::Rewind()
|
||||||
|
{
|
||||||
|
fCurrentIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AttributeInfo *
|
||||||
|
AttributeStreamTemplateNode::Next()
|
||||||
|
{
|
||||||
|
if (fCurrentIndex + 1 >= fCount)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
++fCurrentIndex;
|
||||||
|
|
||||||
|
fCurrentAttr.SetTo(fAttributes[fCurrentIndex].fAttributeName,
|
||||||
|
fAttributes[fCurrentIndex].fAttributeType, fAttributes[fCurrentIndex].fSize);
|
||||||
|
|
||||||
|
return &fCurrentAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
AttributeStreamTemplateNode::Get()
|
||||||
|
{
|
||||||
|
ASSERT(fCurrentIndex < fCount);
|
||||||
|
return fAttributes[fCurrentIndex].fBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AttributeStreamTemplateNode::Fill(char *buffer) const
|
||||||
|
{
|
||||||
|
ASSERT(fCurrentIndex < fCount);
|
||||||
|
memcpy(buffer, fAttributes[fCurrentIndex].fBits, (size_t)fAttributes[fCurrentIndex].fSize);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
AttributeStreamTemplateNode::Find(const char *name, uint32 type) const
|
||||||
|
{
|
||||||
|
for (int32 index = 0; index < fCount; index++)
|
||||||
|
if (fAttributes[index].fAttributeType == type &&
|
||||||
|
strcmp(name, fAttributes[index].fAttributeName) == 0)
|
||||||
|
return index;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AttributeStreamFilterNode::Reject(const char *, uint32 , off_t )
|
||||||
|
{
|
||||||
|
// simple pass everything filter
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AttributeInfo *
|
||||||
|
AttributeStreamFilterNode::Next()
|
||||||
|
{
|
||||||
|
if (!fReadFrom)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
const AttributeInfo *attr = fReadFrom->Next();
|
||||||
|
if (!attr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!Reject(attr->Name(), attr->Type(), attr->Size()))
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamFilterNode::Contains(const char *name, uint32 type)
|
||||||
|
{
|
||||||
|
if (!fReadFrom)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
off_t size = fReadFrom->Contains(name, type);
|
||||||
|
|
||||||
|
if (!Reject(name, type, size))
|
||||||
|
return size;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamFilterNode::Read(const char *name, const char *foreignName, uint32 type,
|
||||||
|
off_t size, void *buffer, void (*swapFunc)(void *))
|
||||||
|
{
|
||||||
|
if (!fReadFrom)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!Reject(name, type, size))
|
||||||
|
return fReadFrom->Read(name, foreignName, type, size, buffer, swapFunc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t
|
||||||
|
AttributeStreamFilterNode::Write(const char *name, const char *foreignName, uint32 type,
|
||||||
|
off_t size, const void *buffer)
|
||||||
|
{
|
||||||
|
if (!fWriteTo)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!Reject(name, type, size))
|
||||||
|
return fWriteTo->Write(name, foreignName, type, size, buffer);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NamesToAcceptAttrFilter::NamesToAcceptAttrFilter(const char **nameList)
|
||||||
|
: fNameList(nameList)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NamesToAcceptAttrFilter::Reject(const char *name, uint32 , off_t )
|
||||||
|
{
|
||||||
|
for (int32 index = 0; ;index++) {
|
||||||
|
if (!fNameList[index])
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (strcmp(name, fNameList[index]) == 0) {
|
||||||
|
// PRINT(("filter passing through %s\n", name));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// PRINT(("filter rejecting %s\n", name));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SelectiveAttributeTransformer::SelectiveAttributeTransformer(const char *attributeName,
|
||||||
|
bool (*transformFunc)(const char * , uint32 , off_t, void *, void *), void *params)
|
||||||
|
: fAttributeNameToTransform(attributeName),
|
||||||
|
fTransformFunc(transformFunc),
|
||||||
|
fTransformParams(params),
|
||||||
|
fTransformedBuffers(10, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SelectiveAttributeTransformer::~SelectiveAttributeTransformer()
|
||||||
|
{
|
||||||
|
for (int32 index = fTransformedBuffers.CountItems() - 1; index >= 0; index--)
|
||||||
|
delete [] fTransformedBuffers.ItemAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SelectiveAttributeTransformer::Rewind()
|
||||||
|
{
|
||||||
|
for (int32 index = fTransformedBuffers.CountItems() - 1; index >= 0; index--)
|
||||||
|
delete [] fTransformedBuffers.ItemAt(index);
|
||||||
|
|
||||||
|
fTransformedBuffers.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
off_t
|
||||||
|
SelectiveAttributeTransformer::Read(const char *name, const char *foreignName,
|
||||||
|
uint32 type, off_t size, void *buffer, void (*swapFunc)(void *))
|
||||||
|
{
|
||||||
|
if (!fReadFrom)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
off_t result = fReadFrom->Read(name, foreignName, type, size, buffer, swapFunc);
|
||||||
|
|
||||||
|
if (WillTransform(name, type, size, (const char *)buffer))
|
||||||
|
ApplyTransformer(name, type, size, (char *)buffer);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SelectiveAttributeTransformer::WillTransform(const char *name, uint32 , off_t ,
|
||||||
|
const char *) const
|
||||||
|
{
|
||||||
|
return strcmp(name, fAttributeNameToTransform) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SelectiveAttributeTransformer::ApplyTransformer(const char *name, uint32 type, off_t size,
|
||||||
|
char *data)
|
||||||
|
{
|
||||||
|
return (fTransformFunc)(name, type, size, data, fTransformParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
SelectiveAttributeTransformer::CopyAndApplyTransformer(const char *name, uint32 type,
|
||||||
|
off_t size, const char *data)
|
||||||
|
{
|
||||||
|
char *result = NULL;
|
||||||
|
if (data) {
|
||||||
|
result = new char[size];
|
||||||
|
memcpy(result, data, (size_t)size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(fTransformFunc)(name, type, size, result, fTransformParams)) {
|
||||||
|
delete [] result;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AttributeInfo *
|
||||||
|
SelectiveAttributeTransformer::Next()
|
||||||
|
{
|
||||||
|
const AttributeInfo *result = fReadFrom->Next();
|
||||||
|
if (!result)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fCurrentAttr.SetTo(*result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
SelectiveAttributeTransformer::Get()
|
||||||
|
{
|
||||||
|
if (!fReadFrom)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
const char *result = fReadFrom->Get();
|
||||||
|
|
||||||
|
if (!WillTransform(fCurrentAttr.Name(), fCurrentAttr.Type(), fCurrentAttr.Size(), result))
|
||||||
|
return result;
|
||||||
|
|
||||||
|
char *transformedData = CopyAndApplyTransformer(fCurrentAttr.Name(), fCurrentAttr.Type(),
|
||||||
|
fCurrentAttr.Size(), result);
|
||||||
|
|
||||||
|
// enlist for proper disposal when our job is done
|
||||||
|
if (transformedData) {
|
||||||
|
fTransformedBuffers.AddItem(transformedData);
|
||||||
|
return transformedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,444 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// attribute streams allow copying/filtering/transformation of attributes
|
||||||
|
// between file and/or memory nodes
|
||||||
|
//
|
||||||
|
// for example one can use constructs of nodes like:
|
||||||
|
//
|
||||||
|
// destinationNode << transformer << buffer << filter << sourceNode
|
||||||
|
//
|
||||||
|
// transformer may for instance perform endian-swapping or offsetting of a B_RECT attribute
|
||||||
|
// filter may withold certain attributes
|
||||||
|
// buffer is a memory allocated snapshot of attributes, may be repeatedly streamed into
|
||||||
|
// other files, buffers
|
||||||
|
//
|
||||||
|
// In addition to the whacky (but usefull) << syntax, calls like Read, Write are also
|
||||||
|
// available
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __ATTRIBUTE_STREAM__
|
||||||
|
#define __ATTRIBUTE_STREAM__
|
||||||
|
|
||||||
|
#include <Node.h>
|
||||||
|
#include <Rect.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <TypeConstants.h>
|
||||||
|
|
||||||
|
#include <fs_attr.h>
|
||||||
|
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
struct AttributeTemplate {
|
||||||
|
// used for read-only attribute source
|
||||||
|
const char *fAttributeName;
|
||||||
|
uint32 fAttributeType;
|
||||||
|
off_t fSize;
|
||||||
|
const char *fBits;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class AttributeInfo {
|
||||||
|
// utility class for internal attribute description
|
||||||
|
public:
|
||||||
|
AttributeInfo()
|
||||||
|
{}
|
||||||
|
AttributeInfo(const AttributeInfo &);
|
||||||
|
AttributeInfo(const char *, attr_info);
|
||||||
|
AttributeInfo(const char *, uint32, off_t);
|
||||||
|
|
||||||
|
void SetTo(const AttributeInfo &);
|
||||||
|
void SetTo(const char *, attr_info);
|
||||||
|
void SetTo(const char *, uint32, off_t);
|
||||||
|
const char *Name() const;
|
||||||
|
uint32 Type() const;
|
||||||
|
off_t Size() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BString fName;
|
||||||
|
attr_info fInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeStreamNode {
|
||||||
|
public:
|
||||||
|
AttributeStreamNode();
|
||||||
|
virtual ~AttributeStreamNode();
|
||||||
|
|
||||||
|
AttributeStreamNode &operator<<(AttributeStreamNode &source);
|
||||||
|
// workhorse call
|
||||||
|
// to the outside makes this node a part of the stream, passing on
|
||||||
|
// any data it has, gets, transforms, doesn't filter out
|
||||||
|
//
|
||||||
|
// under the hood sets up streaming into the next node; hooking
|
||||||
|
// up source and destination, forces the stream head to start streaming
|
||||||
|
|
||||||
|
virtual void Rewind();
|
||||||
|
// get ready to start all over again
|
||||||
|
virtual void MakeEmpty() {}
|
||||||
|
// remove any attributes the node may have
|
||||||
|
|
||||||
|
virtual off_t Contains(const char *, uint32);
|
||||||
|
// returns size of attribute if found
|
||||||
|
|
||||||
|
virtual off_t Read(const char *name, const char *foreignName, uint32 type, off_t size,
|
||||||
|
void *buffer, void (*swapFunc)(void *) = 0);
|
||||||
|
// read from this node
|
||||||
|
virtual off_t Write(const char *name, const char *foreignName, uint32 type, off_t size,
|
||||||
|
const void *buffer);
|
||||||
|
// write to this node
|
||||||
|
|
||||||
|
|
||||||
|
// work calls
|
||||||
|
virtual bool Drive();
|
||||||
|
// node at the head of the stream makes the entire stream
|
||||||
|
// feed it
|
||||||
|
virtual const AttributeInfo *Next();
|
||||||
|
// give me the next attribute in the stream
|
||||||
|
virtual const char *Get();
|
||||||
|
// give me the data of the attribute in the stream that was just returned
|
||||||
|
// by Next
|
||||||
|
// assumes there is a buffering node somewhere on the way to
|
||||||
|
// the source, from which the resulting buffer is borrowed
|
||||||
|
virtual bool Fill(char *buffer) const;
|
||||||
|
// fill the buffer with data of the attribute in the stream that was just returned
|
||||||
|
// by next
|
||||||
|
// <buffer> is big enough to hold the entire attribute data
|
||||||
|
|
||||||
|
virtual bool CanFeed() const { return false; }
|
||||||
|
// return true if can work as a source for the entire stream
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Start();
|
||||||
|
// utility call, used to start up the stream by finding the ultimate
|
||||||
|
// target of the stream and calling Drive on it
|
||||||
|
|
||||||
|
void Detach();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AttributeStreamNode *fReadFrom;
|
||||||
|
AttributeStreamNode *fWriteTo;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeStreamFileNode : public AttributeStreamNode {
|
||||||
|
// handles reading and writing attributes to and from the
|
||||||
|
// stream
|
||||||
|
public:
|
||||||
|
AttributeStreamFileNode();
|
||||||
|
AttributeStreamFileNode(BNode *);
|
||||||
|
|
||||||
|
virtual void MakeEmpty();
|
||||||
|
virtual void Rewind();
|
||||||
|
virtual off_t Contains(const char *name, uint32 type);
|
||||||
|
virtual off_t Read(const char *name, const char *foreignName, uint32 type, off_t size,
|
||||||
|
void *buffer, void (*swapFunc)(void *) = 0);
|
||||||
|
virtual off_t Write(const char *name, const char *foreignName, uint32 type, off_t size,
|
||||||
|
const void *buffer);
|
||||||
|
|
||||||
|
void SetTo(BNode *);
|
||||||
|
|
||||||
|
BNode *Node()
|
||||||
|
{ return fNode; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool CanFeed() const { return true; }
|
||||||
|
|
||||||
|
virtual bool Drive();
|
||||||
|
// give me all the attributes, I'll write them into myself
|
||||||
|
virtual const AttributeInfo *Next();
|
||||||
|
// return the info for the next attribute I can read for you
|
||||||
|
virtual const char *Get();
|
||||||
|
virtual bool Fill(char *buffer) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AttributeInfo fCurrentAttr;
|
||||||
|
BNode *fNode;
|
||||||
|
|
||||||
|
typedef AttributeStreamNode _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeStreamMemoryNode : public AttributeStreamNode {
|
||||||
|
// in memory attribute buffer; can be both target of writing and source
|
||||||
|
// of reading at the same time
|
||||||
|
public:
|
||||||
|
AttributeStreamMemoryNode();
|
||||||
|
|
||||||
|
virtual void MakeEmpty();
|
||||||
|
virtual off_t Contains(const char *name, uint32 type);
|
||||||
|
virtual off_t Read(const char *name, const char *foreignName, uint32 type, off_t size,
|
||||||
|
void *buffer, void (*swapFunc)(void *) = 0);
|
||||||
|
virtual off_t Write(const char *name, const char *foreignName, uint32 type, off_t size,
|
||||||
|
const void *buffer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual bool CanFeed() const { return true; }
|
||||||
|
virtual void Rewind();
|
||||||
|
virtual bool Drive();
|
||||||
|
virtual const AttributeInfo *Next();
|
||||||
|
virtual const char *Get();
|
||||||
|
virtual bool Fill(char *buffer) const;
|
||||||
|
|
||||||
|
class AttrNode {
|
||||||
|
public:
|
||||||
|
AttrNode(const char *name, uint32 type, off_t size, char *data)
|
||||||
|
: fAttr(name, type, size),
|
||||||
|
fData(data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~AttrNode()
|
||||||
|
{
|
||||||
|
delete [] fData;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeInfo fAttr;
|
||||||
|
char *fData;
|
||||||
|
};
|
||||||
|
|
||||||
|
// utility calls
|
||||||
|
virtual AttrNode *BufferingGet();
|
||||||
|
virtual AttrNode *BufferingGet(const char *name, uint32 type, off_t size);
|
||||||
|
int32 Find(const char *name, uint32 type) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
BObjectList<AttrNode> fAttributes;
|
||||||
|
int32 fCurrentIndex;
|
||||||
|
|
||||||
|
typedef AttributeStreamNode _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeStreamTemplateNode : public AttributeStreamNode {
|
||||||
|
// in read-only memory attribute source
|
||||||
|
// can only be used as a source for Next and Get
|
||||||
|
public:
|
||||||
|
AttributeStreamTemplateNode(const AttributeTemplate *, int32 count);
|
||||||
|
|
||||||
|
virtual off_t Contains(const char *name, uint32 type);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual bool CanFeed() const { return true; }
|
||||||
|
virtual void Rewind();
|
||||||
|
virtual const AttributeInfo *Next();
|
||||||
|
virtual const char *Get();
|
||||||
|
virtual bool Fill(char *buffer) const;
|
||||||
|
|
||||||
|
int32 Find(const char *name, uint32 type) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AttributeInfo fCurrentAttr;
|
||||||
|
const AttributeTemplate *fAttributes;
|
||||||
|
int32 fCurrentIndex;
|
||||||
|
int32 fCount;
|
||||||
|
|
||||||
|
typedef AttributeStreamNode _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeStreamFilterNode : public AttributeStreamNode {
|
||||||
|
// filter node may not pass thru specified attributes
|
||||||
|
public:
|
||||||
|
AttributeStreamFilterNode()
|
||||||
|
{}
|
||||||
|
virtual off_t Contains(const char *name, uint32 type);
|
||||||
|
virtual off_t Read(const char *name, const char *foreignName, uint32 type, off_t size,
|
||||||
|
void *buffer, void (*swapFunc)(void *) = 0);
|
||||||
|
virtual off_t Write(const char *name, const char *foreignName, uint32 type, off_t size,
|
||||||
|
const void *buffer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool Reject(const char *name, uint32 type, off_t size);
|
||||||
|
// override to implement filtering
|
||||||
|
virtual const AttributeInfo *Next();
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef AttributeStreamNode _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NamesToAcceptAttrFilter : public AttributeStreamFilterNode {
|
||||||
|
// filter node that only passes thru attributes that match
|
||||||
|
// a list of names
|
||||||
|
public:
|
||||||
|
NamesToAcceptAttrFilter(const char **);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool Reject(const char *name, uint32 type, off_t size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char **fNameList;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SelectiveAttributeTransformer : public AttributeStreamNode {
|
||||||
|
// node applies a transformation on specified attributes
|
||||||
|
public:
|
||||||
|
SelectiveAttributeTransformer(const char *attributeName, bool (*)(const char *,
|
||||||
|
uint32 , off_t , void *, void *), void *params);
|
||||||
|
virtual ~SelectiveAttributeTransformer();
|
||||||
|
|
||||||
|
virtual off_t Read(const char *name, const char *foreignName, uint32 type, off_t size,
|
||||||
|
void *buffer, void (*swapFunc)(void *) = 0);
|
||||||
|
|
||||||
|
virtual void Rewind();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool WillTransform(const char *name, uint32 type, off_t size, const char *data) const;
|
||||||
|
// override to implement filtering; should only return true if transformation will
|
||||||
|
// occur
|
||||||
|
virtual char *CopyAndApplyTransformer(const char *name, uint32 type, off_t size, const char *data);
|
||||||
|
// makes a copy of data
|
||||||
|
virtual bool ApplyTransformer(const char *name, uint32 type, off_t size, char *data);
|
||||||
|
// transforms in place
|
||||||
|
virtual const AttributeInfo *Next();
|
||||||
|
virtual const char *Get();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AttributeInfo fCurrentAttr;
|
||||||
|
const char *fAttributeNameToTransform;
|
||||||
|
bool (*fTransformFunc)(const char *, uint32 , off_t , void *, void *);
|
||||||
|
void *fTransformParams;
|
||||||
|
|
||||||
|
BObjectList<char> fTransformedBuffers;
|
||||||
|
|
||||||
|
typedef AttributeStreamNode _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Type>
|
||||||
|
class AttributeStreamConstValue : public AttributeStreamNode {
|
||||||
|
public:
|
||||||
|
AttributeStreamConstValue(const char *name, uint32 attributeType, Type value);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual bool CanFeed() const { return true; }
|
||||||
|
virtual void Rewind() { fRewound = true; }
|
||||||
|
virtual const AttributeInfo *Next();
|
||||||
|
virtual const char *Get();
|
||||||
|
virtual bool Fill(char *buffer) const;
|
||||||
|
|
||||||
|
int32 Find(const char *name, uint32 type) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AttributeInfo fAttr;
|
||||||
|
Type fValue;
|
||||||
|
bool fRewound;
|
||||||
|
|
||||||
|
typedef AttributeStreamNode _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
AttributeStreamConstValue<Type>::AttributeStreamConstValue(const char *name,
|
||||||
|
uint32 attributeType, Type value)
|
||||||
|
: fAttr(name, attributeType, sizeof(Type)),
|
||||||
|
fValue(value),
|
||||||
|
fRewound(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
const AttributeInfo *
|
||||||
|
AttributeStreamConstValue<Type>::Next()
|
||||||
|
{
|
||||||
|
if (!fRewound)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fRewound = false;
|
||||||
|
return &fAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
const char *
|
||||||
|
AttributeStreamConstValue<Type>::Get()
|
||||||
|
{
|
||||||
|
return (const char *)&fValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
bool
|
||||||
|
AttributeStreamConstValue<Type>::Fill(char *buffer) const
|
||||||
|
{
|
||||||
|
memcpy(buffer, &fValue, sizeof(Type));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
int32
|
||||||
|
AttributeStreamConstValue<Type>::Find(const char *name, uint32 type) const
|
||||||
|
{
|
||||||
|
if (strcmp(fAttr.Name(), name) == 0 && type = fAttr.Type())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AttributeStreamBoolValue : public AttributeStreamConstValue<bool> {
|
||||||
|
public:
|
||||||
|
AttributeStreamBoolValue(const char *name, bool value)
|
||||||
|
: AttributeStreamConstValue<bool>(name, B_BOOL_TYPE, value)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeStreamInt32Value : public AttributeStreamConstValue<int32> {
|
||||||
|
public:
|
||||||
|
AttributeStreamInt32Value(const char *name, int32 value)
|
||||||
|
: AttributeStreamConstValue<int32>(name, B_INT32_TYPE, value)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeStreamInt64Value : public AttributeStreamConstValue<int64> {
|
||||||
|
public:
|
||||||
|
AttributeStreamInt64Value(const char *name, int64 value)
|
||||||
|
: AttributeStreamConstValue<int64>(name, B_INT64_TYPE, value)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeStreamRectValue : public AttributeStreamConstValue<BRect> {
|
||||||
|
public:
|
||||||
|
AttributeStreamRectValue(const char *name, BRect value)
|
||||||
|
: AttributeStreamConstValue<BRect>(name, B_RECT_TYPE, value)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeStreamFloatValue : public AttributeStreamConstValue<float> {
|
||||||
|
public:
|
||||||
|
AttributeStreamFloatValue(const char *name, float value)
|
||||||
|
: AttributeStreamConstValue<float>(name, B_FLOAT_TYPE, value)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
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 _ATTRIBUTES_H
|
||||||
|
#define _ATTRIBUTES_H
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
// viewable attributes
|
||||||
|
#define kAttrStatName "_stat/name"
|
||||||
|
#define kAttrStatSize "_stat/size"
|
||||||
|
#define kAttrStatModified "_stat/modified"
|
||||||
|
#define kAttrStatCreated "_stat/created"
|
||||||
|
#define kAttrStatMode "_stat/mode"
|
||||||
|
#define kAttrStatOwner "_stat/owner"
|
||||||
|
#define kAttrStatGroup "_stat/group"
|
||||||
|
#define kAttrPath "_trk/path"
|
||||||
|
#define kAttrOriginalPath "_trk/original_path"
|
||||||
|
#define kAttrAppVersion "_trk/app_version"
|
||||||
|
#define kAttrSystemVersion "_trk/system_version"
|
||||||
|
#define kAttrOpenWithRelation "_trk/open_with_relation"
|
||||||
|
|
||||||
|
// private attributes
|
||||||
|
#define kAttrWindowFrame "_trk/windframe"
|
||||||
|
#define kAttrWindowWorkspace "_trk/windwkspc"
|
||||||
|
|
||||||
|
#define kAttrQueryString "_trk/qrystr"
|
||||||
|
#define kAttrQueryVolume "_trk/qryvol1"
|
||||||
|
|
||||||
|
#define kAttrMIMEType "BEOS:TYPE"
|
||||||
|
#define kAttrAppSignature "BEOS:APP_SIG"
|
||||||
|
#define kAttrPreferredApp "BEOS:PREF_APP"
|
||||||
|
#define kAttrLargeIcon "BEOS:L:STD_ICON"
|
||||||
|
#define kAttrMiniIcon "BEOS:M:STD_ICON"
|
||||||
|
|
||||||
|
#define kAttrDisksFrame "_trk/d_windframe"
|
||||||
|
#define kAttrDisksWorkspace "_trk/d_windwkspc"
|
||||||
|
|
||||||
|
#define kAttrOpenWindows "_trk/_windows_to_open_"
|
||||||
|
|
||||||
|
#define kAttrClippingFile "_trk/_clipping_file_"
|
||||||
|
|
||||||
|
|
||||||
|
#define kAttrQueryInitialMode "_trk/qryinitmode"
|
||||||
|
#define kAttrQueryInitialString "_trk/qryinitstr"
|
||||||
|
#define kAttrQueryInitialNumAttrs "_trk/qryinitnumattrs"
|
||||||
|
#define kAttrQueryInitialAttrs "_trk/qryinitattrs"
|
||||||
|
#define kAttrQueryInitialMime "_trk/qryinitmime"
|
||||||
|
#define kAttrQueryLastChange "_trk/qrylastchange"
|
||||||
|
|
||||||
|
|
||||||
|
#define kAttrQueryMoreOptions_le "_trk/qrymoreoptions_le"
|
||||||
|
#define kAttrQueryMoreOptions_be "_trk/qrymoreoptions"
|
||||||
|
|
||||||
|
#define kAttrQueryTemplate "_trk/queryTemplate"
|
||||||
|
#define kAttrQueryTemplateName "_trk/queryTemplateName"
|
||||||
|
#define kAttrDynamicDateQuery "_trk/queryDynamicDate"
|
||||||
|
// attributes that need endian swapping (stored as raw)
|
||||||
|
|
||||||
|
#define kAttrPoseInfo_be "_trk/pinfo"
|
||||||
|
#define kAttrPoseInfo_le "_trk/pinfo_le"
|
||||||
|
#define kAttrDisksPoseInfo_be "_trk/d_pinfo"
|
||||||
|
#define kAttrDisksPoseInfo_le "_trk/d_pinfo_le"
|
||||||
|
#define kAttrColumns_be "_trk/columns"
|
||||||
|
#define kAttrColumns_le "_trk/columns_le"
|
||||||
|
#define kAttrViewState_be "_trk/viewstate"
|
||||||
|
#define kAttrViewState_le "_trk/viewstate_le"
|
||||||
|
#define kAttrDisksViewState_be "_trk/d_viewstate"
|
||||||
|
#define kAttrDisksViewState_le "_trk/d_viewstate_le"
|
||||||
|
#define kAttrDisksColumns_be "_trk/d_columns"
|
||||||
|
#define kAttrDisksColumns_le "_trk/d_columns_le"
|
||||||
|
|
||||||
|
#define kAttrExtendedPoseInfo_be "_trk/xtpinfo"
|
||||||
|
#define kAttrExtendedPoseInfo_le "_trk/xtpinfo_le"
|
||||||
|
#define kAttrExtendedDisksPoseInfo_be "_trk/xt_d_pinfo"
|
||||||
|
#define kAttrExtendedDisksPoseInfo_le "_trk/xt_d_pinfo_le"
|
||||||
|
|
||||||
|
#if B_HOST_IS_LENDIAN
|
||||||
|
#define kEndianSuffix "_le"
|
||||||
|
#define kForeignEndianSuffix ""
|
||||||
|
|
||||||
|
#define kAttrDisksPoseInfo kAttrDisksPoseInfo_le
|
||||||
|
#define kAttrDisksPoseInfoForeign kAttrDisksPoseInfo_be
|
||||||
|
|
||||||
|
#define kAttrPoseInfo kAttrPoseInfo_le
|
||||||
|
#define kAttrPoseInfoForeign kAttrPoseInfo_be
|
||||||
|
|
||||||
|
#define kAttrColumns kAttrColumns_le
|
||||||
|
#define kAttrColumnsForeign kAttrColumns_be
|
||||||
|
|
||||||
|
#define kAttrViewState kAttrViewState_le
|
||||||
|
#define kAttrViewStateForeign kAttrViewState_be
|
||||||
|
|
||||||
|
#define kAttrDisksViewState kAttrDisksViewState_le
|
||||||
|
#define kAttrDisksViewStateForeign kAttrDisksViewState_be
|
||||||
|
|
||||||
|
#define kAttrDisksColumns kAttrDisksColumns_le
|
||||||
|
#define kAttrDisksColumnsForeign kAttrDisksColumns_be
|
||||||
|
|
||||||
|
#define kAttrQueryMoreOptions kAttrQueryMoreOptions_le
|
||||||
|
#define kAttrQueryMoreOptionsForeign kAttrQueryMoreOptions_be
|
||||||
|
#define kAttrExtendedPoseInfo kAttrExtendedPoseInfo_le
|
||||||
|
#define kAttrExtendedPoseInfoForegin kAttrExtendedPoseInfo_be
|
||||||
|
#define kAttrExtendedDisksPoseInfo kAttrExtendedDisksPoseInfo_le
|
||||||
|
#define kAttrExtendedDisksPoseInfoForegin kAttrExtendedDisksPoseInfo_be
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define kEndianSuffix ""
|
||||||
|
#define kForeignEndianSuffix "_le"
|
||||||
|
|
||||||
|
#define kAttrDisksPoseInfo kAttrDisksPoseInfo_be
|
||||||
|
#define kAttrDisksPoseInfoForeign kAttrDisksPoseInfo_le
|
||||||
|
|
||||||
|
#define kAttrPoseInfo kAttrPoseInfo_be
|
||||||
|
#define kAttrPoseInfoForeign kAttrPoseInfo_le
|
||||||
|
|
||||||
|
#define kAttrColumns kAttrColumns_be
|
||||||
|
#define kAttrColumnsForeign kAttrColumns_le
|
||||||
|
|
||||||
|
#define kAttrViewState kAttrViewState_be
|
||||||
|
#define kAttrViewStateForeign kAttrViewState_le
|
||||||
|
|
||||||
|
#define kAttrDisksViewState kAttrDisksViewState_be
|
||||||
|
#define kAttrDisksViewStateForeign kAttrDisksViewState_le
|
||||||
|
|
||||||
|
#define kAttrDisksColumns kAttrDisksColumns_be
|
||||||
|
#define kAttrDisksColumnsForeign kAttrDisksColumns_le
|
||||||
|
|
||||||
|
#define kAttrQueryMoreOptions kAttrQueryMoreOptions_be
|
||||||
|
#define kAttrQueryMoreOptionsForeign kAttrQueryMoreOptions_le
|
||||||
|
#define kAttrExtendedPoseInfo kAttrExtendedPoseInfo_be
|
||||||
|
#define kAttrExtendedPoseInfoForegin kAttrExtendedPoseInfo_le
|
||||||
|
#define kAttrExtendedDisksPoseInfo kAttrExtendedDisksPoseInfo_be
|
||||||
|
#define kAttrExtendedDisksPoseInfoForegin kAttrExtendedDisksPoseInfo_le
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
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 _AUTO_MOUNTER_H
|
||||||
|
#define _AUTO_MOUNTER_H
|
||||||
|
|
||||||
|
#include <File.h>
|
||||||
|
#include <Looper.h>
|
||||||
|
#include <Message.h>
|
||||||
|
|
||||||
|
#if OPEN_TRACKER
|
||||||
|
#include "DeviceMap.h"
|
||||||
|
#else
|
||||||
|
#include <private/storage/DeviceMap.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
const uint32 kSetAutomounterParams = 'pmst';
|
||||||
|
const uint32 kSuspendAutomounter = 'amsp';
|
||||||
|
const uint32 kResumeAutomounter = 'amsr';
|
||||||
|
const uint32 kMountAllNow = 'mntn';
|
||||||
|
const uint32 kMountVolume = 'mntv';
|
||||||
|
const uint32 kTryMountingFloppy = 'mntf';
|
||||||
|
const uint32 kAutomounterRescan = 'rscn';
|
||||||
|
|
||||||
|
const int32 kFloppyID = -1;
|
||||||
|
|
||||||
|
struct AutomountParams {
|
||||||
|
bool mountAllFS;
|
||||||
|
bool mountBFS;
|
||||||
|
bool mountHFS;
|
||||||
|
bool mountRemovableDisksOnly;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AutoMounter : public BLooper {
|
||||||
|
public:
|
||||||
|
AutoMounter(
|
||||||
|
bool checkRemovableOnly = true, // do not poll nonremovable disks
|
||||||
|
bool checkCDs = true, // currently ignored
|
||||||
|
bool checkFloppies = false, //
|
||||||
|
bool checkOtherRemovables = true, // currently ignored
|
||||||
|
bool autoMountRemovableOnly = true, // if false, automount nonremovables too
|
||||||
|
bool autoMountAll = false, // disregard the file system during autoumont
|
||||||
|
bool autoMountAllBFS = true, // automount bfs disks
|
||||||
|
bool autoMountAllHFS = false, // automount hfs diska
|
||||||
|
bool initialMountAll = false, // mount everything during boot
|
||||||
|
bool initialMountAllBFS = true, // mount every bfs volume during boot
|
||||||
|
bool initialMountRestore = false, // restore volumes that were mounted at last shutdown
|
||||||
|
bool initialMountAllHFS = false); // mount every hfs volume during boot
|
||||||
|
virtual ~AutoMounter();
|
||||||
|
virtual bool QuitRequested();
|
||||||
|
|
||||||
|
void GetSettings(BMessage *);
|
||||||
|
|
||||||
|
void CheckVolumesNow();
|
||||||
|
// mounts everything respecting the current automounting settings
|
||||||
|
// used to sync up right after settings changed
|
||||||
|
|
||||||
|
void EachMountableItemAndFloppy(EachPartitionFunction , void *);
|
||||||
|
void EachMountedItem(EachPartitionFunction, void *);
|
||||||
|
Partition * EachPartition(EachPartitionFunction, void *);
|
||||||
|
Partition *FindPartition(dev_t id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ReadSettings();
|
||||||
|
void WriteSettings();
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
void UnmountAndEjectVolume(BMessage *);
|
||||||
|
void SetParams(BMessage *, bool rescan);
|
||||||
|
|
||||||
|
static status_t WatchVolumeBinder(void *);
|
||||||
|
void WatchVolumes();
|
||||||
|
|
||||||
|
static status_t InitialRescanBinder(void *);
|
||||||
|
void InitialRescan();
|
||||||
|
|
||||||
|
void SuspendResume(bool);
|
||||||
|
|
||||||
|
void MountAllNow();
|
||||||
|
// used by the mount all now button
|
||||||
|
// ignores the automounting settings and mounts everything it can
|
||||||
|
|
||||||
|
void MountVolume(BMessage *);
|
||||||
|
|
||||||
|
void RescanDevices();
|
||||||
|
|
||||||
|
|
||||||
|
void TryMountingFloppy();
|
||||||
|
bool IsFloppyMounted();
|
||||||
|
bool FloppyInList();
|
||||||
|
|
||||||
|
#if _INCLUDES_CLASS_DEVICE_MAP
|
||||||
|
DeviceList fList;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// automounter settings
|
||||||
|
DeviceScanParams fScanParams;
|
||||||
|
AutomountParams fAutomountParams;
|
||||||
|
|
||||||
|
bool fInitialMountAll;
|
||||||
|
bool fInitialMountAllBFS;
|
||||||
|
bool fInitialMountRestore;
|
||||||
|
bool fInitialMountAllHFS;
|
||||||
|
bool fSuspended;
|
||||||
|
|
||||||
|
// misc.
|
||||||
|
thread_id fScanThread;
|
||||||
|
volatile bool fQuitting;
|
||||||
|
|
||||||
|
BFile fPrefsFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
Partition *AddMountableItemToMessage(Partition *, void *);
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Button.h>
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <RadioButton.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "AutoMounter.h"
|
||||||
|
#include "AutoMounterSettings.h"
|
||||||
|
|
||||||
|
const uint32 kDone = 'done';
|
||||||
|
const uint32 kMountAllNow = 'done';
|
||||||
|
const uint32 kAutomountSettingsChanged = 'achg';
|
||||||
|
const uint32 kBootMountSettingsChanged = 'bchg';
|
||||||
|
const uint32 kAutoAll = 'aall';
|
||||||
|
const uint32 kAutoBFS = 'abfs';
|
||||||
|
const uint32 kAutoHFS = 'ahfs';
|
||||||
|
const uint32 kInitAll = 'iall';
|
||||||
|
const uint32 kInitBFS = 'ibfs';
|
||||||
|
const uint32 kInitHFS = 'ihfs';
|
||||||
|
|
||||||
|
const BPoint kButtonSize(80, 20);
|
||||||
|
const BPoint kSmallButtonSize(60, 20);
|
||||||
|
const rgb_color kLightGray = { 216, 216, 216, 255};
|
||||||
|
|
||||||
|
const int32 kCheckBoxSpacing = 20;
|
||||||
|
|
||||||
|
AutomountSettingsDialog *AutomountSettingsDialog::oneCopyOnly = NULL;
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomountSettingsDialog::RunAutomountSettings(AutoMounter *target)
|
||||||
|
{
|
||||||
|
// either activate an existing mount settings dialog or create a new one
|
||||||
|
if (oneCopyOnly) {
|
||||||
|
oneCopyOnly->Activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage message;
|
||||||
|
target->GetSettings(&message);
|
||||||
|
(new AutomountSettingsDialog(&message, target))->Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
AutomountSettingsPanel::AutomountSettingsPanel(BRect frame,
|
||||||
|
BMessage *settings, AutoMounter *target)
|
||||||
|
: BBox(frame, "", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS
|
||||||
|
| B_NAVIGABLE_JUMP, B_PLAIN_BORDER),
|
||||||
|
fTarget(target)
|
||||||
|
{
|
||||||
|
SetViewColor(kLightGray);
|
||||||
|
|
||||||
|
BRect checkBoxRect(Bounds());
|
||||||
|
|
||||||
|
BRect boxRect(Bounds());
|
||||||
|
boxRect.InsetBy(10, 15);
|
||||||
|
boxRect.bottom = boxRect.top + 85;
|
||||||
|
BBox *box = new BBox(boxRect, "autoMountBox", B_FOLLOW_ALL,
|
||||||
|
B_WILL_DRAW | B_FRAME_EVENTS | B_PULSE_NEEDED | B_NAVIGABLE_JUMP);
|
||||||
|
box->SetLabel("Automatic Disk Mounting:");
|
||||||
|
AddChild(box);
|
||||||
|
|
||||||
|
checkBoxRect = box->Bounds();
|
||||||
|
checkBoxRect.InsetBy(10, 18);
|
||||||
|
|
||||||
|
checkBoxRect.bottom = checkBoxRect.top + 20;
|
||||||
|
|
||||||
|
scanningDisabledCheck = new BRadioButton(checkBoxRect, "scanningOff",
|
||||||
|
"Don't Automount", new BMessage(kAutomountSettingsChanged));
|
||||||
|
box->AddChild(scanningDisabledCheck);
|
||||||
|
|
||||||
|
checkBoxRect.OffsetBy(0, kCheckBoxSpacing);
|
||||||
|
autoMountAllBFSCheck = new BRadioButton(checkBoxRect, "autoBFS",
|
||||||
|
"All BeOS Disks", new BMessage(kAutomountSettingsChanged));
|
||||||
|
box->AddChild(autoMountAllBFSCheck);
|
||||||
|
|
||||||
|
checkBoxRect.OffsetBy(0, kCheckBoxSpacing);
|
||||||
|
autoMountAllCheck = new BRadioButton(checkBoxRect, "autoAll",
|
||||||
|
"All Disks", new BMessage(kAutomountSettingsChanged));
|
||||||
|
box->AddChild(autoMountAllCheck);
|
||||||
|
|
||||||
|
|
||||||
|
boxRect.OffsetTo(boxRect.left, boxRect.bottom + 15);
|
||||||
|
boxRect.bottom = boxRect.top + 105;
|
||||||
|
box = new BBox(boxRect, "", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS
|
||||||
|
| B_PULSE_NEEDED | B_NAVIGABLE_JUMP);
|
||||||
|
box->SetLabel("Disk Mounting During Boot:");
|
||||||
|
AddChild(box);
|
||||||
|
|
||||||
|
checkBoxRect = box->Bounds();
|
||||||
|
checkBoxRect.InsetBy(10, 18);
|
||||||
|
|
||||||
|
checkBoxRect.bottom = checkBoxRect.top + 20;
|
||||||
|
initialDontMountCheck = new BRadioButton(checkBoxRect, "initialNone",
|
||||||
|
"Only The Boot Disk", new BMessage(kBootMountSettingsChanged));
|
||||||
|
box->AddChild(initialDontMountCheck);
|
||||||
|
|
||||||
|
checkBoxRect.OffsetBy(0, kCheckBoxSpacing);
|
||||||
|
initialMountRestoreCheck = new BRadioButton(checkBoxRect, "initialRestore",
|
||||||
|
"Previously Mounted Disks", new BMessage(kBootMountSettingsChanged));
|
||||||
|
box->AddChild(initialMountRestoreCheck);
|
||||||
|
|
||||||
|
checkBoxRect.OffsetBy(0, kCheckBoxSpacing);
|
||||||
|
initialMountAllBFSCheck = new BRadioButton(checkBoxRect, "initialBFS",
|
||||||
|
"All BeOS Disks", new BMessage(kBootMountSettingsChanged));
|
||||||
|
box->AddChild(initialMountAllBFSCheck);
|
||||||
|
|
||||||
|
checkBoxRect.OffsetBy(0, kCheckBoxSpacing);
|
||||||
|
initialMountAllCheck = new BRadioButton(checkBoxRect, "initialAll",
|
||||||
|
"All Disks", new BMessage(kBootMountSettingsChanged));
|
||||||
|
box->AddChild(initialMountAllCheck);
|
||||||
|
|
||||||
|
|
||||||
|
BRect buttonRect(Bounds());
|
||||||
|
buttonRect.InsetBy(15, 15);
|
||||||
|
buttonRect.SetLeftTop(buttonRect.RightBottom() - kSmallButtonSize);
|
||||||
|
fDone = new BButton(buttonRect, "done", "Done", new BMessage(kDone));
|
||||||
|
|
||||||
|
buttonRect.OffsetTo(buttonRect.left - 15 - buttonRect.Width(), buttonRect.top);
|
||||||
|
buttonRect.left = buttonRect.left - 60;
|
||||||
|
fMountAllNow = new BButton(buttonRect, "mountAll", "Mount all disks now",
|
||||||
|
new BMessage(kMountAllNow));
|
||||||
|
|
||||||
|
AddChild(fMountAllNow);
|
||||||
|
|
||||||
|
AddChild(fDone);
|
||||||
|
fDone->MakeDefault(true);
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
if (settings->FindBool("autoMountAll", &result) == B_OK && result)
|
||||||
|
autoMountAllCheck->SetValue(1);
|
||||||
|
else if (settings->FindBool("autoMountAllBFS", &result) == B_OK && result)
|
||||||
|
autoMountAllBFSCheck->SetValue(1);
|
||||||
|
else
|
||||||
|
scanningDisabledCheck->SetValue(1);
|
||||||
|
|
||||||
|
if (settings->FindBool("suspended", &result) == B_OK && result)
|
||||||
|
scanningDisabledCheck->SetValue(1);
|
||||||
|
|
||||||
|
if (settings->FindBool("initialMountAll", &result) == B_OK && result)
|
||||||
|
initialMountAllCheck->SetValue(1);
|
||||||
|
else if (settings->FindBool("initialMountRestore", &result) == B_OK && result)
|
||||||
|
initialMountRestoreCheck->SetValue(1);
|
||||||
|
else if (settings->FindBool("initialMountAllBFS", &result) == B_OK && result)
|
||||||
|
initialMountAllBFSCheck->SetValue(1);
|
||||||
|
else
|
||||||
|
initialDontMountCheck->SetValue(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AutomountSettingsPanel::~AutomountSettingsPanel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomountSettingsPanel::SendSettings(bool rescan)
|
||||||
|
{
|
||||||
|
BMessage message(kSetAutomounterParams);
|
||||||
|
|
||||||
|
message.AddBool("autoMountAll", (bool)autoMountAllCheck->Value());
|
||||||
|
message.AddBool("autoMountAllBFS", (bool)autoMountAllBFSCheck->Value());
|
||||||
|
if (autoMountAllBFSCheck->Value())
|
||||||
|
message.AddBool("autoMountAllHFS", false);
|
||||||
|
|
||||||
|
message.AddBool("suspended", (bool)scanningDisabledCheck->Value());
|
||||||
|
message.AddBool("rescanNow", rescan);
|
||||||
|
|
||||||
|
message.AddBool("initialMountAll", (bool)initialMountAllCheck->Value());
|
||||||
|
message.AddBool("initialMountAllBFS", (bool)initialMountAllBFSCheck->Value());
|
||||||
|
message.AddBool("initialMountRestore", (bool)initialMountRestoreCheck->Value());
|
||||||
|
if (initialDontMountCheck->Value())
|
||||||
|
message.AddBool("initialMountAllHFS", false);
|
||||||
|
|
||||||
|
fTarget->PostMessage(&message, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomountSettingsPanel::AttachedToWindow()
|
||||||
|
{
|
||||||
|
initialMountAllCheck->SetTarget(this);
|
||||||
|
initialMountAllBFSCheck->SetTarget(this);
|
||||||
|
initialMountRestoreCheck->SetTarget(this);
|
||||||
|
initialDontMountCheck->SetTarget(this);
|
||||||
|
autoMountAllCheck->SetTarget(this);
|
||||||
|
autoMountAllBFSCheck->SetTarget(this);
|
||||||
|
scanningDisabledCheck->SetTarget(this);
|
||||||
|
fDone->SetTarget(this);
|
||||||
|
fMountAllNow->SetTarget(fTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AutomountSettingsPanel::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case kDone:
|
||||||
|
case B_QUIT_REQUESTED:
|
||||||
|
Window()->Quit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kAutomountSettingsChanged:
|
||||||
|
SendSettings(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kBootMountSettingsChanged:
|
||||||
|
SendSettings(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_inherited::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AutomountSettingsDialog::AutomountSettingsDialog(BMessage *settings,
|
||||||
|
AutoMounter *target)
|
||||||
|
: BWindow(BRect(100, 100, 320, 370), "Disk Mount Settings",
|
||||||
|
B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE)
|
||||||
|
{
|
||||||
|
AddChild(new AutomountSettingsPanel(Bounds(), settings, target));
|
||||||
|
ASSERT(!oneCopyOnly);
|
||||||
|
oneCopyOnly = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutomountSettingsDialog::~AutomountSettingsDialog()
|
||||||
|
{
|
||||||
|
ASSERT(oneCopyOnly);
|
||||||
|
oneCopyOnly = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
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 __AUTOMOUNTER_SETTINGS__
|
||||||
|
#define __AUTOMOUNTER_SETTINGS__
|
||||||
|
|
||||||
|
#include <Window.h>
|
||||||
|
#include <Box.h>
|
||||||
|
|
||||||
|
class BCheckBox;
|
||||||
|
class BRadioButton;
|
||||||
|
class BButton;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class AutoMounter;
|
||||||
|
|
||||||
|
class AutomountSettingsPanel : public BBox {
|
||||||
|
public:
|
||||||
|
AutomountSettingsPanel(BRect, BMessage *, AutoMounter *);
|
||||||
|
virtual ~AutomountSettingsPanel();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SendSettings(bool rescan);
|
||||||
|
|
||||||
|
BRadioButton *initialDontMountCheck;
|
||||||
|
BRadioButton *initialMountAllBFSCheck;
|
||||||
|
BRadioButton *initialMountAllCheck;
|
||||||
|
BRadioButton *initialMountRestoreCheck;
|
||||||
|
|
||||||
|
BRadioButton *scanningDisabledCheck;
|
||||||
|
BRadioButton *autoMountAllBFSCheck;
|
||||||
|
BRadioButton *autoMountAllCheck;
|
||||||
|
|
||||||
|
BButton *fDone;
|
||||||
|
BButton *fMountAllNow;
|
||||||
|
|
||||||
|
AutoMounter *fTarget;
|
||||||
|
|
||||||
|
typedef BBox _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AutomountSettingsDialog : public BWindow {
|
||||||
|
public:
|
||||||
|
AutomountSettingsDialog(BMessage *settings, AutoMounter *);
|
||||||
|
virtual ~AutomountSettingsDialog();
|
||||||
|
|
||||||
|
static void RunAutomountSettings(AutoMounter *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static AutomountSettingsDialog *oneCopyOnly;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
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 _TRACKER_BACKGROUND_H
|
||||||
|
#define _TRACKER_BACKGROUND_H
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
/*----- Tracker background attribute name ----------------------*/
|
||||||
|
|
||||||
|
#define B_BACKGROUND_INFO "be:bgndimginfo"
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
/*----- Tracker background BMessage entries --------------------*/
|
||||||
|
|
||||||
|
#define B_BACKGROUND_IMAGE "be:bgndimginfopath" // string path
|
||||||
|
#define B_BACKGROUND_MODE "be:bgndimginfomode" // int32, the enum below
|
||||||
|
#define B_BACKGROUND_ORIGIN "be:bgndimginfooffset" // BPoint
|
||||||
|
#define B_BACKGROUND_ERASE_TEXT "be:bgndimginfoerasetext" // bool
|
||||||
|
#define B_BACKGROUND_WORKSPACES "be:bgndimginfoworkspaces" // uint32
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
/*----- Background mode values ---------------------------------*/
|
||||||
|
|
||||||
|
enum {
|
||||||
|
B_BACKGROUND_MODE_USE_ORIGIN,
|
||||||
|
B_BACKGROUND_MODE_CENTERED, // only works on Desktop
|
||||||
|
B_BACKGROUND_MODE_SCALED, // only works on Desktop
|
||||||
|
B_BACKGROUND_MODE_TILED
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
const int32 B_RESTORE_BACKGROUND_IMAGE = 'Tbgr'; // force a Tracker window to
|
||||||
|
// use a new background image
|
||||||
|
|
||||||
|
#endif /* _TRACKER_BACKGROUND_H */
|
||||||
@@ -0,0 +1,317 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Classes used for setting up and managing background images
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <Node.h>
|
||||||
|
#include <TranslationKit.h>
|
||||||
|
#include <View.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include <fs_attr.h>
|
||||||
|
|
||||||
|
#include "BackgroundImage.h"
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
const char *kBackgroundImageInfo = "be:bgndimginfo";
|
||||||
|
const char *kBackgroundImageInfoOffset = "be:bgndimginfooffset";
|
||||||
|
const char *kBackgroundImageInfoEraseText = "be:bgndimginfoerasetext";
|
||||||
|
const char *kBackgroundImageInfoMode = "be:bgndimginfomode";
|
||||||
|
const char *kBackgroundImageInfoWorkspaces = "be:bgndimginfoworkspaces";
|
||||||
|
const char *kBackgroundImageInfoPath = "be:bgndimginfopath";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundImage *
|
||||||
|
BackgroundImage::GetBackgroundImage(const BNode *node, bool isDesktop)
|
||||||
|
{
|
||||||
|
attr_info info;
|
||||||
|
if (node->GetAttrInfo(kBackgroundImageInfo, &info) != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
BMessage container;
|
||||||
|
char *buffer = new char [info.size];
|
||||||
|
|
||||||
|
status_t error = node->ReadAttr(kBackgroundImageInfo, info.type, 0, buffer, (size_t)info.size);
|
||||||
|
if (error == info.size)
|
||||||
|
error = container.Unflatten(buffer);
|
||||||
|
|
||||||
|
delete [] buffer;
|
||||||
|
|
||||||
|
if (error != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
BackgroundImage *result = NULL;
|
||||||
|
for (int32 index = 0; ; index++) {
|
||||||
|
const char *path;
|
||||||
|
uint32 workspaces = B_ALL_WORKSPACES;
|
||||||
|
Mode mode = kTiled;
|
||||||
|
bool eraseTextWidgetBackground = true;
|
||||||
|
BPoint offset;
|
||||||
|
|
||||||
|
if (container.FindString(kBackgroundImageInfoPath, index, &path) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BBitmap *bitmap = BTranslationUtils::GetBitmap(path);
|
||||||
|
if (!bitmap) {
|
||||||
|
// PRINT(("failed to load background bitmap from path\n"));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
container.FindInt32(kBackgroundImageInfoWorkspaces, index, (int32 *)&workspaces);
|
||||||
|
container.FindInt32(kBackgroundImageInfoMode, index, (int32 *)&mode);
|
||||||
|
container.FindBool(kBackgroundImageInfoEraseText, index, &eraseTextWidgetBackground);
|
||||||
|
container.FindPoint(kBackgroundImageInfoOffset, index, &offset);
|
||||||
|
|
||||||
|
BackgroundImage::BackgroundImageInfo *imageInfo = new
|
||||||
|
BackgroundImage::BackgroundImageInfo(workspaces, bitmap, mode, offset,
|
||||||
|
eraseTextWidgetBackground);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
result = new BackgroundImage(node, isDesktop);
|
||||||
|
|
||||||
|
result->Add(imageInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BackgroundImage::BackgroundImageInfo::BackgroundImageInfo(uint32 workspaces,
|
||||||
|
BBitmap *bitmap, Mode mode, BPoint offset, bool eraseTextWidget)
|
||||||
|
: fWorkspace(workspaces),
|
||||||
|
fBitmap(bitmap),
|
||||||
|
fMode(mode),
|
||||||
|
fOffset(offset),
|
||||||
|
fEraseTextWidgetBackground(eraseTextWidget)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BackgroundImage::BackgroundImageInfo::~BackgroundImageInfo()
|
||||||
|
{
|
||||||
|
delete fBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BackgroundImage::BackgroundImage(const BNode *node, bool desktop)
|
||||||
|
: fIsDesktop(desktop),
|
||||||
|
fDefinedByNode(*node),
|
||||||
|
fView(NULL),
|
||||||
|
fShowingBitmap(NULL),
|
||||||
|
fBitmapForWorkspaceList(1, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundImage::~BackgroundImage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BackgroundImage::Add(BackgroundImageInfo *info)
|
||||||
|
{
|
||||||
|
fBitmapForWorkspaceList.AddItem(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BackgroundImage::Show(BView *view, int32 workspace)
|
||||||
|
{
|
||||||
|
fView = view;
|
||||||
|
|
||||||
|
BackgroundImageInfo *info = ImageInfoForWorkspace(workspace);
|
||||||
|
if (info) {
|
||||||
|
BPoseView *poseView = dynamic_cast<BPoseView *>(fView);
|
||||||
|
if (poseView)
|
||||||
|
poseView->SetEraseWidgetTextBackground(info->fEraseTextWidgetBackground);
|
||||||
|
Show(info, fView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BackgroundImage::Show(BackgroundImageInfo *info, BView *view)
|
||||||
|
{
|
||||||
|
BRect viewBounds(view->Bounds());
|
||||||
|
BRect bitmapBounds(info->fBitmap->Bounds());
|
||||||
|
BRect destinationBitmapBounds(bitmapBounds);
|
||||||
|
|
||||||
|
uint32 tile = 0;
|
||||||
|
uint32 followFlags = B_FOLLOW_TOP | B_FOLLOW_LEFT;
|
||||||
|
|
||||||
|
// figure out the display mode and the destination bounds for the bitmap
|
||||||
|
switch (info->fMode) {
|
||||||
|
case kCentered:
|
||||||
|
if (fIsDesktop) {
|
||||||
|
destinationBitmapBounds.OffsetBy(
|
||||||
|
(viewBounds.Width() - bitmapBounds.Width()) / 2,
|
||||||
|
(viewBounds.Height() - bitmapBounds.Height()) / 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// else fall thru
|
||||||
|
case kScaledToFit:
|
||||||
|
if (fIsDesktop) {
|
||||||
|
destinationBitmapBounds = viewBounds;
|
||||||
|
followFlags = B_FOLLOW_ALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// else fall thru
|
||||||
|
case kAtOffset:
|
||||||
|
destinationBitmapBounds.OffsetTo(info->fOffset);
|
||||||
|
break;
|
||||||
|
case kTiled:
|
||||||
|
if (fIsDesktop) {
|
||||||
|
destinationBitmapBounds.OffsetBy(
|
||||||
|
(viewBounds.Width() - bitmapBounds.Width()) / 2,
|
||||||
|
(viewBounds.Height() - bitmapBounds.Height()) / 2);
|
||||||
|
}
|
||||||
|
tile = B_TILE_BITMAP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPoseView *poseView = dynamic_cast<BPoseView *>(view);
|
||||||
|
if (poseView)
|
||||||
|
poseView->SetEraseWidgetTextBackground(info->fEraseTextWidgetBackground);
|
||||||
|
|
||||||
|
// switch to the bitmap and force a redraw
|
||||||
|
view->SetViewBitmap(info->fBitmap, bitmapBounds, destinationBitmapBounds,
|
||||||
|
followFlags, tile);
|
||||||
|
view->Invalidate();
|
||||||
|
|
||||||
|
fShowingBitmap = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BackgroundImage::Remove()
|
||||||
|
{
|
||||||
|
if (fShowingBitmap) {
|
||||||
|
fView->ClearViewBitmap();
|
||||||
|
fView->Invalidate();
|
||||||
|
BPoseView *poseView = dynamic_cast<BPoseView *>(fView);
|
||||||
|
// make sure text widgets draw the default way, erasing their background
|
||||||
|
if (poseView)
|
||||||
|
poseView->SetEraseWidgetTextBackground(true);
|
||||||
|
}
|
||||||
|
fShowingBitmap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundImage::BackgroundImageInfo *
|
||||||
|
BackgroundImage::ImageInfoForWorkspace(int32 workspace) const
|
||||||
|
{
|
||||||
|
uint32 workspaceMask = 1;
|
||||||
|
|
||||||
|
for ( ; workspace; workspace--)
|
||||||
|
workspaceMask *= 2;
|
||||||
|
|
||||||
|
int32 count = fBitmapForWorkspaceList.CountItems();
|
||||||
|
|
||||||
|
// do a simple lookup for the most likely candidate bitmap -
|
||||||
|
// pick the imageInfo that is only defined for this workspace over one
|
||||||
|
// that supports multiple workspaces
|
||||||
|
BackgroundImageInfo *result = NULL;
|
||||||
|
for (int32 index = 0; index < count; index++) {
|
||||||
|
BackgroundImageInfo *info = fBitmapForWorkspaceList.ItemAt(index);
|
||||||
|
if (info->fWorkspace == workspaceMask)
|
||||||
|
return info;
|
||||||
|
if (info->fWorkspace & workspaceMask)
|
||||||
|
result = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BackgroundImage::WorkspaceActivated(BView *view, int32 workspace, bool state)
|
||||||
|
{
|
||||||
|
if (!fIsDesktop)
|
||||||
|
// we only care for desktop bitmaps
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!state)
|
||||||
|
// we only care comming into a new workspace, not leaving one
|
||||||
|
return;
|
||||||
|
|
||||||
|
BackgroundImageInfo *info = ImageInfoForWorkspace(workspace);
|
||||||
|
if (info != fShowingBitmap) {
|
||||||
|
if (info)
|
||||||
|
Show(info, view);
|
||||||
|
else {
|
||||||
|
if (BPoseView *poseView = dynamic_cast<BPoseView *>(view))
|
||||||
|
poseView->SetEraseWidgetTextBackground(true);
|
||||||
|
view->ClearViewBitmap();
|
||||||
|
view->Invalidate();
|
||||||
|
}
|
||||||
|
fShowingBitmap = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BackgroundImage::ScreenChanged(BRect, color_space)
|
||||||
|
{
|
||||||
|
if (!fIsDesktop || !fShowingBitmap)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fShowingBitmap->fMode == kCentered) {
|
||||||
|
BRect viewBounds(fView->Bounds());
|
||||||
|
BRect bitmapBounds(fShowingBitmap->fBitmap->Bounds());
|
||||||
|
BRect destinationBitmapBounds(bitmapBounds);
|
||||||
|
destinationBitmapBounds.OffsetBy(
|
||||||
|
(viewBounds.Width() - bitmapBounds.Width()) / 2,
|
||||||
|
(viewBounds.Height() - bitmapBounds.Height()) / 2);
|
||||||
|
|
||||||
|
fView->SetViewBitmap(fShowingBitmap->fBitmap, bitmapBounds, destinationBitmapBounds,
|
||||||
|
B_FOLLOW_NONE, 0);
|
||||||
|
fView->Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundImage *
|
||||||
|
BackgroundImage::Refresh(BackgroundImage *oldBackgroundImage,
|
||||||
|
const BNode *fromNode, bool desktop, BPoseView *poseView)
|
||||||
|
{
|
||||||
|
if (oldBackgroundImage) {
|
||||||
|
oldBackgroundImage->Remove();
|
||||||
|
delete oldBackgroundImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundImage *result = GetBackgroundImage(fromNode, desktop);
|
||||||
|
if (result && poseView->ViewMode() != kListMode)
|
||||||
|
result->Show(poseView, current_workspace());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Classes used for setting up and managing background images
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __BACKGROUND_IMAGE__
|
||||||
|
#define __BACKGROUND_IMAGE__
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
class BNode;
|
||||||
|
class BView;
|
||||||
|
class BBitmap;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BackgroundImage;
|
||||||
|
class BPoseView;
|
||||||
|
|
||||||
|
extern const char *kBackgroundImageInfo;
|
||||||
|
extern const char *kBackgroundImageInfoOffset;
|
||||||
|
extern const char *kBackgroundImageInfoEraseText;
|
||||||
|
extern const char *kBackgroundImageInfoMode;
|
||||||
|
extern const char *kBackgroundImageInfoWorkspaces;
|
||||||
|
extern const char *kBackgroundImageInfoPath;
|
||||||
|
|
||||||
|
const uint32 kRestoreBackgroundImage = 'Tbgr';
|
||||||
|
|
||||||
|
class BackgroundImage {
|
||||||
|
// This class knows everything about which bitmap to use for a given
|
||||||
|
// view and how.
|
||||||
|
// Unlike other windows, the Desktop window can have different backgrounds
|
||||||
|
// for each workspace
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Mode {
|
||||||
|
kAtOffset,
|
||||||
|
kCentered, // only works on Desktop
|
||||||
|
kScaledToFit, // only works on Desktop
|
||||||
|
kTiled
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundImageInfo {
|
||||||
|
// element of the per-workspace list
|
||||||
|
public:
|
||||||
|
BackgroundImageInfo(uint32 workspace, BBitmap *bitmap, Mode mode, BPoint offset,
|
||||||
|
bool eraseTextWidget);
|
||||||
|
~BackgroundImageInfo();
|
||||||
|
|
||||||
|
uint32 fWorkspace;
|
||||||
|
BBitmap *fBitmap;
|
||||||
|
Mode fMode;
|
||||||
|
BPoint fOffset;
|
||||||
|
bool fEraseTextWidgetBackground;
|
||||||
|
};
|
||||||
|
|
||||||
|
static BackgroundImage *GetBackgroundImage(const BNode *, bool isDesktop);
|
||||||
|
// create a BackgroundImage object by reading it from a node
|
||||||
|
virtual ~BackgroundImage();
|
||||||
|
|
||||||
|
void Show(BView *view, int32 workspace);
|
||||||
|
// display the right background for a given workspace
|
||||||
|
void Remove();
|
||||||
|
// remove the background from it's current view
|
||||||
|
|
||||||
|
void WorkspaceActivated(BView *view, int32 workspace, bool state);
|
||||||
|
// respond to a workspace change
|
||||||
|
void ScreenChanged(BRect , color_space);
|
||||||
|
// respond to a screen size change
|
||||||
|
static BackgroundImage *Refresh(BackgroundImage *oldBackgroundImage,
|
||||||
|
const BNode *fromNode, bool desktop, BPoseView *poseView);
|
||||||
|
// respond to a background image setting change
|
||||||
|
|
||||||
|
private:
|
||||||
|
BackgroundImageInfo *ImageInfoForWorkspace(int32) const;
|
||||||
|
void Show(BackgroundImageInfo *, BView *view);
|
||||||
|
|
||||||
|
BackgroundImage(const BNode *, bool);
|
||||||
|
// no public constructor, GetBackgroundImage factory function is
|
||||||
|
// used instead
|
||||||
|
|
||||||
|
void Add(BackgroundImageInfo *);
|
||||||
|
|
||||||
|
bool fIsDesktop;
|
||||||
|
BNode fDefinedByNode;
|
||||||
|
BView *fView;
|
||||||
|
BackgroundImageInfo *fShowingBitmap;
|
||||||
|
|
||||||
|
BObjectList<BackgroundImageInfo> fBitmapForWorkspaceList;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Autolock.h>
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <DataIO.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include "Bitmaps.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
BImageResources::BImageResources(void *memAddr)
|
||||||
|
{
|
||||||
|
image_id image = find_image(memAddr);
|
||||||
|
image_info info;
|
||||||
|
if (get_image_info(image, &info) == B_OK) {
|
||||||
|
#if _SUPPORTS_RESOURCES
|
||||||
|
BFile file(&info.name[0], B_READ_ONLY);
|
||||||
|
#else
|
||||||
|
BString name(&info.name[0]);
|
||||||
|
name += ".rsrc";
|
||||||
|
BFile file(name.String(), B_READ_ONLY);
|
||||||
|
#endif
|
||||||
|
if (file.InitCheck() == B_OK)
|
||||||
|
fResources.SetTo(&file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BImageResources::~BImageResources()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const BResources *
|
||||||
|
BImageResources::ViewResources() const
|
||||||
|
{
|
||||||
|
if (fLock.Lock() != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &fResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
BResources *
|
||||||
|
BImageResources::ViewResources()
|
||||||
|
{
|
||||||
|
if (fLock.Lock() != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &fResources;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BImageResources::FinishResources(BResources *res) const
|
||||||
|
{
|
||||||
|
ASSERT(res == &fResources);
|
||||||
|
if (res != &fResources)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
fLock.Unlock();
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const void *
|
||||||
|
BImageResources::LoadResource(type_code type, int32 id, size_t *out_size) const
|
||||||
|
{
|
||||||
|
// Serialize execution.
|
||||||
|
// Looks like BResources is not really thread safe. We should
|
||||||
|
// clean that up in the future and remove the locking from here.
|
||||||
|
BAutolock lock(fLock);
|
||||||
|
if (!lock.IsLocked())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Return the resource. Because we never change the BResources
|
||||||
|
// object, the returned data will not change until TTracker is
|
||||||
|
// destroyed.
|
||||||
|
return const_cast<BResources *>(&fResources)->LoadResource(type, id, out_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
const void *
|
||||||
|
BImageResources::LoadResource(type_code type, const char *name, size_t *out_size) const
|
||||||
|
{
|
||||||
|
// Serialize execution.
|
||||||
|
BAutolock lock(fLock);
|
||||||
|
if (!lock.IsLocked())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// Return the resource. Because we never change the BResources
|
||||||
|
// object, the returned data will not change until TTracker is
|
||||||
|
// destroyed.
|
||||||
|
return const_cast<BResources *>(&fResources)->LoadResource(type, name, out_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BImageResources::GetIconResource(int32 id, icon_size size, BBitmap *dest) const
|
||||||
|
{
|
||||||
|
if (size != B_LARGE_ICON && size != B_MINI_ICON )
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
const void *data = LoadResource(size == B_LARGE_ICON ? 'ICON' : 'MICN',
|
||||||
|
id, &len);
|
||||||
|
|
||||||
|
if (data == 0 || len != (size_t)(size == B_LARGE_ICON ? 1024 : 256)) {
|
||||||
|
TRESPASS();
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest->SetBits(data, (int32)len, 0, kDefaultIconDepth);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
image_id
|
||||||
|
BImageResources::find_image(void *memAddr) const
|
||||||
|
{
|
||||||
|
image_info info;
|
||||||
|
int32 cookie = 0;
|
||||||
|
while (get_next_image_info(0, &cookie, &info) == B_OK)
|
||||||
|
if ((info.text <= memAddr && (((uint8 *)info.text)+info.text_size) > memAddr)
|
||||||
|
||(info.data <= memAddr && (((uint8 *)info.data)+info.data_size) > memAddr))
|
||||||
|
// Found the image.
|
||||||
|
return info.id;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BImageResources::GetBitmapResource(type_code type, int32 id, BBitmap **out) const
|
||||||
|
{
|
||||||
|
*out = NULL;
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
const void *data = LoadResource(type, id, &len);
|
||||||
|
|
||||||
|
if (data == NULL) {
|
||||||
|
TRESPASS();
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMemoryIO stream(data, len);
|
||||||
|
|
||||||
|
// Try to read as an archived bitmap.
|
||||||
|
stream.Seek(0, SEEK_SET);
|
||||||
|
BMessage archive;
|
||||||
|
status_t err = archive.Unflatten(&stream);
|
||||||
|
if (err != B_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
*out = new BBitmap(&archive);
|
||||||
|
if (!*out)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
err = (*out)->InitCheck();
|
||||||
|
if (err != B_OK) {
|
||||||
|
delete *out;
|
||||||
|
*out = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static BLocker resLock;
|
||||||
|
static BImageResources *resources = NULL;
|
||||||
|
|
||||||
|
// This class is used as a static instance to delete the resources
|
||||||
|
// global object when the image is getting unloaded.
|
||||||
|
class _TTrackerCleanupResources
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
_TTrackerCleanupResources() { }
|
||||||
|
~_TTrackerCleanupResources()
|
||||||
|
{
|
||||||
|
delete resources;
|
||||||
|
resources = NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
static _TTrackerCleanupResources CleanupResources;
|
||||||
|
|
||||||
|
|
||||||
|
BImageResources *GetTrackerResources()
|
||||||
|
{
|
||||||
|
if (!resources) {
|
||||||
|
BAutolock lock(&resLock);
|
||||||
|
resources = new BImageResources(&resources);
|
||||||
|
}
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
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 __BITS__
|
||||||
|
#define __BITS__
|
||||||
|
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <Resources.h>
|
||||||
|
#include <Mime.h>
|
||||||
|
#include <image.h>
|
||||||
|
|
||||||
|
#include "TrackerIcons.h"
|
||||||
|
|
||||||
|
class BBitmap;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
// This maps the old tracker resource ID definitions to the new ones
|
||||||
|
// generated by QuickRes. Somebody want to go through the code and
|
||||||
|
// get rid of all these?
|
||||||
|
enum {
|
||||||
|
kResAppIcon = R_AppIcon,
|
||||||
|
kResFileIcon = R_FileIcon,
|
||||||
|
kResFolderIcon = 1,
|
||||||
|
kResTrashIcon = R_TrashIcon,
|
||||||
|
kResTrashFullIcon = R_TrashFullIcon,
|
||||||
|
kResQueryIcon = 2,
|
||||||
|
kResQueryTemplateIcon = 4,
|
||||||
|
kResPrinterIcon = R_PrinterIcon,
|
||||||
|
kResBarberPoleBitmap = R_BarberPoleBitmap,
|
||||||
|
kResFloppyIcon = R_FloppyIcon,
|
||||||
|
kResHardDiskIcon = 3,
|
||||||
|
kResCDIcon = R_CDIcon,
|
||||||
|
kResBeBoxIcon = R_BeBoxIcon,
|
||||||
|
kResBookmarkIcon = R_BookmarkIcon,
|
||||||
|
kResPersonIcon = R_PersonIcon,
|
||||||
|
kResBrokenLinkIcon = R_BrokenLinkIcon,
|
||||||
|
kResDeskIcon = R_DeskIcon,
|
||||||
|
kResHomeDirIcon = R_HomeDirIcon,
|
||||||
|
kResBeosFolderIcon = R_BeosFolderIcon,
|
||||||
|
kResBootVolumeIcon = R_BootVolumeIcon,
|
||||||
|
kResFontDirIcon = R_FontDirIcon,
|
||||||
|
kResAppsDirIcon = R_AppsDirIcon,
|
||||||
|
kResPrefsDirIcon = R_PrefsDirIcon,
|
||||||
|
kResMailDirIcon = R_MailDirIcon,
|
||||||
|
kResQueryDirIcon = R_QueryDirIcon,
|
||||||
|
kResSpoolFileIcon = R_SpoolFileIcon,
|
||||||
|
kResGenericPrinterIcon = R_GenericPrinterIcon,
|
||||||
|
kResDevelopDirIcon = R_DevelopDirIcon,
|
||||||
|
kResDownloadDirIcon = R_DownloadDirIcon,
|
||||||
|
kResPersonDirIcon = R_PersonDirIcon,
|
||||||
|
kResUtilDirIcon = R_UtilDirIcon,
|
||||||
|
kResConfigDirIcon = R_ConfigDirIcon,
|
||||||
|
kResMoveStatusBitmap = R_MoveStatusBitmap,
|
||||||
|
kResCopyStatusBitmap = R_CopyStatusBitmap,
|
||||||
|
kResTrashStatusBitmap = R_TrashStatusBitmap,
|
||||||
|
kResBackNavActive = R_ResBackNavActive,
|
||||||
|
kResBackNavInactive = R_ResBackNavInactive,
|
||||||
|
kResForwNavActive = R_ResForwNavActive,
|
||||||
|
kResForwNavInactive = R_ResForwNavInactive,
|
||||||
|
kResUpNavActive = R_ResUpNavActive,
|
||||||
|
kResUpNavInactive = R_ResUpNavInactive,
|
||||||
|
kResBackNavActiveSel = R_ResBackNavActiveSel,
|
||||||
|
kResForwNavActiveSel = R_ResForwNavActiveSel,
|
||||||
|
kResUpNavActiveSel = R_ResUpNavActiveSel,
|
||||||
|
kResShareIcon = R_ShareIcon
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BImageResources
|
||||||
|
{
|
||||||
|
// convenience class for accessing
|
||||||
|
public:
|
||||||
|
BImageResources(void *memAddr);
|
||||||
|
~BImageResources();
|
||||||
|
|
||||||
|
BResources *ViewResources();
|
||||||
|
const BResources *ViewResources() const;
|
||||||
|
|
||||||
|
status_t FinishResources(BResources *) const;
|
||||||
|
|
||||||
|
const void *LoadResource(type_code type, int32 id,
|
||||||
|
size_t *outSize) const;
|
||||||
|
const void *LoadResource(type_code type, const char *name,
|
||||||
|
size_t *outSize) const;
|
||||||
|
// load a resource from the Tracker executable, just like the
|
||||||
|
// corresponding functions in BResources. These methods are
|
||||||
|
// thread-safe.
|
||||||
|
|
||||||
|
status_t GetIconResource(int32 id, icon_size size, BBitmap *dest) const;
|
||||||
|
// this is a wrapper around LoadResource(), for retrieving
|
||||||
|
// B_LARGE_ICON and B_MINI_ICON ('ICON' and 'MICN' respectively)
|
||||||
|
// resources. this does sanity checking on the found data,
|
||||||
|
// and if all is okay blasts it into the 'dest' bitmap.
|
||||||
|
|
||||||
|
status_t GetBitmapResource(type_code type, int32 id, BBitmap **out) const;
|
||||||
|
// this is a wrapper around LoadResource(), for retrieving
|
||||||
|
// arbitrary bitmaps. the resource with the given type and
|
||||||
|
// id is looked up, and a BBitmap created from it and returned
|
||||||
|
// in <out>. currently it can only create bitmaps from data
|
||||||
|
// that is an archived bitmap object.
|
||||||
|
|
||||||
|
private:
|
||||||
|
image_id find_image(void *memAddr) const;
|
||||||
|
|
||||||
|
mutable BLocker fLock;
|
||||||
|
BResources fResources;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern
|
||||||
|
#if !B_BEOS_VERSION_DANO
|
||||||
|
_IMPEXP_TRACKER
|
||||||
|
#endif
|
||||||
|
BImageResources* GetTrackerResources();
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
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 _COMMANDS_H
|
||||||
|
#define _COMMANDS_H
|
||||||
|
|
||||||
|
#include "PublicCommands.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
// external app messages
|
||||||
|
|
||||||
|
const uint32 kGetInfo = 'Tinf';
|
||||||
|
const uint32 kMoveToTrash = 'Ttrs';
|
||||||
|
const uint32 kDelete = 'Tdel';
|
||||||
|
const uint32 kRestoreFromTrash = 'Tres';
|
||||||
|
const uint32 kIdentifyEntry = 'Tidt';
|
||||||
|
const uint32 kOpenSelection = 'Tosl';
|
||||||
|
const uint32 kOpenSelectionWith = 'Tosu';
|
||||||
|
const uint32 kCloseAllWindows = 'Tall';
|
||||||
|
const uint32 kCloseWindowAndChildren = 'Tcwc';
|
||||||
|
|
||||||
|
// end external app messages
|
||||||
|
|
||||||
|
const uint32 kRestoreState = 'Trst';
|
||||||
|
|
||||||
|
const uint32 kCutMoreSelectionToClipboard = 'Tmvm';
|
||||||
|
const uint32 kCopyMoreSelectionToClipboard = 'Tcpm';
|
||||||
|
const uint32 kPasteLinksFromClipboard = 'Tplc';
|
||||||
|
const uint32 kCancelSelectionToClipboard = 'Tesc';
|
||||||
|
const uint32 kClipboardPosesChanged = 'Tcpc';
|
||||||
|
|
||||||
|
const uint32 kEditItem = 'Tedt';
|
||||||
|
const uint32 kEditQuery = 'Qedt';
|
||||||
|
const uint32 kNewFolder = 'Tnwf';
|
||||||
|
const uint32 kNewEntryFromTemplate = 'Tnwe';
|
||||||
|
const uint32 kCopySelectionTo = 'Tcsl';
|
||||||
|
const uint32 kMoveSelectionTo = 'Tmsl';
|
||||||
|
const uint32 kCreateLink = 'Tlnk';
|
||||||
|
const uint32 kCreateRelativeLink = 'Trln';
|
||||||
|
const uint32 kDuplicateSelection = 'Tdsl';
|
||||||
|
const uint32 kLoadAddOn = 'Tlda';
|
||||||
|
const uint32 kEmptyTrash = 'Tetr';
|
||||||
|
const uint32 kAddPrinter = 'Tadp';
|
||||||
|
const uint32 kMakeActivePrinter = 'Tmap';
|
||||||
|
|
||||||
|
const uint32 kUnmountVolume = 'Tunm';
|
||||||
|
const uint32 kRunAutomounterSettings = 'Tram';
|
||||||
|
|
||||||
|
const uint32 kOpenParentDir = 'Topt';
|
||||||
|
const uint32 kOpenDir = 'Topd';
|
||||||
|
const uint32 kCleanup = 'Tcln';
|
||||||
|
const uint32 kCleanupAll = 'Tcla';
|
||||||
|
const uint32 kResizeToFit = 'Trtf';
|
||||||
|
const uint32 kSelectMatchingEntries = 'Tsme';
|
||||||
|
const uint32 kShowSelectionWindow = 'Tssw';
|
||||||
|
const uint32 kShowSettingsWindow = 'Tstw';
|
||||||
|
const uint32 kInvertSelection = 'Tisl';
|
||||||
|
|
||||||
|
const uint32 kCancelButton = 'Tcnl';
|
||||||
|
const uint32 kDefaultButton = 'Tact';
|
||||||
|
const uint32 kPauseButton = 'Tpaw';
|
||||||
|
const uint32 kStopButton = 'Tstp';
|
||||||
|
const uint32 kCopyAttributes = 'Tcat';
|
||||||
|
const uint32 kPasteAttributes = 'Tpat';
|
||||||
|
const uint32 kAttributeItem = 'Tatr';
|
||||||
|
const uint32 kMIMETypeItem = 'Tmim';
|
||||||
|
const uint32 kAddCurrentDir = 'Tadd';
|
||||||
|
const uint32 kSwitchDirectory = 'Tswd';
|
||||||
|
const uint32 kQuitTracker = 'Tqit';
|
||||||
|
|
||||||
|
const uint32 kContextMenuDragNDrop = '_dnd';
|
||||||
|
|
||||||
|
const uint32 kSwitchToHome = 'Tswh';
|
||||||
|
|
||||||
|
const uint32 kTestIconCache = 'TicC';
|
||||||
|
|
||||||
|
// Observers and Notifiers:
|
||||||
|
|
||||||
|
// Settings-changed messages:
|
||||||
|
const uint32 kDisksIconChanged = 'Dicn';
|
||||||
|
const uint32 kDesktopIntegrationChanged = 'Dint';
|
||||||
|
const uint32 kShowDisksIconChanged = 'Sdic';
|
||||||
|
const uint32 kVolumesOnDesktopChanged = 'Codc';
|
||||||
|
const uint32 kEjectWhenUnmountingChanged = 'Ewum';
|
||||||
|
|
||||||
|
const uint32 kWindowsShowFullPathChanged = 'Wsfp';
|
||||||
|
const uint32 kSingleWindowBrowseChanged = 'Osmw';
|
||||||
|
const uint32 kShowNavigatorChanged = 'Snvc';
|
||||||
|
const uint32 kShowSelectionWhenInactiveChanged = 'Sswi';
|
||||||
|
const uint32 kTransparentSelectionChanged = 'Trse';
|
||||||
|
const uint32 kSortFolderNamesFirstChanged = 'Sfnf';
|
||||||
|
|
||||||
|
const uint32 kDesktopFilePanelRootChanged = 'Dfpr';
|
||||||
|
const uint32 kFavoriteCountChanged = 'Fvct';
|
||||||
|
const uint32 kFavoriteCountChangedExternally = 'Fvcx';
|
||||||
|
|
||||||
|
const uint32 kDateFormatChanged = 'Date';
|
||||||
|
|
||||||
|
const uint32 kUpdateVolumeSpaceBar = 'UpSB';
|
||||||
|
const uint32 kShowVolumeSpaceBar = 'ShSB';
|
||||||
|
const uint32 kSpaceBarColorChanged = 'SBcc';
|
||||||
|
|
||||||
|
const uint32 kDontMoveFilesToTrashChanged = 'STdm';
|
||||||
|
const uint32 kAskBeforeDeleteFileChanged = 'STad';
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,421 @@
|
|||||||
|
/*
|
||||||
|
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 _CONTAINER_WINDOW_H
|
||||||
|
#define _CONTAINER_WINDOW_H
|
||||||
|
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "LockingList.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "SlowContextPopup.h"
|
||||||
|
#include "TaskLoop.h"
|
||||||
|
|
||||||
|
class BPopUpMenu;
|
||||||
|
class BMenuBar;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BNavigator;
|
||||||
|
class BPoseView;
|
||||||
|
class ModelMenuItem;
|
||||||
|
class AttributeStreamNode;
|
||||||
|
class BackgroundImage;
|
||||||
|
class Model;
|
||||||
|
class ModelNodeLazyOpener;
|
||||||
|
class SelectionWindow;
|
||||||
|
|
||||||
|
#define kDefaultFolderTemplate "DefaultFolderTemplate"
|
||||||
|
|
||||||
|
extern const char *kAddOnsMenuName;
|
||||||
|
|
||||||
|
const window_feel kPrivateDesktopWindowFeel = window_feel(1024);
|
||||||
|
const window_look kPrivateDesktopWindowLook = window_look(4);
|
||||||
|
// this is a mirror of an app server private values
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// flags that describe opening of the window
|
||||||
|
kRestoreWorkspace = 0x1,
|
||||||
|
kIsHidden = 0x2
|
||||||
|
// set when opening a window during initial Tracker start
|
||||||
|
};
|
||||||
|
|
||||||
|
class BContainerWindow : public BWindow {
|
||||||
|
public:
|
||||||
|
BContainerWindow(LockingList<BWindow> *windowList,
|
||||||
|
uint32 containerWindowFlags,
|
||||||
|
window_look look = B_DOCUMENT_WINDOW_LOOK,
|
||||||
|
window_feel feel = B_NORMAL_WINDOW_FEEL,
|
||||||
|
uint32 flags = B_WILL_ACCEPT_FIRST_CLICK | B_NO_WORKSPACE_ACTIVATION,
|
||||||
|
uint32 workspace = B_CURRENT_WORKSPACE);
|
||||||
|
|
||||||
|
virtual ~BContainerWindow();
|
||||||
|
|
||||||
|
virtual void Init(const BMessage *message = NULL);
|
||||||
|
|
||||||
|
static BRect InitialWindowRect(window_feel);
|
||||||
|
|
||||||
|
virtual void Minimize(bool minimize);
|
||||||
|
virtual void Quit();
|
||||||
|
virtual bool QuitRequested();
|
||||||
|
|
||||||
|
virtual void UpdateIfTrash(Model *);
|
||||||
|
|
||||||
|
virtual void CreatePoseView(Model *);
|
||||||
|
|
||||||
|
virtual void ShowContextMenu(BPoint, const entry_ref *, BView *);
|
||||||
|
virtual uint32 ShowDropContextMenu(BPoint);
|
||||||
|
virtual void MenusBeginning();
|
||||||
|
virtual void MenusEnded();
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
virtual void FrameResized(float, float);
|
||||||
|
virtual void FrameMoved(BPoint);
|
||||||
|
virtual void Zoom(BPoint, float, float);
|
||||||
|
virtual void WorkspacesChanged(uint32, uint32);
|
||||||
|
|
||||||
|
// virtuals that control setup of window
|
||||||
|
virtual bool ShouldAddMenus() const;
|
||||||
|
virtual bool ShouldAddScrollBars() const;
|
||||||
|
virtual bool ShouldAddCountView() const;
|
||||||
|
|
||||||
|
virtual void CheckScreenIntersect();
|
||||||
|
|
||||||
|
bool IsTrash() const;
|
||||||
|
bool InTrash() const;
|
||||||
|
bool IsPrintersDir() const;
|
||||||
|
|
||||||
|
virtual bool IsShowing(const node_ref *) const;
|
||||||
|
virtual bool IsShowing(const entry_ref *) const;
|
||||||
|
|
||||||
|
void ResizeToFit();
|
||||||
|
|
||||||
|
Model *TargetModel() const;
|
||||||
|
BPoseView *PoseView() const;
|
||||||
|
BNavigator *Navigator() const;
|
||||||
|
|
||||||
|
virtual void SelectionChanged();
|
||||||
|
virtual void ViewModeChanged(uint32 oldMode, uint32 newMode);
|
||||||
|
|
||||||
|
virtual void RestoreState();
|
||||||
|
virtual void RestoreState(const BMessage &);
|
||||||
|
void RestoreStateCommon();
|
||||||
|
virtual void SaveState(bool hide = true);
|
||||||
|
virtual void SaveState(BMessage &) const;
|
||||||
|
void UpdateTitle();
|
||||||
|
|
||||||
|
bool StateNeedsSaving() const;
|
||||||
|
bool SaveStateIsEnabled() const;
|
||||||
|
void SetSaveStateEnabled(bool);
|
||||||
|
|
||||||
|
void UpdateBackgroundImage();
|
||||||
|
|
||||||
|
static status_t GetLayoutState(BNode *, BMessage *);
|
||||||
|
static status_t SetLayoutState(BNode *, const BMessage *);
|
||||||
|
// calls for inheriting window size, attribute layout, etc.
|
||||||
|
// deprecated
|
||||||
|
|
||||||
|
virtual void AddMimeTypesToMenu(BMenu *);
|
||||||
|
void AddMimeTypesToMenu();
|
||||||
|
virtual void MarkAttributeMenu(BMenu *);
|
||||||
|
void MarkAttributeMenu();
|
||||||
|
BMenuItem *NewAttributeMenuItem (const char *label, const char *attrName, int32 attrType,
|
||||||
|
float attrWidth, int32 attrAlign, bool attrEditable, bool attrStatField);
|
||||||
|
virtual void NewAttributeMenu(BMenu *);
|
||||||
|
|
||||||
|
void HideAttributeMenu();
|
||||||
|
void ShowAttributeMenu();
|
||||||
|
PiggybackTaskLoop *DelayedTaskLoop();
|
||||||
|
// use for RunLater queueing
|
||||||
|
void PulseTaskLoop();
|
||||||
|
// called by some view that has pulse, either BackgroundView or BPoseView
|
||||||
|
|
||||||
|
static bool DefaultStateSourceNode(const char *name, BNode *result,
|
||||||
|
bool createNew = false, bool createFolder = true);
|
||||||
|
|
||||||
|
// add-on iteration
|
||||||
|
void EachAddon(bool(*)(const Model *, const char *, uint32 shortcut, bool primary, void *), void *);
|
||||||
|
|
||||||
|
BPopUpMenu *ContextMenu();
|
||||||
|
|
||||||
|
// drag&drop support
|
||||||
|
status_t DragStart(const BMessage *);
|
||||||
|
void DragStop();
|
||||||
|
bool Dragging() const;
|
||||||
|
BMessage *DragMessage() const;
|
||||||
|
|
||||||
|
void ShowSelectionWindow();
|
||||||
|
|
||||||
|
void ShowNavigator(bool);
|
||||||
|
void SetSingleWindowBrowseShortcuts(bool);
|
||||||
|
|
||||||
|
void SetPathWatchingEnabled(bool);
|
||||||
|
bool IsPathWatchingEnabled(void) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual BPoseView *NewPoseView(Model *, BRect, uint32);
|
||||||
|
// instantiate a different flavor of BPoseView for different
|
||||||
|
// ContainerWindows
|
||||||
|
|
||||||
|
virtual void RestoreWindowState(AttributeStreamNode *);
|
||||||
|
virtual void RestoreWindowState(const BMessage &);
|
||||||
|
virtual void SaveWindowState(AttributeStreamNode *);
|
||||||
|
virtual void SaveWindowState(BMessage &) const;
|
||||||
|
|
||||||
|
virtual bool NeedsDefaultStateSetup();
|
||||||
|
virtual void SetUpDefaultState();
|
||||||
|
// these two virtuals control setting up a new folder that
|
||||||
|
// does not have any state settings yet with the default
|
||||||
|
|
||||||
|
virtual void AddMenus();
|
||||||
|
virtual void AddShortcuts();
|
||||||
|
// add equivalents of the menu shortcuts to the menuless desktop window
|
||||||
|
virtual void AddFileMenu(BMenu *menu);
|
||||||
|
virtual void AddWindowMenu(BMenu *menu);
|
||||||
|
|
||||||
|
virtual void AddContextMenus();
|
||||||
|
|
||||||
|
virtual void AddFileContextMenus(BMenu *);
|
||||||
|
virtual void AddWindowContextMenus(BMenu *);
|
||||||
|
virtual void AddVolumeContextMenus(BMenu *);
|
||||||
|
virtual void AddDropContextMenus(BMenu *);
|
||||||
|
|
||||||
|
virtual void RepopulateMenus();
|
||||||
|
|
||||||
|
virtual void SetCutItem(BMenu *);
|
||||||
|
virtual void SetCopyItem(BMenu *);
|
||||||
|
virtual void SetPasteItem(BMenu *);
|
||||||
|
virtual void SetCleanUpItem(BMenu *);
|
||||||
|
virtual void SetCloseItem(BMenu *);
|
||||||
|
virtual void SetupNavigationMenu(const entry_ref *, BMenu *);
|
||||||
|
virtual void SetupMoveCopyMenus(const entry_ref *, BMenu *);
|
||||||
|
virtual void PopulateMoveCopyNavMenu(BNavMenu *, uint32, const entry_ref *, bool);
|
||||||
|
|
||||||
|
virtual void SetupOpenWithMenu(BMenu *);
|
||||||
|
virtual void SetUpEditQueryItem(BMenu *);
|
||||||
|
virtual void SetUpDiskMenu(BMenu *);
|
||||||
|
|
||||||
|
virtual void BuildAddOnMenu(BMenu *);
|
||||||
|
|
||||||
|
enum UpdateMenuContext {
|
||||||
|
kMenuBarContext,
|
||||||
|
kPosePopUpContext,
|
||||||
|
kWindowPopUpContext
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void UpdateMenu(BMenu *menu, UpdateMenuContext context);
|
||||||
|
|
||||||
|
BHandler *ResolveSpecifier(BMessage *, int32, BMessage *, int32,
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
bool EachAddon(BPath &path, bool(*)(const Model *, const char *, uint32, bool, void *),
|
||||||
|
BObjectList<Model> *, void *);
|
||||||
|
void LoadAddOn(BMessage *);
|
||||||
|
|
||||||
|
BPopUpMenu *fFileContextMenu;
|
||||||
|
BPopUpMenu *fWindowContextMenu;
|
||||||
|
BPopUpMenu *fDropContextMenu;
|
||||||
|
BPopUpMenu *fVolumeContextMenu;
|
||||||
|
BSlowContextMenu *fDragContextMenu;
|
||||||
|
BMenuItem *fMoveToItem;
|
||||||
|
BMenuItem *fCopyToItem;
|
||||||
|
BMenuItem *fCreateLinkItem;
|
||||||
|
BMenuItem *fOpenWithItem;
|
||||||
|
ModelMenuItem *fNavigationItem;
|
||||||
|
BMenuBar *fMenuBar;
|
||||||
|
BNavigator *fNavigator;
|
||||||
|
BPoseView *fPoseView;
|
||||||
|
LockingList<BWindow> *fWindowList;
|
||||||
|
BMenu *fAttrMenu;
|
||||||
|
BMenu *fWindowMenu;
|
||||||
|
BMenu *fFileMenu;
|
||||||
|
|
||||||
|
SelectionWindow *fSelectionWindow;
|
||||||
|
|
||||||
|
PiggybackTaskLoop *fTaskLoop;
|
||||||
|
|
||||||
|
bool fIsTrash;
|
||||||
|
bool fInTrash;
|
||||||
|
bool fIsPrinters;
|
||||||
|
|
||||||
|
uint32 fContainerWindowFlags;
|
||||||
|
BackgroundImage *fBackgroundImage;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BRect fSavedZoomRect;
|
||||||
|
|
||||||
|
static BRect sNewWindRect;
|
||||||
|
|
||||||
|
BPopUpMenu *fContextMenu;
|
||||||
|
BMessage *fDragMessage;
|
||||||
|
BObjectList<BString> *fCachedTypesList;
|
||||||
|
bool fWaitingForRefs;
|
||||||
|
|
||||||
|
bool fStateNeedsSaving;
|
||||||
|
bool fSaveStateIsEnabled;
|
||||||
|
|
||||||
|
bool fIsWatchingPath;
|
||||||
|
|
||||||
|
typedef BWindow _inherited;
|
||||||
|
|
||||||
|
friend int32 show_context_menu(void*);
|
||||||
|
friend class BackgroundView;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WindowStateNodeOpener {
|
||||||
|
// this class manages opening and closing the proper node for
|
||||||
|
// state restoring / saving; the constructor knows how to decide wether
|
||||||
|
// to use a special directory for root, etc.
|
||||||
|
// setter calls used when no attributes can be read from a node and defaults
|
||||||
|
// are to be substituted
|
||||||
|
public:
|
||||||
|
WindowStateNodeOpener(BContainerWindow *window, bool forWriting);
|
||||||
|
virtual ~WindowStateNodeOpener();
|
||||||
|
|
||||||
|
void SetTo(const BDirectory *);
|
||||||
|
void SetTo(const BEntry *entry, bool forWriting);
|
||||||
|
void SetTo(Model *, bool forWriting);
|
||||||
|
|
||||||
|
AttributeStreamNode *StreamNode() const;
|
||||||
|
BNode *Node() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ModelNodeLazyOpener *fModelOpener;
|
||||||
|
BNode *fNode;
|
||||||
|
AttributeStreamNode *fStreamNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundView : public BView {
|
||||||
|
// background view placed in a BContainerWindow, under the pose view
|
||||||
|
public:
|
||||||
|
BackgroundView(BRect);
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void FrameResized(float, float);
|
||||||
|
virtual void Draw(BRect);
|
||||||
|
|
||||||
|
void PoseViewFocused(bool);
|
||||||
|
virtual void Pulse();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void WindowActivated(bool);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef BView _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
int CompareLabels(const BMenuItem *, const BMenuItem *);
|
||||||
|
|
||||||
|
// inlines ---------
|
||||||
|
|
||||||
|
inline BNavigator *
|
||||||
|
BContainerWindow::Navigator() const
|
||||||
|
{
|
||||||
|
return fNavigator;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPoseView *
|
||||||
|
BContainerWindow::PoseView() const
|
||||||
|
{
|
||||||
|
return fPoseView;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BContainerWindow::IsTrash() const
|
||||||
|
{
|
||||||
|
return fIsTrash;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BContainerWindow::InTrash() const
|
||||||
|
{
|
||||||
|
return fInTrash;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BContainerWindow::IsPrintersDir() const
|
||||||
|
{
|
||||||
|
return fIsPrinters;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
BContainerWindow::SetUpDiskMenu(BMenu *)
|
||||||
|
{
|
||||||
|
// nothing at this level
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BPopUpMenu *
|
||||||
|
BContainerWindow::ContextMenu()
|
||||||
|
{
|
||||||
|
return fContextMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BContainerWindow::Dragging() const
|
||||||
|
{
|
||||||
|
return fDragMessage && fCachedTypesList;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline BMessage *
|
||||||
|
BContainerWindow::DragMessage() const
|
||||||
|
{
|
||||||
|
return fDragMessage;
|
||||||
|
}
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
BContainerWindow::SaveStateIsEnabled() const
|
||||||
|
{
|
||||||
|
return fSaveStateIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
BContainerWindow::SetSaveStateEnabled(bool value)
|
||||||
|
{
|
||||||
|
fSaveStateIsEnabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
BContainerWindow::IsPathWatchingEnabled() const
|
||||||
|
{
|
||||||
|
return fIsWatchingPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_result ActivateWindowFilter(BMessage *message, BHandler **target,
|
||||||
|
BMessageFilter *messageFilter);
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// defines the status area drawn in the bottom left corner of a Tracker window
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
|
||||||
|
#include "AutoLock.h"
|
||||||
|
#include "Bitmaps.h"
|
||||||
|
#include "CountView.h"
|
||||||
|
#include "ContainerWindow.h"
|
||||||
|
#include "DirMenu.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
|
||||||
|
BCountView::BCountView(BRect bounds, BPoseView* view)
|
||||||
|
: BView(bounds, "CountVw", B_FOLLOW_LEFT + B_FOLLOW_BOTTOM,
|
||||||
|
B_PULSE_NEEDED | B_WILL_DRAW),
|
||||||
|
fLastCount(-1),
|
||||||
|
fPoseView(view),
|
||||||
|
fShowingBarberPole(false),
|
||||||
|
fBarberPoleMap(NULL),
|
||||||
|
fLastBarberPoleOffset(5),
|
||||||
|
fStartSpinningAfter(0),
|
||||||
|
fTypeAheadString("")
|
||||||
|
|
||||||
|
{
|
||||||
|
GetTrackerResources()->GetBitmapResource(B_MESSAGE_TYPE, kResBarberPoleBitmap,
|
||||||
|
&fBarberPoleMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
BCountView::~BCountView()
|
||||||
|
{
|
||||||
|
delete fBarberPoleMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BCountView::TrySpinningBarberPole()
|
||||||
|
{
|
||||||
|
if (!fShowingBarberPole)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fStartSpinningAfter && system_time() < fStartSpinningAfter)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fStartSpinningAfter) {
|
||||||
|
fStartSpinningAfter = 0;
|
||||||
|
Invalidate(BarberPoleOuterRect());
|
||||||
|
} else
|
||||||
|
Invalidate(BarberPoleInnerRect());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BCountView::Pulse()
|
||||||
|
{
|
||||||
|
TrySpinningBarberPole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BCountView::EndBarberPole()
|
||||||
|
{
|
||||||
|
if (!fShowingBarberPole)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fShowingBarberPole = false;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bigtime_t kBarberPoleDelay = 500000;
|
||||||
|
|
||||||
|
void
|
||||||
|
BCountView::StartBarberPole()
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(Window());
|
||||||
|
if (fShowingBarberPole)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fShowingBarberPole = true;
|
||||||
|
fStartSpinningAfter = system_time() + kBarberPoleDelay;
|
||||||
|
// wait a bit before showing the barber pole
|
||||||
|
}
|
||||||
|
|
||||||
|
BRect
|
||||||
|
BCountView::BarberPoleInnerRect() const
|
||||||
|
{
|
||||||
|
BRect result = Bounds();
|
||||||
|
result.InsetBy(3, 4);
|
||||||
|
result.left = result.right - 7;
|
||||||
|
result.bottom = result.top + 7;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
BRect
|
||||||
|
BCountView::BarberPoleOuterRect() const
|
||||||
|
{
|
||||||
|
BRect result(BarberPoleInnerRect());
|
||||||
|
result.InsetBy(-1, -1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
BRect
|
||||||
|
BCountView::TextInvalRect() const
|
||||||
|
{
|
||||||
|
BRect result = Bounds();
|
||||||
|
result.InsetBy(4, 2);
|
||||||
|
result.right -= 10;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BCountView::CheckCount()
|
||||||
|
{
|
||||||
|
// invalidate the count text area if necessary
|
||||||
|
if (fLastCount != fPoseView->CountItems()) {
|
||||||
|
fLastCount = fPoseView->CountItems();
|
||||||
|
Invalidate(TextInvalRect());
|
||||||
|
}
|
||||||
|
// invalidate barber pole area if necessary
|
||||||
|
TrySpinningBarberPole();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BCountView::Draw(BRect)
|
||||||
|
{
|
||||||
|
BRect bounds(Bounds());
|
||||||
|
BRect barberPoleRect;
|
||||||
|
BString itemString;
|
||||||
|
if (!IsTypingAhead()) {
|
||||||
|
if (fLastCount == 0)
|
||||||
|
itemString << "no items";
|
||||||
|
else if (fLastCount == 1)
|
||||||
|
itemString << "1 item";
|
||||||
|
else
|
||||||
|
itemString << fLastCount << " items";
|
||||||
|
} else
|
||||||
|
itemString << TypeAhead();
|
||||||
|
|
||||||
|
|
||||||
|
BString string(itemString);
|
||||||
|
BRect textRect(TextInvalRect());
|
||||||
|
|
||||||
|
if (fShowingBarberPole && !fStartSpinningAfter) {
|
||||||
|
barberPoleRect = BarberPoleOuterRect();
|
||||||
|
TruncateString(&string, B_TRUNCATE_END, textRect.Width());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsTypingAhead())
|
||||||
|
// use a muted gray for the typeahead
|
||||||
|
SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_4_TINT));
|
||||||
|
else
|
||||||
|
SetHighColor(0, 0, 0);
|
||||||
|
MovePenTo(textRect.LeftBottom());
|
||||||
|
DrawString(string.String());
|
||||||
|
|
||||||
|
bounds.top++;
|
||||||
|
|
||||||
|
rgb_color light = tint_color(ViewColor(), B_LIGHTEN_MAX_TINT);
|
||||||
|
rgb_color shadow = tint_color(ViewColor(), B_DARKEN_2_TINT);
|
||||||
|
rgb_color lightShadow = tint_color(ViewColor(), B_DARKEN_1_TINT);
|
||||||
|
|
||||||
|
BeginLineArray(fShowingBarberPole && !fStartSpinningAfter ? 9 : 5);
|
||||||
|
AddLine(bounds.LeftTop(), bounds.RightTop(), light);
|
||||||
|
AddLine(bounds.LeftTop(), bounds.LeftBottom(), light);
|
||||||
|
bounds.top--;
|
||||||
|
|
||||||
|
AddLine(bounds.LeftTop(), bounds.RightTop(), shadow);
|
||||||
|
AddLine(BPoint(bounds.right, bounds.top + 2), bounds.RightBottom(), lightShadow);
|
||||||
|
AddLine(bounds.LeftBottom(), bounds.RightBottom(), lightShadow);
|
||||||
|
|
||||||
|
if (!fShowingBarberPole || fStartSpinningAfter) {
|
||||||
|
EndLineArray();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddLine(barberPoleRect.LeftTop(), barberPoleRect.RightTop(), shadow);
|
||||||
|
AddLine(barberPoleRect.LeftTop(), barberPoleRect.LeftBottom(), shadow);
|
||||||
|
AddLine(barberPoleRect.LeftBottom(), barberPoleRect.RightBottom(), light);
|
||||||
|
AddLine(barberPoleRect.RightBottom(), barberPoleRect.RightTop(), light);
|
||||||
|
EndLineArray();
|
||||||
|
|
||||||
|
barberPoleRect.InsetBy(1, 1);
|
||||||
|
|
||||||
|
BRect destRect(fBarberPoleMap ? fBarberPoleMap->Bounds() : BRect(0, 0, 0, 0));
|
||||||
|
destRect.OffsetTo(barberPoleRect.LeftTop() - BPoint(0, fLastBarberPoleOffset));
|
||||||
|
fLastBarberPoleOffset -= 1;
|
||||||
|
if (fLastBarberPoleOffset < 0)
|
||||||
|
fLastBarberPoleOffset = 5;
|
||||||
|
|
||||||
|
BRegion region;
|
||||||
|
region.Set(BarberPoleInnerRect());
|
||||||
|
ConstrainClippingRegion(®ion);
|
||||||
|
|
||||||
|
if (fBarberPoleMap)
|
||||||
|
DrawBitmap(fBarberPoleMap, destRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BCountView::MouseDown(BPoint)
|
||||||
|
{
|
||||||
|
BContainerWindow *window = dynamic_cast<BContainerWindow *>(Window());
|
||||||
|
window->Activate();
|
||||||
|
window->UpdateIfNeeded();
|
||||||
|
|
||||||
|
if (fPoseView->IsFilePanel() || !fPoseView->TargetModel())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!window->TargetModel()->IsRoot()) {
|
||||||
|
BDirMenu *menu = new BDirMenu(NULL, B_REFS_RECEIVED);
|
||||||
|
BEntry entry;
|
||||||
|
if (entry.SetTo(window->TargetModel()->EntryRef()) == B_OK)
|
||||||
|
menu->Populate(&entry, Window(), false, false, true, false, true);
|
||||||
|
else
|
||||||
|
menu->Populate(NULL, Window(), false, false, true, false, true);
|
||||||
|
|
||||||
|
menu->SetTargetForItems(be_app);
|
||||||
|
BPoint pop_pt = Bounds().LeftBottom();
|
||||||
|
pop_pt.y += 3;
|
||||||
|
ConvertToScreen(&pop_pt);
|
||||||
|
BRect mouse_rect(Bounds());
|
||||||
|
ConvertToScreen(&mouse_rect);
|
||||||
|
menu->Go(pop_pt, true, true, mouse_rect);
|
||||||
|
delete menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BCountView::AttachedToWindow()
|
||||||
|
{
|
||||||
|
SetFont(be_plain_font);
|
||||||
|
SetFontSize(9);
|
||||||
|
|
||||||
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
SetLowColor(ViewColor());
|
||||||
|
|
||||||
|
CheckCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BCountView::SetTypeAhead(const char *string)
|
||||||
|
{
|
||||||
|
fTypeAheadString = string;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
BCountView::TypeAhead() const
|
||||||
|
{
|
||||||
|
return fTypeAheadString.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BCountView::IsTypingAhead() const
|
||||||
|
{
|
||||||
|
return fTypeAheadString.Length() != 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
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 __COUNT_VIEW__
|
||||||
|
#define __COUNT_VIEW__
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BPoseView;
|
||||||
|
|
||||||
|
class BCountView : public BView {
|
||||||
|
// displays the item count and a barber pole while the view is updating
|
||||||
|
|
||||||
|
public:
|
||||||
|
BCountView(BRect, BPoseView *);
|
||||||
|
~BCountView();
|
||||||
|
|
||||||
|
virtual void Draw(BRect);
|
||||||
|
virtual void MouseDown(BPoint);
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void Pulse();
|
||||||
|
|
||||||
|
void CheckCount();
|
||||||
|
void StartBarberPole();
|
||||||
|
void EndBarberPole();
|
||||||
|
|
||||||
|
void SetTypeAhead(const char *);
|
||||||
|
const char *TypeAhead() const;
|
||||||
|
bool IsTypingAhead() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BRect BarberPoleInnerRect() const;
|
||||||
|
BRect BarberPoleOuterRect() const;
|
||||||
|
BRect TextInvalRect() const;
|
||||||
|
void TrySpinningBarberPole();
|
||||||
|
|
||||||
|
int32 fLastCount;
|
||||||
|
BPoseView *fPoseView;
|
||||||
|
bool fShowingBarberPole;
|
||||||
|
BBitmap *fBarberPoleMap;
|
||||||
|
float fLastBarberPoleOffset;
|
||||||
|
bigtime_t fStartSpinningAfter;
|
||||||
|
BString fTypeAheadString;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,430 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <NodeMonitor.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
#include <Screen.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
#include <VolumeRoster.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "Attributes.h"
|
||||||
|
#include "AutoLock.h"
|
||||||
|
#include "BackgroundImage.h"
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "DesktopPoseView.h"
|
||||||
|
#include "DeskWindow.h"
|
||||||
|
#include "FSUtils.h"
|
||||||
|
#include "IconMenuItem.h"
|
||||||
|
#include "MountMenu.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
#include "TemplatesMenu.h"
|
||||||
|
|
||||||
|
#if OPEN_TRACKER
|
||||||
|
#include "DeviceMap.h"
|
||||||
|
#else
|
||||||
|
#include <private/storage/DeviceMap.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *kShelfPath = "tracker_shelf";
|
||||||
|
// replicant support
|
||||||
|
|
||||||
|
|
||||||
|
BDeskWindow::BDeskWindow(LockingList<BWindow> *windowList)
|
||||||
|
: BContainerWindow(windowList, 0,
|
||||||
|
kPrivateDesktopWindowLook, kPrivateDesktopWindowFeel,
|
||||||
|
B_NOT_MOVABLE | B_WILL_ACCEPT_FIRST_CLICK |
|
||||||
|
B_NOT_CLOSABLE | B_NOT_MINIMIZABLE | B_ASYNCHRONOUS_CONTROLS,
|
||||||
|
B_ALL_WORKSPACES),
|
||||||
|
fDeskShelf(0),
|
||||||
|
fTrashContextMenu(0),
|
||||||
|
fShouldUpdateAddonShortcuts(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BDeskWindow::~BDeskWindow()
|
||||||
|
{
|
||||||
|
SaveDesktopPoseLocations();
|
||||||
|
// explicit call to SavePoseLocations so that extended pose info
|
||||||
|
// gets committed properly
|
||||||
|
PoseView()->DisableSaveLocation();
|
||||||
|
// prevent double-saving, this would slow down quitting
|
||||||
|
PoseView()->StopSettingsWatch();
|
||||||
|
stop_watching(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
WatchAddOnDir(directory_which dirName, BDeskWindow *window)
|
||||||
|
{
|
||||||
|
BPath path;
|
||||||
|
if (find_directory(dirName, &path) == B_OK) {
|
||||||
|
path.Append("Tracker");
|
||||||
|
BNode node(path.Path());
|
||||||
|
node_ref nodeRef;
|
||||||
|
node.GetNodeRef(&nodeRef);
|
||||||
|
TTracker::WatchNode(&nodeRef, B_WATCH_DIRECTORY, window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::Init(const BMessage *)
|
||||||
|
{
|
||||||
|
AddTrashContextMenu();
|
||||||
|
//
|
||||||
|
// Set the size of the screen before calling the container window's
|
||||||
|
// Init() because it will add volume poses to this window and
|
||||||
|
// they will be clipped otherwise
|
||||||
|
//
|
||||||
|
BScreen screen(this);
|
||||||
|
fOldFrame = screen.Frame();
|
||||||
|
|
||||||
|
PoseView()->SetShowHideSelection(false);
|
||||||
|
ResizeTo(fOldFrame.Width(), fOldFrame.Height());
|
||||||
|
|
||||||
|
entry_ref ref;
|
||||||
|
BPath path;
|
||||||
|
if (!BootedInSafeMode() && FSFindTrackerSettingsDir(&path) == B_OK) {
|
||||||
|
path.Append(kShelfPath);
|
||||||
|
close(open(path.Path(), O_RDONLY | O_CREAT));
|
||||||
|
if (get_ref_for_path(path.Path(), &ref) == B_OK)
|
||||||
|
fDeskShelf = new BShelf(&ref, fPoseView);
|
||||||
|
if (fDeskShelf)
|
||||||
|
fDeskShelf->SetDisplaysZombies(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// watch add-on directories so that we can track the addons with
|
||||||
|
// corresponding shortcuts
|
||||||
|
WatchAddOnDir(B_BEOS_ADDONS_DIRECTORY, this);
|
||||||
|
WatchAddOnDir(B_USER_ADDONS_DIRECTORY, this);
|
||||||
|
WatchAddOnDir(B_COMMON_ADDONS_DIRECTORY, this);
|
||||||
|
|
||||||
|
_inherited::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct AddOneShortcutParams {
|
||||||
|
BDeskWindow *window;
|
||||||
|
std::set<uint32> *currentAddonShortcuts;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
AddOneShortcut(const Model *model, const char *, uint32 shortcut, bool /*primary*/, void *context)
|
||||||
|
{
|
||||||
|
if (!shortcut)
|
||||||
|
// no shortcut, bail
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AddOneShortcutParams *params = (AddOneShortcutParams *)context;
|
||||||
|
BMessage *runAddon = new BMessage(kLoadAddOn);
|
||||||
|
runAddon->AddRef("refs", model->EntryRef());
|
||||||
|
|
||||||
|
params->window->AddShortcut(shortcut, B_OPTION_KEY | B_COMMAND_KEY,
|
||||||
|
runAddon);
|
||||||
|
params->currentAddonShortcuts->insert(shortcut);
|
||||||
|
PRINT(("adding new shortcut %c\n", (char)shortcut));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::MenusBeginning()
|
||||||
|
{
|
||||||
|
_inherited::MenusBeginning();
|
||||||
|
|
||||||
|
if (fShouldUpdateAddonShortcuts) {
|
||||||
|
PRINT(("updating addon shortcuts\n"));
|
||||||
|
fShouldUpdateAddonShortcuts = false;
|
||||||
|
|
||||||
|
// remove all current addon shortcuts
|
||||||
|
for (std::set<uint32>::iterator it= fCurrentAddonShortcuts.begin();
|
||||||
|
it != fCurrentAddonShortcuts.end(); it++) {
|
||||||
|
PRINT(("removing shortcut %c\n", *it));
|
||||||
|
RemoveShortcut(*it, B_OPTION_KEY | B_COMMAND_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
fCurrentAddonShortcuts.clear();
|
||||||
|
|
||||||
|
AddOneShortcutParams params;
|
||||||
|
params.window = this;
|
||||||
|
params.currentAddonShortcuts = &fCurrentAddonShortcuts;
|
||||||
|
EachAddon(&AddOneShortcut, ¶ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::Quit()
|
||||||
|
{
|
||||||
|
if (fNavigationItem) {
|
||||||
|
// this duplicates BContainerWindow::Quit because
|
||||||
|
// fNavigationItem can be part of fTrashContextMenu
|
||||||
|
// and would get deleted with it
|
||||||
|
BMenu *menu = fNavigationItem->Menu();
|
||||||
|
if (menu)
|
||||||
|
menu->RemoveItem(fNavigationItem);
|
||||||
|
delete fNavigationItem;
|
||||||
|
fNavigationItem = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete fTrashContextMenu;
|
||||||
|
fTrashContextMenu = NULL;
|
||||||
|
|
||||||
|
delete fDeskShelf;
|
||||||
|
_inherited::Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BPoseView *
|
||||||
|
BDeskWindow::NewPoseView(Model *model, BRect rect, uint32 viewMode)
|
||||||
|
{
|
||||||
|
return new DesktopPoseView(model, rect, viewMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::CreatePoseView(Model *model)
|
||||||
|
{
|
||||||
|
fPoseView = NewPoseView(model, Bounds(), kIconMode);
|
||||||
|
fPoseView->SetIconMapping(false);
|
||||||
|
fPoseView->SetEnsurePosesVisible(true);
|
||||||
|
fPoseView->SetAutoScroll(false);
|
||||||
|
|
||||||
|
BScreen screen(this);
|
||||||
|
rgb_color desktopColor = screen.DesktopColor();
|
||||||
|
if (desktopColor.alpha != 255) {
|
||||||
|
desktopColor.alpha = 255;
|
||||||
|
screen.SetDesktopColor(desktopColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
fPoseView->SetViewColor(desktopColor);
|
||||||
|
fPoseView->SetLowColor(desktopColor);
|
||||||
|
|
||||||
|
AddChild(fPoseView);
|
||||||
|
|
||||||
|
PoseView()->StartSettingsWatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::AddWindowContextMenus(BMenu *menu)
|
||||||
|
{
|
||||||
|
TemplatesMenu *tempateMenu = new TemplatesMenu(PoseView());
|
||||||
|
|
||||||
|
menu->AddItem(tempateMenu);
|
||||||
|
tempateMenu->SetTargetForItems(PoseView());
|
||||||
|
tempateMenu->SetFont(be_plain_font);
|
||||||
|
|
||||||
|
menu->AddSeparatorItem();
|
||||||
|
menu->AddItem(new BMenuItem("Icon View", new BMessage(kIconMode)));
|
||||||
|
menu->AddItem(new BMenuItem("Mini Icon View", new BMessage(kMiniIconMode)));
|
||||||
|
menu->AddSeparatorItem();
|
||||||
|
BMenuItem *pasteItem;
|
||||||
|
menu->AddItem(pasteItem = new BMenuItem("Paste", new BMessage(B_PASTE), 'V'));
|
||||||
|
menu->AddSeparatorItem();
|
||||||
|
menu->AddItem(new BMenuItem("Clean Up", new BMessage(kCleanup), 'K'));
|
||||||
|
menu->AddItem(new BMenuItem("Select"B_UTF8_ELLIPSIS,
|
||||||
|
new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY));
|
||||||
|
menu->AddItem(new BMenuItem("Select All", new BMessage(B_SELECT_ALL), 'A'));
|
||||||
|
|
||||||
|
menu->AddSeparatorItem();
|
||||||
|
menu->AddItem(new MountMenu("Mount"));
|
||||||
|
|
||||||
|
menu->AddSeparatorItem();
|
||||||
|
menu->AddItem(new BMenu(kAddOnsMenuName));
|
||||||
|
|
||||||
|
// target items as needed
|
||||||
|
menu->SetTargetForItems(PoseView());
|
||||||
|
pasteItem->SetTarget(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::AddTrashContextMenu()
|
||||||
|
{
|
||||||
|
// setup special trash context menu
|
||||||
|
fTrashContextMenu = new BPopUpMenu("TrashContext", false, false);
|
||||||
|
fTrashContextMenu->SetFont(be_plain_font);
|
||||||
|
fTrashContextMenu->AddItem(new BMenuItem("Empty Trash",
|
||||||
|
new BMessage(kEmptyTrash)));
|
||||||
|
fTrashContextMenu->AddItem(new BMenuItem("Open",
|
||||||
|
new BMessage(kOpenSelection), 'O'));
|
||||||
|
fTrashContextMenu->AddItem(new BMenuItem("Get Info", new BMessage(kGetInfo), 'I'));
|
||||||
|
fTrashContextMenu->SetTargetForItems(PoseView());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::ShowContextMenu(BPoint loc, const entry_ref *ref, BView *view)
|
||||||
|
{
|
||||||
|
BEntry entry;
|
||||||
|
|
||||||
|
// cleanup previous entries
|
||||||
|
DeleteSubmenu(fNavigationItem);
|
||||||
|
|
||||||
|
if (ref && entry.SetTo(ref) == B_OK && FSIsTrashDir(&entry)) {
|
||||||
|
//
|
||||||
|
// don't show any menu if this is the trash
|
||||||
|
if (Dragging() && FSIsTrashDir(&entry))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// selected item was trash, show the trash context menu instead
|
||||||
|
BPoint global(loc);
|
||||||
|
PoseView()->ConvertToScreen(&global);
|
||||||
|
PoseView()->CommitActivePose();
|
||||||
|
BRect mouse_rect(global.x, global.y, global.x, global.y);
|
||||||
|
mouse_rect.InsetBy(-5, -5);
|
||||||
|
|
||||||
|
EnableNamedMenuItem(fTrashContextMenu, kEmptyTrash,
|
||||||
|
static_cast<TTracker *>(be_app)->TrashFull());
|
||||||
|
|
||||||
|
SetupNavigationMenu(ref, fTrashContextMenu);
|
||||||
|
fTrashContextMenu->Go(global, true, false, mouse_rect, true);
|
||||||
|
} else
|
||||||
|
_inherited::ShowContextMenu(loc, ref, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::WorkspaceActivated(int32 workspace, bool state)
|
||||||
|
{
|
||||||
|
if (fBackgroundImage)
|
||||||
|
fBackgroundImage->WorkspaceActivated(PoseView(), workspace, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::SaveDesktopPoseLocations()
|
||||||
|
{
|
||||||
|
PoseView()->SavePoseLocations(&fOldFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::ScreenChanged(BRect frame, color_space space)
|
||||||
|
{
|
||||||
|
bool frameChanged = (frame != fOldFrame);
|
||||||
|
|
||||||
|
SaveDesktopPoseLocations();
|
||||||
|
fOldFrame = frame;
|
||||||
|
ResizeTo(frame.Width(), frame.Height());
|
||||||
|
|
||||||
|
if (fBackgroundImage)
|
||||||
|
fBackgroundImage->ScreenChanged(frame, space);
|
||||||
|
|
||||||
|
PoseView()->CheckPoseVisibility(frameChanged ? &frame : 0);
|
||||||
|
// if frame changed, pass new frame so that icons can
|
||||||
|
// get rearranged based on old pose info for the frame
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::UpdateDesktopBackgroundImages()
|
||||||
|
{
|
||||||
|
WindowStateNodeOpener opener(this, false);
|
||||||
|
fBackgroundImage = BackgroundImage::Refresh(fBackgroundImage,
|
||||||
|
opener.Node(), true, PoseView());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::Show()
|
||||||
|
{
|
||||||
|
if (fBackgroundImage)
|
||||||
|
fBackgroundImage->Show(PoseView(), current_workspace());
|
||||||
|
|
||||||
|
PoseView()->CheckPoseVisibility();
|
||||||
|
|
||||||
|
_inherited::Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BDeskWindow::ShouldAddScrollBars() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BDeskWindow::ShouldAddMenus() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BDeskWindow::ShouldAddContainerView() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDeskWindow::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
if (message->WasDropped()) {
|
||||||
|
const rgb_color *color;
|
||||||
|
int32 size;
|
||||||
|
// handle "roColour"-style color drops
|
||||||
|
if (message->FindData("RGBColor", 'RGBC',
|
||||||
|
(const void **)&color, &size) == B_OK) {
|
||||||
|
BScreen(this).SetDesktopColor(*color);
|
||||||
|
fPoseView->SetViewColor(*color);
|
||||||
|
fPoseView->SetLowColor(*color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message->what) {
|
||||||
|
case B_NODE_MONITOR:
|
||||||
|
PRINT(("will update addon shortcuts\n"));
|
||||||
|
fShouldUpdateAddonShortcuts = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_inherited::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
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 _DESK_WINDOW_H
|
||||||
|
#define _DESK_WINDOW_H
|
||||||
|
|
||||||
|
#include <Shelf.h>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "ContainerWindow.h"
|
||||||
|
#include "DesktopPoseView.h"
|
||||||
|
|
||||||
|
class BPopUpMenu;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BDeskWindow : public BContainerWindow {
|
||||||
|
public:
|
||||||
|
BDeskWindow(LockingList<BWindow> *windowList);
|
||||||
|
virtual ~BDeskWindow();
|
||||||
|
|
||||||
|
virtual void Init(const BMessage *message = NULL);
|
||||||
|
|
||||||
|
virtual void Show();
|
||||||
|
virtual void Quit();
|
||||||
|
virtual void ScreenChanged(BRect, color_space);
|
||||||
|
|
||||||
|
virtual void ShowContextMenu(BPoint, const entry_ref *, BView *);
|
||||||
|
virtual void CreatePoseView(Model *);
|
||||||
|
|
||||||
|
virtual bool ShouldAddMenus() const;
|
||||||
|
virtual bool ShouldAddScrollBars() const;
|
||||||
|
virtual bool ShouldAddContainerView() const;
|
||||||
|
|
||||||
|
DesktopPoseView *PoseView() const;
|
||||||
|
|
||||||
|
void UpdateDesktopBackgroundImages();
|
||||||
|
// Desktop window has special background image handling
|
||||||
|
|
||||||
|
void SaveDesktopPoseLocations();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void AddWindowContextMenus(BMenu *);
|
||||||
|
void AddTrashContextMenu();
|
||||||
|
virtual BPoseView *NewPoseView(Model *, BRect, uint32);
|
||||||
|
|
||||||
|
virtual void WorkspaceActivated(int32, bool);
|
||||||
|
virtual void MenusBeginning();
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BShelf *fDeskShelf;
|
||||||
|
// shelf for replicant support
|
||||||
|
BPopUpMenu *fTrashContextMenu;
|
||||||
|
|
||||||
|
BRect fOldFrame;
|
||||||
|
|
||||||
|
// in the desktop window addon shortcuts have to be added by AddShortcut
|
||||||
|
// and we don't always get the MenusBeginning call to check for new addons/update the
|
||||||
|
// shortcuts -- instead we need to node monitor the addon directory and keep
|
||||||
|
// a dirty flag that triggers shortcut re-installing
|
||||||
|
bool fShouldUpdateAddonShortcuts;
|
||||||
|
std::set<uint32> fCurrentAddonShortcuts;
|
||||||
|
// keeps track of which shortcuts are installed for Tracker addons
|
||||||
|
|
||||||
|
typedef BContainerWindow _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline DesktopPoseView *
|
||||||
|
BDeskWindow::PoseView() const
|
||||||
|
{
|
||||||
|
return dynamic_cast<DesktopPoseView *>(_inherited::PoseView());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,451 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DesktopPoseView adds support for displaying integrated desktops
|
||||||
|
// from multiple volumes to BPoseView
|
||||||
|
//
|
||||||
|
// Used by the Desktop window and by the root view in file panels
|
||||||
|
|
||||||
|
#include <NodeMonitor.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <VolumeRoster.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "DesktopPoseView.h"
|
||||||
|
#include "FSUtils.h"
|
||||||
|
#include "PoseList.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
#include "TrackerSettings.h"
|
||||||
|
#include "TrackerString.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
bool
|
||||||
|
ShouldShowDesktopPose(dev_t device, const Model *model, const PoseInfo *)
|
||||||
|
{
|
||||||
|
if (model->NodeRef()->device != device) {
|
||||||
|
// avoid having more than one Trash
|
||||||
|
BDirectory remoteTrash;
|
||||||
|
if (FSGetTrashDir(&remoteTrash, model->NodeRef()->device) == B_OK) {
|
||||||
|
node_ref remoteTrashNodeRef;
|
||||||
|
remoteTrash.GetNodeRef(&remoteTrashNodeRef);
|
||||||
|
if (remoteTrashNodeRef == *model->NodeRef())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
|
DesktopEntryListCollection::DesktopEntryListCollection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
DesktopPoseView::DesktopPoseView(Model *model, BRect frame, uint32 viewMode,
|
||||||
|
uint32 resizeMask)
|
||||||
|
: BPoseView(model, frame, viewMode, resizeMask)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EntryListBase *
|
||||||
|
DesktopPoseView::InitDesktopDirentIterator(BPoseView *nodeMonitoringTarget,
|
||||||
|
const entry_ref *ref)
|
||||||
|
{
|
||||||
|
// the desktop dirent iterator knows how to iterate over all the volumes,
|
||||||
|
// integrated onto the desktop
|
||||||
|
|
||||||
|
Model sourceModel(ref, false, true);
|
||||||
|
if (sourceModel.InitCheck() != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
CachedEntryIteratorList *result = new DesktopEntryListCollection();
|
||||||
|
|
||||||
|
ASSERT(!sourceModel.IsQuery());
|
||||||
|
ASSERT(sourceModel.Node());
|
||||||
|
BDirectory *sourceDirectory = dynamic_cast<BDirectory *>(sourceModel.Node());
|
||||||
|
|
||||||
|
dev_t sourceDevice = sourceModel.NodeRef()->device;
|
||||||
|
|
||||||
|
ASSERT(sourceDirectory);
|
||||||
|
|
||||||
|
// build an iterator list, start with boot
|
||||||
|
EntryListBase *perDesktopIterator = new CachedDirectoryEntryList(
|
||||||
|
*sourceDirectory);
|
||||||
|
|
||||||
|
result->AddItem(perDesktopIterator);
|
||||||
|
if (nodeMonitoringTarget) {
|
||||||
|
TTracker::WatchNode(sourceModel.NodeRef(),
|
||||||
|
B_WATCH_DIRECTORY | B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR,
|
||||||
|
nodeMonitoringTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the other volumes
|
||||||
|
|
||||||
|
BVolumeRoster roster;
|
||||||
|
roster.Rewind();
|
||||||
|
BVolume volume;
|
||||||
|
while (roster.GetNextVolume(&volume) == B_OK) {
|
||||||
|
if (volume.Device() == sourceDevice)
|
||||||
|
// got that already
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!DesktopPoseView::ShouldIntegrateDesktop(volume))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BDirectory remoteDesktop;
|
||||||
|
if (FSGetDeskDir(&remoteDesktop, volume.Device()) < B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BDirectory root;
|
||||||
|
if (volume.GetRootDirectory(&root) == B_OK) {
|
||||||
|
perDesktopIterator = new CachedDirectoryEntryList(remoteDesktop);
|
||||||
|
result->AddItem(perDesktopIterator);
|
||||||
|
|
||||||
|
node_ref nodeRef;
|
||||||
|
remoteDesktop.GetNodeRef(&nodeRef);
|
||||||
|
|
||||||
|
if (nodeMonitoringTarget) {
|
||||||
|
TTracker::WatchNode(&nodeRef,
|
||||||
|
B_WATCH_DIRECTORY | B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR,
|
||||||
|
nodeMonitoringTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result->Rewind() != B_OK) {
|
||||||
|
delete result;
|
||||||
|
if (nodeMonitoringTarget)
|
||||||
|
nodeMonitoringTarget->HideBarberPole();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EntryListBase *
|
||||||
|
DesktopPoseView::InitDirentIterator(const entry_ref *ref)
|
||||||
|
{
|
||||||
|
return InitDesktopDirentIterator(this, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
DesktopPoseView::FSNotification(const BMessage *message)
|
||||||
|
{
|
||||||
|
switch (message->FindInt32("opcode")) {
|
||||||
|
case B_DEVICE_MOUNTED:
|
||||||
|
{
|
||||||
|
dev_t device;
|
||||||
|
if (message->FindInt32("new device", &device) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ASSERT(TargetModel());
|
||||||
|
TrackerSettings settings;
|
||||||
|
|
||||||
|
BVolume volume(device);
|
||||||
|
if (volume.InitCheck() != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (settings.MountVolumesOntoDesktop()
|
||||||
|
&& (!volume.IsShared() || settings.MountSharedVolumesOntoDesktop())) {
|
||||||
|
// place an icon for the volume onto the desktop
|
||||||
|
CreateVolumePose(&volume, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ShouldIntegrateDesktop(volume))
|
||||||
|
break;
|
||||||
|
|
||||||
|
BDirectory otherDesktop;
|
||||||
|
BEntry entry;
|
||||||
|
if (FSGetDeskDir(&otherDesktop, volume.Device()) == B_OK
|
||||||
|
&& otherDesktop.GetEntry(&entry) == B_OK) {
|
||||||
|
// place desktop items from the mounted volume onto the desktop
|
||||||
|
Model model(&entry);
|
||||||
|
if (model.InitCheck() == B_OK)
|
||||||
|
AddPoses(&model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _inherited::FSNotification(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
DesktopPoseView::AddPosesThreadValid(const entry_ref *) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
DesktopPoseView::ShouldShowPose(const Model *model, const PoseInfo *poseInfo)
|
||||||
|
{
|
||||||
|
ASSERT(TargetModel());
|
||||||
|
if (!ShouldShowDesktopPose(TargetModel()->NodeRef()->device, model, poseInfo))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _inherited::ShouldShowPose(model, poseInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
DesktopPoseView::Represents(const node_ref *ref) const
|
||||||
|
{
|
||||||
|
// When the Tracker is set up to integrate non-boot beos volumes,
|
||||||
|
// it represents the home/Desktop folders of all beos volumes
|
||||||
|
|
||||||
|
if (TrackerSettings().IntegrateNonBootBeOSDesktops()) {
|
||||||
|
BDirectory deviceDesktop;
|
||||||
|
FSGetDeskDir(&deviceDesktop, ref->device);
|
||||||
|
node_ref nref;
|
||||||
|
deviceDesktop.GetNodeRef(&nref);
|
||||||
|
return nref == *ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _inherited::Represents(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
DesktopPoseView::Represents(const entry_ref *ref) const
|
||||||
|
{
|
||||||
|
BEntry entry(ref);
|
||||||
|
node_ref nref;
|
||||||
|
entry.GetNodeRef(&nref);
|
||||||
|
return Represents(&nref);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DesktopPoseView::ShowVolumes(bool visible, bool showShared)
|
||||||
|
{
|
||||||
|
if (LockLooper()) {
|
||||||
|
if (!visible)
|
||||||
|
RemoveRootPoses();
|
||||||
|
else
|
||||||
|
AddRootPoses(true, showShared);
|
||||||
|
UnlockLooper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DesktopPoseView::RemoveNonBootItems()
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(Window());
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
EachPoseAndModel(fPoseList, &RemoveNonBootDesktopModels, (BPoseView*)this, (dev_t)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DesktopPoseView::AddNonBootItems()
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(Window());
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BVolumeRoster volumeRoster;
|
||||||
|
|
||||||
|
BVolume boot;
|
||||||
|
volumeRoster.GetBootVolume(&boot);
|
||||||
|
|
||||||
|
BVolume volume;
|
||||||
|
while (volumeRoster.GetNextVolume(&volume) == B_OK) {
|
||||||
|
if (volume == boot || !ShouldIntegrateDesktop(volume))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BDirectory otherDesktop;
|
||||||
|
BEntry entry;
|
||||||
|
|
||||||
|
if (FSGetDeskDir(&otherDesktop, volume.Device()) == B_OK
|
||||||
|
&& otherDesktop.GetEntry(&entry) == B_OK) {
|
||||||
|
// place desktop items from the mounted volume onto the desktop
|
||||||
|
Model model(&entry);
|
||||||
|
if (model.InitCheck() == B_OK)
|
||||||
|
AddPoses(&model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DesktopPoseView::StartSettingsWatch()
|
||||||
|
{
|
||||||
|
be_app->LockLooper();
|
||||||
|
be_app->StartWatching(this, kShowDisksIconChanged);
|
||||||
|
be_app->StartWatching(this, kVolumesOnDesktopChanged);
|
||||||
|
be_app->StartWatching(this, kDesktopIntegrationChanged);
|
||||||
|
be_app->UnlockLooper();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DesktopPoseView::StopSettingsWatch()
|
||||||
|
{
|
||||||
|
be_app->LockLooper();
|
||||||
|
be_app->StopWatching(this, kShowDisksIconChanged);
|
||||||
|
be_app->StopWatching(this, kVolumesOnDesktopChanged);
|
||||||
|
be_app->StopWatching(this, kDesktopIntegrationChanged);
|
||||||
|
be_app->UnlockLooper();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DesktopPoseView::AdaptToVolumeChange(BMessage *message)
|
||||||
|
{
|
||||||
|
TTracker *tracker = dynamic_cast<TTracker *>(be_app);
|
||||||
|
if (!tracker)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool showDisksIcon = false;
|
||||||
|
bool mountVolumesOnDesktop = true;
|
||||||
|
bool mountSharedVolumesOntoDesktop = false;
|
||||||
|
|
||||||
|
message->FindBool("ShowDisksIcon", &showDisksIcon);
|
||||||
|
message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop);
|
||||||
|
message->FindBool("MountSharedVolumesOntoDesktop", &mountSharedVolumesOntoDesktop);
|
||||||
|
|
||||||
|
BEntry entry("/");
|
||||||
|
Model model(&entry);
|
||||||
|
if (model.InitCheck() == B_OK) {
|
||||||
|
BMessage entryMessage;
|
||||||
|
entryMessage.what = B_NODE_MONITOR;
|
||||||
|
|
||||||
|
if (showDisksIcon)
|
||||||
|
entryMessage.AddInt32("opcode", B_ENTRY_CREATED);
|
||||||
|
else {
|
||||||
|
entryMessage.AddInt32("opcode", B_ENTRY_REMOVED);
|
||||||
|
entry_ref ref;
|
||||||
|
if (entry.GetRef(&ref) == B_OK) {
|
||||||
|
BContainerWindow *disksWindow = tracker->FindContainerWindow(&ref);
|
||||||
|
if (disksWindow) {
|
||||||
|
disksWindow->Lock();
|
||||||
|
disksWindow->Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entryMessage.AddInt32("device", model.NodeRef()->device);
|
||||||
|
entryMessage.AddInt64("node", model.NodeRef()->node);
|
||||||
|
entryMessage.AddInt64("directory", model.EntryRef()->directory);
|
||||||
|
entryMessage.AddString("name", model.EntryRef()->name);
|
||||||
|
BContainerWindow *deskWindow = dynamic_cast<BContainerWindow*>(Window());
|
||||||
|
if (deskWindow)
|
||||||
|
deskWindow->PostMessage(&entryMessage, deskWindow->PoseView());
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DesktopPoseView::AdaptToDesktopIntegrationChange(BMessage *message)
|
||||||
|
{
|
||||||
|
bool mountVolumesOnDesktop = true;
|
||||||
|
bool mountSharedVolumesOntoDesktop = true;
|
||||||
|
bool integrateNonBootBeOSDesktops = true;
|
||||||
|
|
||||||
|
message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop);
|
||||||
|
message->FindBool("MountSharedVolumesOntoDesktop", &mountSharedVolumesOntoDesktop);
|
||||||
|
message->FindBool("IntegrateNonBootBeOSDesktops", &integrateNonBootBeOSDesktops);
|
||||||
|
|
||||||
|
ShowVolumes(false, mountSharedVolumesOntoDesktop);
|
||||||
|
ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop);
|
||||||
|
|
||||||
|
UpdateNonBootDesktopPoses(integrateNonBootBeOSDesktops);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DesktopPoseView::UpdateNonBootDesktopPoses(bool integrateNonBootBeOSDesktops)
|
||||||
|
{
|
||||||
|
static bool nonBootDesktopPosesAlreadyAdded = false;
|
||||||
|
|
||||||
|
BVolumeRoster volumeRoster;
|
||||||
|
BVolume bootVolume;
|
||||||
|
volumeRoster.GetBootVolume(&bootVolume);
|
||||||
|
|
||||||
|
dev_t bootDevice = bootVolume.Device();
|
||||||
|
|
||||||
|
int32 poseCount = CountItems();
|
||||||
|
|
||||||
|
if (!integrateNonBootBeOSDesktops) {
|
||||||
|
for (int32 index = 0; index < poseCount; index++) {
|
||||||
|
Model *model = PoseAtIndex(index)->TargetModel();
|
||||||
|
if (!model->IsVolume() && model->NodeRef()->device != bootDevice){
|
||||||
|
DeletePose(model->NodeRef());
|
||||||
|
index--;
|
||||||
|
poseCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nonBootDesktopPosesAlreadyAdded = false;
|
||||||
|
} else if (!nonBootDesktopPosesAlreadyAdded) {
|
||||||
|
for (int32 index = 0; index < poseCount; index++) {
|
||||||
|
Model *model = PoseAtIndex(index)->TargetModel();
|
||||||
|
|
||||||
|
if (model->IsVolume()) {
|
||||||
|
BDirectory remoteDesktop;
|
||||||
|
BEntry entry;
|
||||||
|
BVolume volume(model->NodeRef()->device);
|
||||||
|
|
||||||
|
if (ShouldIntegrateDesktop(volume)
|
||||||
|
&& FSGetDeskDir(&remoteDesktop, volume.Device()) == B_OK
|
||||||
|
&& remoteDesktop.GetEntry(&entry) == B_OK
|
||||||
|
&& volume != bootVolume) {
|
||||||
|
// place desktop items from the volume onto the desktop
|
||||||
|
Model model(&entry);
|
||||||
|
if (model.InitCheck() == B_OK)
|
||||||
|
AddPoses(&model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nonBootDesktopPosesAlreadyAdded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// DesktopPoseView adds support for displaying integrated desktops
|
||||||
|
// from multiple volumes to BPoseView
|
||||||
|
|
||||||
|
#ifndef _DESKTOP_POSE_VIEW_H
|
||||||
|
#define _DESKTOP_POSE_VIEW_H
|
||||||
|
|
||||||
|
#include "EntryIterator.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class DesktopPoseView : public BPoseView {
|
||||||
|
// overrides BPoseView to add desktop-view specific code
|
||||||
|
public:
|
||||||
|
DesktopPoseView(Model *, BRect, uint32 viewMode, uint32 resizeMask = B_FOLLOW_ALL);
|
||||||
|
|
||||||
|
static EntryListBase *InitDesktopDirentIterator(BPoseView *, const entry_ref *);
|
||||||
|
|
||||||
|
void ShowVolumes(bool visible, bool showShared);
|
||||||
|
void RemoveNonBootItems();
|
||||||
|
void AddNonBootItems();
|
||||||
|
|
||||||
|
void StartSettingsWatch();
|
||||||
|
void StopSettingsWatch();
|
||||||
|
|
||||||
|
virtual bool AddPosesThreadValid(const entry_ref *) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual EntryListBase *InitDirentIterator(const entry_ref *);
|
||||||
|
virtual bool FSNotification(const BMessage *);
|
||||||
|
|
||||||
|
virtual bool IsDesktopView() const;
|
||||||
|
virtual bool ShouldShowPose(const Model *, const PoseInfo *);
|
||||||
|
|
||||||
|
virtual bool Represents(const node_ref *) const;
|
||||||
|
virtual bool Represents(const entry_ref *) const;
|
||||||
|
|
||||||
|
void AdaptToVolumeChange(BMessage *);
|
||||||
|
void AdaptToDesktopIntegrationChange(BMessage *);
|
||||||
|
|
||||||
|
void UpdateNonBootDesktopPoses(bool integrateNonBootBeOSDesktops);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef BPoseView _inherited;
|
||||||
|
|
||||||
|
friend bool ShouldShowDesktopPose(dev_t device, const Model *,
|
||||||
|
const PoseInfo *);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DesktopEntryListCollection : public CachedEntryIteratorList {
|
||||||
|
public:
|
||||||
|
DesktopEntryListCollection();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
DesktopPoseView::IsDesktopView() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,423 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING **
|
||||||
|
** **
|
||||||
|
** DANGER, WILL ROBINSON! **
|
||||||
|
** **
|
||||||
|
** The interfaces contained here are part of BeOS's **
|
||||||
|
** **
|
||||||
|
** >> PRIVATE NOT FOR PUBLIC USE << **
|
||||||
|
** **
|
||||||
|
** implementation. **
|
||||||
|
** **
|
||||||
|
** These interfaces WILL CHANGE in future releases. **
|
||||||
|
** If you use them, your app WILL BREAK at some future time. **
|
||||||
|
** **
|
||||||
|
** (And yes, this does mean that binaries built from OpenTracker will not **
|
||||||
|
** be compatible with some future releases of the OS. When that happens, **
|
||||||
|
** we will provide an updated version of this file to keep compatibility.) **
|
||||||
|
** **
|
||||||
|
** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING **
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
// volume management utilities
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __DEVICE_MAP__
|
||||||
|
#define __DEVICE_MAP__
|
||||||
|
|
||||||
|
#if _INCLUDES_CLASS_DEVICE_MAP
|
||||||
|
#define _DEVICE_MAP_ONLY(x) x
|
||||||
|
#else
|
||||||
|
#define _DEVICE_MAP_ONLY(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "DeviceMapGlue.h"
|
||||||
|
|
||||||
|
#include <Drivers.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Node.h>
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
class BBitmap;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
P_UNKNOWN = 0,
|
||||||
|
P_UNREADABLE,
|
||||||
|
P_ADD_ON,
|
||||||
|
P_AUDIO
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MountState {
|
||||||
|
kMounted,
|
||||||
|
kNotMounted,
|
||||||
|
kUnknown
|
||||||
|
};
|
||||||
|
|
||||||
|
class Device;
|
||||||
|
class Session;
|
||||||
|
class Partition;
|
||||||
|
|
||||||
|
typedef bool (Partition::*EachPartitionMemberFunction)(void *);
|
||||||
|
typedef Partition *(*EachPartitionFunction)(Partition *, void *);
|
||||||
|
typedef bool (Device::*EachDeviceMemberFunction)(void *);
|
||||||
|
typedef Device *(*EachDeviceFunction)(Device *, void *);
|
||||||
|
|
||||||
|
|
||||||
|
// structure used to communicate between the client application,
|
||||||
|
// the fs addon and the Initialize call
|
||||||
|
struct InitializeControlBlock {
|
||||||
|
BWindow *window; // window is used by the addon to
|
||||||
|
// center it's dialog over and send the
|
||||||
|
// result message to
|
||||||
|
sem_id completionSemaphore; // semaphore used to block the Initialize
|
||||||
|
// call while waiting for the user to
|
||||||
|
// interact with the addon dialog and the
|
||||||
|
// initialization to finish
|
||||||
|
int32 completionMessage; // the message that will be sent back to
|
||||||
|
// window upon addon completion
|
||||||
|
bool cancelOrFail; // the receiving window finds result codes
|
||||||
|
// from the addon and stuffs them in here
|
||||||
|
// for the Initialize call to use currently
|
||||||
|
// only bool is returned by the addon
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Partition {
|
||||||
|
public:
|
||||||
|
Partition(Session *, const char *name, const char *type,
|
||||||
|
const char *fsShortName, const char *fsLongName,
|
||||||
|
const char *volumeName, const char *mountedAt,
|
||||||
|
uint32 logicalBlockSize, uint64 offset, uint64 blocks,
|
||||||
|
bool hidden = false);
|
||||||
|
Partition(Session *, uint32 logicalBlockSize, uint64 offset,
|
||||||
|
uint64 blocks, bool hidden = false);
|
||||||
|
Partition(Session *, const partition_data &);
|
||||||
|
|
||||||
|
// getters/setters for partition info
|
||||||
|
void SetName(const char *);
|
||||||
|
const char *Name() const;
|
||||||
|
void SetType(const char *);
|
||||||
|
const char *Type() const;
|
||||||
|
void SetFileSystemShortName(const char *);
|
||||||
|
const char *FileSystemShortName() const;
|
||||||
|
void SetFileSystemLongName(const char *);
|
||||||
|
const char *FileSystemLongName() const;
|
||||||
|
void SetVolumeName(const char *);
|
||||||
|
const char *VolumeName() const;
|
||||||
|
void SetMountedAt(const char *);
|
||||||
|
const char *MountedAt() const;
|
||||||
|
|
||||||
|
status_t GetMountPointNodeRef(node_ref*) const;
|
||||||
|
void SetMountPointNodeRef(const node_ref*);
|
||||||
|
|
||||||
|
MountState Mounted() const;
|
||||||
|
void SetMountState(MountState state);
|
||||||
|
|
||||||
|
uint32 LogicalBlockSize() const;
|
||||||
|
uint64 Offset() const;
|
||||||
|
uint64 Blocks() const;
|
||||||
|
bool Hidden() const;
|
||||||
|
|
||||||
|
Session *GetSession() const;
|
||||||
|
// the session the partition is on
|
||||||
|
Device *GetDevice() const;
|
||||||
|
// the device the partition and it's session are on
|
||||||
|
|
||||||
|
bool BuildFileSystemInfo(void *params);
|
||||||
|
// set up the files system short and long names for this partition
|
||||||
|
bool RebuildFileSystemInfo();
|
||||||
|
// set up the files system short and long names for this partition
|
||||||
|
|
||||||
|
partition_data *Data();
|
||||||
|
// accessor to the low level data for low level calls
|
||||||
|
|
||||||
|
bool IsBFSDisk() const;
|
||||||
|
bool IsHFSDisk() const;
|
||||||
|
bool IsOFSDisk() const;
|
||||||
|
|
||||||
|
int32 Index() const;
|
||||||
|
|
||||||
|
// utility calls for updating mounting info
|
||||||
|
bool SetOneUnknownMountState(void *);
|
||||||
|
bool ClearOneMountState(void *);
|
||||||
|
|
||||||
|
// here is the real stuff
|
||||||
|
status_t Mount(int32 mountflags = 0, void *params = NULL, int32 len = 0);
|
||||||
|
status_t Unmount();
|
||||||
|
status_t Initialize(InitializeControlBlock *params,
|
||||||
|
const char *fileSystem = "bfs");
|
||||||
|
// the drive setup addon call protocol requires a lot of extra stuff:
|
||||||
|
// you have to pass a window onto which the drive setup addon will
|
||||||
|
// center itself. Upon completion it will send it a message with
|
||||||
|
// <completionMessage> signature; the MessageReceived in the window
|
||||||
|
// needs to release <completionSemaphore> to unblock the call
|
||||||
|
|
||||||
|
int32 UniqueID() const;
|
||||||
|
// returns a number uinque to the volume in a given device list
|
||||||
|
// used to identify unmounted volumes
|
||||||
|
|
||||||
|
dev_t VolumeDeviceID() const;
|
||||||
|
void SetVolumeDeviceID(dev_t);
|
||||||
|
// only available for mounted volumes
|
||||||
|
|
||||||
|
status_t AddVirtualDevice();
|
||||||
|
// publishes a device in /dev...
|
||||||
|
|
||||||
|
void Dump(const char *includeThisText = "");
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t AddVirtualDevice(char *device);
|
||||||
|
// fills out <device> with the path to the device driver in /dev...
|
||||||
|
void InitialMountPointName(char *);
|
||||||
|
|
||||||
|
partition_data data;
|
||||||
|
Session *session;
|
||||||
|
MountState mounted;
|
||||||
|
|
||||||
|
int32 partitionUniqueID;
|
||||||
|
dev_t volumeDeviceID;
|
||||||
|
|
||||||
|
node_ref mountPointNodeRef;
|
||||||
|
status_t mountPointNodeRefStatus;
|
||||||
|
static int32 lastUniqueID;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Session {
|
||||||
|
public:
|
||||||
|
Session(Device *device, const char *, uint64 offset, uint64 blocks,
|
||||||
|
bool data);
|
||||||
|
|
||||||
|
uint64 Blocks() const;
|
||||||
|
|
||||||
|
void AddPartition(Partition *);
|
||||||
|
void SetName(const char *);
|
||||||
|
const char *Name() const;
|
||||||
|
void SetType(int32 type);
|
||||||
|
|
||||||
|
uint64 Offset() const;
|
||||||
|
|
||||||
|
Device *GetDevice() const;
|
||||||
|
|
||||||
|
int32 CountPartitions() const;
|
||||||
|
Partition *PartitionAt(int32 index) const;
|
||||||
|
bool VirtualPartitionOnly() const;
|
||||||
|
|
||||||
|
|
||||||
|
void SetAddOnEntry(const BEntry *entry);
|
||||||
|
// the addon that knows how to handle this session
|
||||||
|
|
||||||
|
bool BuildPartitionMap(int32 dev, uchar *block, bool singlePartition);
|
||||||
|
// adds one or more partitions to the list
|
||||||
|
// returns true if multiple partitions found
|
||||||
|
// pass false in <singlePartition> if device cannot support
|
||||||
|
// multiple partitions (floppy)
|
||||||
|
|
||||||
|
bool BuildFileSystemInfo(int32 dev);
|
||||||
|
|
||||||
|
int32 Index() const;
|
||||||
|
|
||||||
|
bool EachPartition(EachPartitionMemberFunction, void *);
|
||||||
|
// return true if terminated early
|
||||||
|
|
||||||
|
bool IsDataSession() const;
|
||||||
|
|
||||||
|
static status_t GetSessionData(int32 dev, int32 index,
|
||||||
|
int32 blockSize, session_data *session);
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
uint64 offset;
|
||||||
|
uint64 blocks;
|
||||||
|
char name[B_OS_NAME_LENGTH]; // map name
|
||||||
|
int32 type;
|
||||||
|
bool data;
|
||||||
|
bool virtualPartitionOnly;
|
||||||
|
BEntry add_on; // we probably don't need this
|
||||||
|
TypedList<Partition *> partitionList;
|
||||||
|
Device *device;
|
||||||
|
|
||||||
|
friend class Partition;
|
||||||
|
friend class Device;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceScanParams {
|
||||||
|
bigtime_t shortestRescanHartbeat;
|
||||||
|
bool removableOrUnknownOnly;
|
||||||
|
bool checkFloppies;
|
||||||
|
bool checkCDROMs;
|
||||||
|
bool checkOtherRemovable;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Device {
|
||||||
|
public:
|
||||||
|
Device(const char *path, int devfd = -1);
|
||||||
|
~Device();
|
||||||
|
|
||||||
|
int32 CountSessions() const;
|
||||||
|
Session *SessionAt(int32 index) const;
|
||||||
|
|
||||||
|
int32 CountPartitions() const;
|
||||||
|
|
||||||
|
int32 BlockSize() const;
|
||||||
|
|
||||||
|
void SetPartitioningFlags(drive_setup_partition_flags newFlags);
|
||||||
|
|
||||||
|
const char *Name() const;
|
||||||
|
// device name, including path
|
||||||
|
const char *DisplayName(bool includeBusID = true,
|
||||||
|
bool includeLUN = false) const;
|
||||||
|
|
||||||
|
Session *NewSession(int32 dev, int32 index);
|
||||||
|
|
||||||
|
bool FindMountedVolumes(void *);
|
||||||
|
bool ReadOnly() const
|
||||||
|
{ return readOnly; }
|
||||||
|
bool Removable() const
|
||||||
|
{ return removable; }
|
||||||
|
|
||||||
|
void UpdateDeviceState();
|
||||||
|
status_t Eject();
|
||||||
|
|
||||||
|
bool NoMedia() const;
|
||||||
|
|
||||||
|
void Dump(const char *);
|
||||||
|
|
||||||
|
bool Dump(void *);
|
||||||
|
// each function dump
|
||||||
|
|
||||||
|
bool DeviceStateChanged(void *params);
|
||||||
|
|
||||||
|
bool IsFloppy() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitNewDeviceState();
|
||||||
|
void KillOldDeviceState();
|
||||||
|
|
||||||
|
bool OneIfDeviceStateChangedAdaptor(void *params);
|
||||||
|
|
||||||
|
void BuildDisplayName(bool includeBusID, bool includeLUN);
|
||||||
|
|
||||||
|
char name[B_FILE_NAME_LENGTH];
|
||||||
|
char shortName[B_FILE_NAME_LENGTH];
|
||||||
|
int devfd;
|
||||||
|
drive_setup_partition_flags partitioningFlags;
|
||||||
|
BBitmap *largeIcon;
|
||||||
|
BBitmap *miniIcon;
|
||||||
|
|
||||||
|
bool readOnly;
|
||||||
|
bool removable;
|
||||||
|
bool isFloppy;
|
||||||
|
bool media_changed;
|
||||||
|
bool eject_request;
|
||||||
|
|
||||||
|
int32 blockSize;
|
||||||
|
|
||||||
|
TypedList<Session *> sessionList;
|
||||||
|
|
||||||
|
friend class Session;
|
||||||
|
friend class DeviceList;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceList;
|
||||||
|
class EachPartitionAdaptor;
|
||||||
|
class EachPartitionMemberAdaptor;
|
||||||
|
class EachMountablePartitionAdaptor;
|
||||||
|
class EachInitializablePartitionAdaptor;
|
||||||
|
class EachMountedPartitionAdaptor;
|
||||||
|
|
||||||
|
template<class Adaptor, class EachFunction, class ResultType, class ParamType>
|
||||||
|
class EachPartitionIterator {
|
||||||
|
public:
|
||||||
|
static ResultType EachPartition(DeviceList *, EachFunction func,
|
||||||
|
ParamType params);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DeviceList : private TypedList<Device *> {
|
||||||
|
public:
|
||||||
|
DeviceList();
|
||||||
|
~DeviceList();
|
||||||
|
|
||||||
|
status_t RescanDevices(bool runRescanDriver = true);
|
||||||
|
bool UpdateMountingInfo();
|
||||||
|
// returns true if there was a change
|
||||||
|
|
||||||
|
bool EachDevice(EachDeviceMemberFunction, void *);
|
||||||
|
// return true if terminated early
|
||||||
|
Device *EachDevice(EachDeviceFunction, void *);
|
||||||
|
// return true if terminated early
|
||||||
|
|
||||||
|
Partition *EachPartition(EachPartitionFunction func, void *params);
|
||||||
|
// return Partition * if terminated early
|
||||||
|
|
||||||
|
bool EachPartition(EachPartitionMemberFunction func, void *params);
|
||||||
|
// return true if terminated early
|
||||||
|
|
||||||
|
Partition *EachMountedPartition(EachPartitionFunction, void *);
|
||||||
|
Partition *EachMountablePartition(EachPartitionFunction, void *);
|
||||||
|
Partition *EachInitializablePartition(EachPartitionFunction, void *);
|
||||||
|
|
||||||
|
Partition *PartitionWithID(int32);
|
||||||
|
|
||||||
|
bool CheckDevicesChanged(DeviceScanParams *);
|
||||||
|
void UpdateChangedDevices(DeviceScanParams *);
|
||||||
|
bool UnmountDisappearedPartitions();
|
||||||
|
// ToDo: pass a hook function for alerting user
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool EachChangedDevice(EachDeviceFunction, DeviceScanParams *, void *);
|
||||||
|
// iterate through every device that is out of sync with current state
|
||||||
|
// used to sync when media changes, etc.
|
||||||
|
|
||||||
|
status_t ScanDirectory(const char *path);
|
||||||
|
|
||||||
|
friend class EachPartitionIterator<EachPartitionAdaptor,
|
||||||
|
EachPartitionFunction, Partition *, void *>;
|
||||||
|
friend class EachPartitionIterator<EachMountedPartitionAdaptor,
|
||||||
|
EachPartitionFunction, Partition *, void *>;
|
||||||
|
friend class EachPartitionIterator<EachMountablePartitionAdaptor,
|
||||||
|
EachPartitionFunction, Partition *, void *>;
|
||||||
|
friend class EachPartitionIterator<EachInitializablePartitionAdaptor,
|
||||||
|
EachPartitionFunction, Partition *, void *>;
|
||||||
|
friend class EachPartitionIterator<EachPartitionMemberAdaptor,
|
||||||
|
EachPartitionMemberFunction, bool, void *>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING **
|
||||||
|
** **
|
||||||
|
** DANGER, WILL ROBINSON! **
|
||||||
|
** **
|
||||||
|
** The interfaces contained here are part of BeOS's **
|
||||||
|
** **
|
||||||
|
** >> PRIVATE NOT FOR PUBLIC USE << **
|
||||||
|
** **
|
||||||
|
** implementation. **
|
||||||
|
** **
|
||||||
|
** These interfaces WILL CHANGE in future releases. **
|
||||||
|
** If you use them, your app WILL BREAK at some future time. **
|
||||||
|
** **
|
||||||
|
** (And yes, this does mean that binaries built from OpenTracker will not **
|
||||||
|
** be compatible with some future releases of the OS. When that happens, **
|
||||||
|
** we will provide an updated version of this file to keep compatibility.) **
|
||||||
|
** **
|
||||||
|
** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING **
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __INTERNAL_GLUE__
|
||||||
|
#define __INTERNAL_GLUE__
|
||||||
|
|
||||||
|
// This file contains stubs of private headers that were needed to build
|
||||||
|
// Tracker independently of the BeOS build system.
|
||||||
|
// Care should be taken to make sure the structures in here are not out of date
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
|
||||||
|
// cruft from TypedList.h -----------------------
|
||||||
|
|
||||||
|
class PointerList : public BList {
|
||||||
|
public:
|
||||||
|
PointerList();
|
||||||
|
virtual ~PointerList();
|
||||||
|
|
||||||
|
bool Owning() const;
|
||||||
|
private:
|
||||||
|
const bool owning;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class TypedList : public PointerList {
|
||||||
|
public:
|
||||||
|
virtual ~TypedList();
|
||||||
|
|
||||||
|
void MakeEmpty();
|
||||||
|
bool RemoveItem(T);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
TypedList<T>::~TypedList()
|
||||||
|
{
|
||||||
|
if (Owning())
|
||||||
|
// have to nuke elements first
|
||||||
|
MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
bool
|
||||||
|
TypedList<T>::RemoveItem(T item)
|
||||||
|
{
|
||||||
|
bool result = PointerList::RemoveItem((void *)item);
|
||||||
|
|
||||||
|
if (result && Owning())
|
||||||
|
delete item;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void
|
||||||
|
TypedList<T>::MakeEmpty()
|
||||||
|
{
|
||||||
|
if (Owning()) {
|
||||||
|
int32 numElements = CountItems();
|
||||||
|
|
||||||
|
for (int32 count = 0; count < numElements; count++)
|
||||||
|
// this is probably not the most efficient, but
|
||||||
|
// is relatively indepenent of BList implementation
|
||||||
|
// details
|
||||||
|
RemoveItem((T)PointerList::LastItem());
|
||||||
|
}
|
||||||
|
PointerList::MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// from partition.h ------------------------------
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64 offset; /* in device blocks */
|
||||||
|
uint64 blocks;
|
||||||
|
bool data; /* audio or data session */
|
||||||
|
} session_data;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char partition_name[B_FILE_NAME_LENGTH];
|
||||||
|
char partition_type[B_FILE_NAME_LENGTH];
|
||||||
|
char file_system_short_name[B_FILE_NAME_LENGTH];
|
||||||
|
char file_system_long_name[B_FILE_NAME_LENGTH];
|
||||||
|
char volume_name[B_FILE_NAME_LENGTH];
|
||||||
|
char mounted_at[B_FILE_NAME_LENGTH];
|
||||||
|
uint32 logical_block_size;
|
||||||
|
uint64 offset; /* in logical blocks from start of session */
|
||||||
|
uint64 blocks; /* in logical blocks */
|
||||||
|
bool hidden; /* non-file system partition */
|
||||||
|
uchar partition_code;
|
||||||
|
bool reserved1;
|
||||||
|
uint32 reserved2;
|
||||||
|
} partition_data;
|
||||||
|
|
||||||
|
/* Partition add-on entry points */
|
||||||
|
/*-------------------------------*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool can_partition;
|
||||||
|
bool can_repartition;
|
||||||
|
} drive_setup_partition_flags;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,461 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Window.h"
|
||||||
|
#include "DialogPane.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
ViewList::RemoveAll(BView *)
|
||||||
|
{
|
||||||
|
EachListItemIgnoreResult(this, &BView::RemoveSelf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
AddSelf(BView *self, BView *to)
|
||||||
|
{
|
||||||
|
to->AddChild(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ViewList::AddAll(BView *toParent)
|
||||||
|
{
|
||||||
|
EachListItem(this, &AddSelf, toParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DialogPane::DialogPane(BRect mode1Frame, BRect mode2Frame, int32 initialMode,
|
||||||
|
const char *name, uint32 followFlags, uint32 flags)
|
||||||
|
: BView(FrameForMode(initialMode, mode1Frame, mode2Frame, mode2Frame),
|
||||||
|
name, followFlags, flags),
|
||||||
|
fMode1Frame(mode1Frame),
|
||||||
|
fMode2Frame(mode2Frame),
|
||||||
|
fMode3Frame(mode2Frame)
|
||||||
|
{
|
||||||
|
SetMode(initialMode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DialogPane::DialogPane(BRect mode1Frame, BRect mode2Frame, BRect mode3Frame,
|
||||||
|
int32 initialMode, const char *name, uint32 followFlags, uint32 flags)
|
||||||
|
: BView(FrameForMode(initialMode, mode1Frame, mode2Frame, mode3Frame),
|
||||||
|
name, followFlags, flags),
|
||||||
|
fMode1Frame(mode1Frame),
|
||||||
|
fMode2Frame(mode2Frame),
|
||||||
|
fMode3Frame(mode3Frame)
|
||||||
|
{
|
||||||
|
SetMode(initialMode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DialogPane::~DialogPane()
|
||||||
|
{
|
||||||
|
fMode3Items.RemoveAll(this);
|
||||||
|
fMode2Items.RemoveAll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
DialogPane::SetMode(int32 mode, bool initialSetup)
|
||||||
|
{
|
||||||
|
ASSERT(mode < 3 && mode >= 0);
|
||||||
|
|
||||||
|
if (!initialSetup && mode == fMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 oldMode = fMode;
|
||||||
|
fMode = mode;
|
||||||
|
|
||||||
|
bool followBottom = (ResizingMode() & B_FOLLOW_BOTTOM) != 0;
|
||||||
|
// if we are follow bottom, we will move ourselves, need to place us back
|
||||||
|
float bottomOffset = 0;
|
||||||
|
if (followBottom)
|
||||||
|
bottomOffset = Window()->Bounds().bottom - Frame().bottom;
|
||||||
|
|
||||||
|
BRect newBounds(BoundsForMode(fMode));
|
||||||
|
if (!initialSetup)
|
||||||
|
ResizeParentWindow(fMode, oldMode);
|
||||||
|
|
||||||
|
ResizeTo(newBounds.Width(), newBounds.Height());
|
||||||
|
|
||||||
|
float delta = 0;
|
||||||
|
if (followBottom)
|
||||||
|
delta = (Window()->Bounds().bottom - Frame().bottom) - bottomOffset;
|
||||||
|
|
||||||
|
if (delta != 0) {
|
||||||
|
MoveBy(0, delta);
|
||||||
|
if (fLatch && (fLatch->ResizingMode() & B_FOLLOW_BOTTOM))
|
||||||
|
fLatch->MoveBy(0, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (fMode) {
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
if (oldMode > 1)
|
||||||
|
fMode3Items.RemoveAll(this);
|
||||||
|
if (oldMode > 0)
|
||||||
|
fMode2Items.RemoveAll(this);
|
||||||
|
|
||||||
|
BView *separator = FindView("separatorLine");
|
||||||
|
if (separator) {
|
||||||
|
BRect frame(separator->Frame());
|
||||||
|
frame.InsetBy(-1, -1);
|
||||||
|
RemoveChild(separator);
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
AddChild(new SeparatorLine(BPoint(newBounds.left, newBounds.top
|
||||||
|
+ newBounds.Height() / 2), newBounds.Width(), false,
|
||||||
|
"separatorLine"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
if (oldMode > 1)
|
||||||
|
fMode3Items.RemoveAll(this);
|
||||||
|
else
|
||||||
|
fMode2Items.AddAll(this);
|
||||||
|
|
||||||
|
BView *separator = FindView("separatorLine");
|
||||||
|
if (separator) {
|
||||||
|
BRect frame(separator->Frame());
|
||||||
|
frame.InsetBy(-1, -1);
|
||||||
|
RemoveChild(separator);
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
fMode3Items.AddAll(this);
|
||||||
|
if (oldMode < 1)
|
||||||
|
fMode2Items.AddAll(this);
|
||||||
|
|
||||||
|
BView *separator = FindView("separatorLine");
|
||||||
|
if (separator) {
|
||||||
|
BRect frame(separator->Frame());
|
||||||
|
frame.InsetBy(-1, -1);
|
||||||
|
RemoveChild(separator);
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DialogPane::AttachedToWindow()
|
||||||
|
{
|
||||||
|
BView *parent = Parent();
|
||||||
|
if (parent) {
|
||||||
|
SetViewColor(parent->ViewColor());
|
||||||
|
SetLowColor(parent->LowColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DialogPane::ResizeParentWindow(int32 from, int32 to)
|
||||||
|
{
|
||||||
|
if (!Window())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BRect oldBounds = BoundsForMode(from);
|
||||||
|
BRect newBounds = BoundsForMode(to);
|
||||||
|
|
||||||
|
BPoint by = oldBounds.RightBottom() - newBounds.RightBottom();
|
||||||
|
if (by != BPoint(0, 0))
|
||||||
|
Window()->ResizeBy(by.x, by.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DialogPane::AddItem(BView *view, int32 toMode)
|
||||||
|
{
|
||||||
|
if (toMode == 1)
|
||||||
|
fMode2Items.AddItem(view);
|
||||||
|
else if (toMode == 2)
|
||||||
|
fMode3Items.AddItem(view);
|
||||||
|
if (fMode >= toMode)
|
||||||
|
AddChild(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
BRect
|
||||||
|
DialogPane::FrameForMode(int32 mode)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case 0:
|
||||||
|
return fMode1Frame;
|
||||||
|
case 1:
|
||||||
|
return fMode2Frame;
|
||||||
|
case 2:
|
||||||
|
return fMode3Frame;
|
||||||
|
}
|
||||||
|
return fMode1Frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
BRect
|
||||||
|
DialogPane::BoundsForMode(int32 mode)
|
||||||
|
{
|
||||||
|
BRect result;
|
||||||
|
switch (mode) {
|
||||||
|
case 0:
|
||||||
|
result = fMode1Frame;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result = fMode2Frame;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = fMode3Frame;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.OffsetTo(0, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
BRect
|
||||||
|
DialogPane::FrameForMode(int32 mode, BRect mode1Frame, BRect mode2Frame,
|
||||||
|
BRect mode3Frame)
|
||||||
|
{
|
||||||
|
switch (mode) {
|
||||||
|
case 0:
|
||||||
|
return mode1Frame;
|
||||||
|
case 1:
|
||||||
|
return mode2Frame;
|
||||||
|
case 2:
|
||||||
|
return mode3Frame;
|
||||||
|
}
|
||||||
|
return mode1Frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32 kValueChanged = 'swch';
|
||||||
|
|
||||||
|
void
|
||||||
|
DialogPane::SetSwitch(BControl *control)
|
||||||
|
{
|
||||||
|
fLatch = control;
|
||||||
|
control->SetMessage(new BMessage(kValueChanged));
|
||||||
|
control->SetTarget(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DialogPane::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
if (message->what == kValueChanged) {
|
||||||
|
int32 value;
|
||||||
|
if (message->FindInt32("be:value", &value) == B_OK)
|
||||||
|
SetMode(value);
|
||||||
|
} else
|
||||||
|
_inherited::MessageReceived(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
PaneSwitch::PaneSwitch(BRect frame, const char *name, bool leftAligned,
|
||||||
|
uint32 resizeMask, uint32 flags)
|
||||||
|
: BControl(frame, name, "", 0, resizeMask, flags),
|
||||||
|
fLeftAligned(leftAligned),
|
||||||
|
fPressing(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PaneSwitch::DoneTracking(BPoint point)
|
||||||
|
{
|
||||||
|
BRect bounds(Bounds());
|
||||||
|
bounds.InsetBy(-3, -3);
|
||||||
|
|
||||||
|
fPressing = false;
|
||||||
|
Invalidate();
|
||||||
|
if (bounds.Contains(point)) {
|
||||||
|
SetValue(!Value());
|
||||||
|
Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PaneSwitch::Track(BPoint point, uint32)
|
||||||
|
{
|
||||||
|
BRect bounds(Bounds());
|
||||||
|
bounds.InsetBy(-3, -3);
|
||||||
|
|
||||||
|
bool newPressing = bounds.Contains(point);
|
||||||
|
if (newPressing != fPressing) {
|
||||||
|
fPressing = newPressing;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PaneSwitch::MouseDown(BPoint)
|
||||||
|
{
|
||||||
|
if (!IsEnabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
fPressing = true;
|
||||||
|
MouseDownThread<PaneSwitch>::TrackMouse(this, &PaneSwitch::DoneTracking,
|
||||||
|
&PaneSwitch::Track);
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const rgb_color kNormalColor = {150, 150, 150, 255};
|
||||||
|
const rgb_color kHighlightColor = {100, 100, 0, 255};
|
||||||
|
|
||||||
|
void
|
||||||
|
PaneSwitch::Draw(BRect)
|
||||||
|
{
|
||||||
|
if (fPressing)
|
||||||
|
DrawInState(kPressed);
|
||||||
|
else if (Value())
|
||||||
|
DrawInState(kExpanded);
|
||||||
|
else
|
||||||
|
DrawInState(kCollapsed);
|
||||||
|
|
||||||
|
|
||||||
|
rgb_color markColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
|
||||||
|
|
||||||
|
bool focused = IsFocus() && Window()->IsActive();
|
||||||
|
BRect bounds(Bounds());
|
||||||
|
BeginLineArray(2);
|
||||||
|
AddLine(BPoint(bounds.left + 2, bounds.bottom - 1),
|
||||||
|
BPoint(bounds.right - 2, bounds.bottom - 1), focused ? markColor : ViewColor());
|
||||||
|
AddLine(BPoint(bounds.left + 2, bounds.bottom),
|
||||||
|
BPoint(bounds.right - 2, bounds.bottom), focused ? kWhite : ViewColor());
|
||||||
|
EndLineArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PaneSwitch::DrawInState(PaneSwitch::State state)
|
||||||
|
{
|
||||||
|
BRect rect(0, 0, 10, 10);
|
||||||
|
|
||||||
|
rgb_color outlineColor = {0, 0, 0, 255};
|
||||||
|
rgb_color middleColor = state == kPressed ? kHighlightColor : kNormalColor;
|
||||||
|
|
||||||
|
|
||||||
|
SetDrawingMode(B_OP_COPY);
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case kCollapsed:
|
||||||
|
BeginLineArray(6);
|
||||||
|
|
||||||
|
if (fLeftAligned) {
|
||||||
|
AddLine(BPoint(rect.left + 3, rect.top + 1),
|
||||||
|
BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
|
||||||
|
AddLine(BPoint(rect.left + 3, rect.top + 1),
|
||||||
|
BPoint(rect.left + 7, rect.top + 5), outlineColor);
|
||||||
|
AddLine(BPoint(rect.left + 7, rect.top + 5),
|
||||||
|
BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
|
||||||
|
|
||||||
|
AddLine(BPoint(rect.left + 4, rect.top + 3),
|
||||||
|
BPoint(rect.left + 4, rect.bottom - 3), middleColor);
|
||||||
|
AddLine(BPoint(rect.left + 5, rect.top + 4),
|
||||||
|
BPoint(rect.left + 5, rect.bottom - 4), middleColor);
|
||||||
|
AddLine(BPoint(rect.left + 5, rect.top + 5),
|
||||||
|
BPoint(rect.left + 6, rect.top + 5), middleColor);
|
||||||
|
} else {
|
||||||
|
AddLine(BPoint(rect.right - 3, rect.top + 1),
|
||||||
|
BPoint(rect.right - 3, rect.bottom - 1), outlineColor);
|
||||||
|
AddLine(BPoint(rect.right - 3, rect.top + 1),
|
||||||
|
BPoint(rect.right - 7, rect.top + 5), outlineColor);
|
||||||
|
AddLine(BPoint(rect.right - 7, rect.top + 5),
|
||||||
|
BPoint(rect.right - 3, rect.bottom - 1), outlineColor);
|
||||||
|
|
||||||
|
AddLine(BPoint(rect.right - 4, rect.top + 3),
|
||||||
|
BPoint(rect.right - 4, rect.bottom - 3), middleColor);
|
||||||
|
AddLine(BPoint(rect.right - 5, rect.top + 4),
|
||||||
|
BPoint(rect.right - 5, rect.bottom - 4), middleColor);
|
||||||
|
AddLine(BPoint(rect.right - 5, rect.top + 5),
|
||||||
|
BPoint(rect.right - 6, rect.top + 5), middleColor);
|
||||||
|
}
|
||||||
|
EndLineArray();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kPressed:
|
||||||
|
BeginLineArray(7);
|
||||||
|
if (fLeftAligned) {
|
||||||
|
AddLine(BPoint(rect.left + 1, rect.top + 7),
|
||||||
|
BPoint(rect.left + 7, rect.top + 7), outlineColor);
|
||||||
|
AddLine(BPoint(rect.left + 7, rect.top + 1),
|
||||||
|
BPoint(rect.left + 7, rect.top + 7), outlineColor);
|
||||||
|
AddLine(BPoint(rect.left + 1, rect.top + 7),
|
||||||
|
BPoint(rect.left + 7, rect.top + 1), outlineColor);
|
||||||
|
|
||||||
|
AddLine(BPoint(rect.left + 3, rect.top + 6),
|
||||||
|
BPoint(rect.left + 6, rect.top + 6), middleColor);
|
||||||
|
AddLine(BPoint(rect.left + 4, rect.top + 5),
|
||||||
|
BPoint(rect.left + 6, rect.top + 5), middleColor);
|
||||||
|
AddLine(BPoint(rect.left + 5, rect.top + 4),
|
||||||
|
BPoint(rect.left + 6, rect.top + 4), middleColor);
|
||||||
|
AddLine(BPoint(rect.left + 6, rect.top + 3),
|
||||||
|
BPoint(rect.left + 6, rect.top + 4), middleColor);
|
||||||
|
} else {
|
||||||
|
AddLine(BPoint(rect.right - 1, rect.top + 7),
|
||||||
|
BPoint(rect.right - 7, rect.top + 7), outlineColor);
|
||||||
|
AddLine(BPoint(rect.right - 7, rect.top + 1),
|
||||||
|
BPoint(rect.right - 7, rect.top + 7), outlineColor);
|
||||||
|
AddLine(BPoint(rect.right - 1, rect.top + 7),
|
||||||
|
BPoint(rect.right - 7, rect.top + 1), outlineColor);
|
||||||
|
|
||||||
|
AddLine(BPoint(rect.right - 3, rect.top + 6),
|
||||||
|
BPoint(rect.right - 6, rect.top + 6), middleColor);
|
||||||
|
AddLine(BPoint(rect.right - 4, rect.top + 5),
|
||||||
|
BPoint(rect.right - 6, rect.top + 5), middleColor);
|
||||||
|
AddLine(BPoint(rect.right - 5, rect.top + 4),
|
||||||
|
BPoint(rect.right - 6, rect.top + 4), middleColor);
|
||||||
|
AddLine(BPoint(rect.right - 6, rect.top + 3),
|
||||||
|
BPoint(rect.right - 6, rect.top + 4), middleColor);
|
||||||
|
}
|
||||||
|
EndLineArray();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kExpanded:
|
||||||
|
BeginLineArray(6);
|
||||||
|
AddLine(BPoint(rect.left + 1, rect.top + 3),
|
||||||
|
BPoint(rect.right - 1, rect.top + 3), outlineColor);
|
||||||
|
AddLine(BPoint(rect.left + 1, rect.top + 3),
|
||||||
|
BPoint(rect.left + 5, rect.top + 7), outlineColor);
|
||||||
|
AddLine(BPoint(rect.left + 5, rect.top + 7),
|
||||||
|
BPoint(rect.right - 1, rect.top + 3), outlineColor);
|
||||||
|
|
||||||
|
AddLine(BPoint(rect.left + 3, rect.top + 4),
|
||||||
|
BPoint(rect.right - 3, rect.top + 4), middleColor);
|
||||||
|
AddLine(BPoint(rect.left + 4, rect.top + 5),
|
||||||
|
BPoint(rect.right - 4, rect.top + 5), middleColor);
|
||||||
|
AddLine(BPoint(rect.left + 5, rect.top + 5),
|
||||||
|
BPoint(rect.left + 5, rect.top + 6), middleColor);
|
||||||
|
EndLineArray();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
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 _DIALOG_PANE_
|
||||||
|
#define _DIALOG_PANE_
|
||||||
|
|
||||||
|
#include <Control.h>
|
||||||
|
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class ViewList : public BObjectList<BView> {
|
||||||
|
public:
|
||||||
|
ViewList()
|
||||||
|
: BObjectList<BView>(5, true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void RemoveAll(BView *fromParent);
|
||||||
|
void AddAll(BView *toParent);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DialogPane : public BView {
|
||||||
|
// dialog with collapsible panes
|
||||||
|
public:
|
||||||
|
DialogPane(BRect mode1Frame, BRect mode2Frame, int32 initialMode,
|
||||||
|
const char *name, uint32 followFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||||
|
uint32 flags = B_WILL_DRAW);
|
||||||
|
DialogPane(BRect mode1Frame, BRect mode2Frame, BRect mode3Frame,
|
||||||
|
int32 initialMode, const char *name,
|
||||||
|
uint32 followFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||||
|
uint32 flags = B_WILL_DRAW);
|
||||||
|
|
||||||
|
virtual ~DialogPane();
|
||||||
|
|
||||||
|
BRect FrameForMode(int32);
|
||||||
|
BRect BoundsForMode(int32);
|
||||||
|
|
||||||
|
int32 Mode() const;
|
||||||
|
virtual void SetMode(int32, bool initialSetup = false);
|
||||||
|
|
||||||
|
void AddItem(BView *, int32 toMode);
|
||||||
|
|
||||||
|
void SetSwitch(BControl *);
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void ResizeParentWindow(int32 from, int32 to);
|
||||||
|
static BRect FrameForMode(int32, BRect, BRect, BRect);
|
||||||
|
// called only by the constructor
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 fMode;
|
||||||
|
|
||||||
|
BRect fMode1Frame;
|
||||||
|
BRect fMode2Frame;
|
||||||
|
BRect fMode3Frame;
|
||||||
|
|
||||||
|
ViewList fMode2Items;
|
||||||
|
ViewList fMode3Items;
|
||||||
|
BControl *fLatch;
|
||||||
|
|
||||||
|
typedef BView _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline int32
|
||||||
|
DialogPane::Mode() const
|
||||||
|
{
|
||||||
|
return fMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PaneSwitch : public BControl {
|
||||||
|
|
||||||
|
public:
|
||||||
|
PaneSwitch(BRect frame, const char *name, bool leftAligned = true,
|
||||||
|
uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||||
|
uint32 flags = B_WILL_DRAW | B_NAVIGABLE);
|
||||||
|
|
||||||
|
virtual void Draw(BRect );
|
||||||
|
virtual void MouseDown(BPoint );
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void DoneTracking(BPoint );
|
||||||
|
void Track(BPoint, uint32);
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
kCollapsed,
|
||||||
|
kPressed,
|
||||||
|
kExpanded
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void DrawInState(PaneSwitch::State state);
|
||||||
|
|
||||||
|
bool fLeftAligned;
|
||||||
|
bool fPressing;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,260 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ToDo:
|
||||||
|
// get rid of fMenuBar, SetMenuBar and related mess
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <MenuBar.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
#include <VolumeRoster.h>
|
||||||
|
|
||||||
|
#include "Attributes.h"
|
||||||
|
#include "ContainerWindow.h"
|
||||||
|
#include "DirMenu.h"
|
||||||
|
#include "FSUtils.h"
|
||||||
|
#include "IconMenuItem.h"
|
||||||
|
#include "NavMenu.h"
|
||||||
|
#include "TrackerSettings.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
|
||||||
|
BDirMenu::BDirMenu(BMenuBar *bar, uint32 command, const char *entryName)
|
||||||
|
: BPopUpMenu("directories"),
|
||||||
|
fMenuBar(bar),
|
||||||
|
fCommand(command)
|
||||||
|
{
|
||||||
|
SetFont(be_plain_font);
|
||||||
|
if (entryName)
|
||||||
|
fEntryName = entryName;
|
||||||
|
else
|
||||||
|
fEntryName = "refs";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BDirMenu::~BDirMenu()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDirMenu::Populate(const BEntry *startEntry, BWindow *originatingWindow,
|
||||||
|
bool includeStartEntry, bool select, bool reverse, bool addShortcuts,
|
||||||
|
bool navMenuEntries)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!startEntry)
|
||||||
|
throw (status_t)B_ERROR;
|
||||||
|
|
||||||
|
Model model(startEntry);
|
||||||
|
ThrowOnInitCheckError(&model);
|
||||||
|
|
||||||
|
ModelMenuItem *menu = new ModelMenuItem(&model, this, true, true);
|
||||||
|
|
||||||
|
if (fMenuBar)
|
||||||
|
fMenuBar->AddItem(menu);
|
||||||
|
|
||||||
|
BEntry entry(*startEntry);
|
||||||
|
|
||||||
|
bool showDesktop, showDisksIcon;
|
||||||
|
{
|
||||||
|
TrackerSettings settings;
|
||||||
|
showDesktop = settings.DesktopFilePanelRoot();
|
||||||
|
showDisksIcon = settings.ShowDisksIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
// might start one level above startEntry
|
||||||
|
if (!includeStartEntry) {
|
||||||
|
BDirectory parent;
|
||||||
|
BDirectory dir(&entry);
|
||||||
|
// if we're at the root directory skip "mnt" and go straight to "/"
|
||||||
|
if (!showDesktop && dir.InitCheck() == B_OK && dir.IsRootDirectory())
|
||||||
|
parent.SetTo("/");
|
||||||
|
else
|
||||||
|
entry.GetParent(&parent);
|
||||||
|
|
||||||
|
parent.GetEntry(&entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
BVolume bootVol;
|
||||||
|
BVolumeRoster().GetBootVolume(&bootVol);
|
||||||
|
BDirectory desktopDir;
|
||||||
|
FSGetDeskDir(&desktopDir, bootVol.Device());
|
||||||
|
BEntry desktopEntry;
|
||||||
|
desktopDir.GetEntry(&desktopEntry);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
BNode node(&entry);
|
||||||
|
ThrowOnInitCheckError(&node);
|
||||||
|
|
||||||
|
PoseInfo info;
|
||||||
|
ReadAttrResult result = ReadAttr(&node, kAttrPoseInfo,
|
||||||
|
kAttrPoseInfoForeign, B_RAW_TYPE, 0, &info, sizeof(PoseInfo),
|
||||||
|
&PoseInfo::EndianSwap);
|
||||||
|
|
||||||
|
BDirectory parent;
|
||||||
|
entry.GetParent(&parent);
|
||||||
|
|
||||||
|
bool hitRoot = false;
|
||||||
|
|
||||||
|
// if we're at the root directory skip "mnt" and go straight to "/"
|
||||||
|
BDirectory dir(&entry);
|
||||||
|
if (!showDesktop && dir.InitCheck() == B_OK && dir.IsRootDirectory()) {
|
||||||
|
hitRoot = true;
|
||||||
|
parent.SetTo("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showDesktop) {
|
||||||
|
BEntry root("/");
|
||||||
|
// warp from "/" to Desktop properly
|
||||||
|
if (entry == root) {
|
||||||
|
if (showDisksIcon)
|
||||||
|
AddDisksIconToMenu(reverse);
|
||||||
|
entry = desktopEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry == desktopEntry)
|
||||||
|
hitRoot = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == kReadAttrFailed || !info.fInvisible
|
||||||
|
|| (showDesktop && desktopEntry == entry))
|
||||||
|
AddItemToDirMenu(&entry, originatingWindow, reverse,
|
||||||
|
addShortcuts, navMenuEntries);
|
||||||
|
|
||||||
|
if (hitRoot) {
|
||||||
|
if (!showDesktop && showDisksIcon && *startEntry != "/")
|
||||||
|
AddDisksIconToMenu(reverse);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.GetEntry(&entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// select last item in menu
|
||||||
|
if (!select)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ModelMenuItem *item = dynamic_cast<ModelMenuItem *>(ItemAt(CountItems() - 1));
|
||||||
|
if (item) {
|
||||||
|
item->SetMarked(true);
|
||||||
|
if (menu) {
|
||||||
|
entry.SetTo(item->TargetModel()->EntryRef());
|
||||||
|
ThrowOnError(menu->SetEntry(&entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (status_t err) {
|
||||||
|
PRINT(("BDirMenu::Populate: caught error %s\n", strerror(err)));
|
||||||
|
if (!CountItems()) {
|
||||||
|
BString error;
|
||||||
|
error << "Error [" << strerror(err) << "] populating menu";
|
||||||
|
AddItem(new BMenuItem(error.String(), 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDirMenu::AddItemToDirMenu(const BEntry *entry, BWindow *originatingWindow,
|
||||||
|
bool atEnd, bool addShortcuts, bool navMenuEntries)
|
||||||
|
{
|
||||||
|
Model model(entry);
|
||||||
|
if (model.InitCheck() != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BMessage *message = new BMessage(fCommand);
|
||||||
|
message->AddRef(fEntryName.String(), model.EntryRef());
|
||||||
|
|
||||||
|
// add reference to the container windows model so that we can
|
||||||
|
// close the window if
|
||||||
|
BContainerWindow *window = originatingWindow ?
|
||||||
|
dynamic_cast<BContainerWindow *>(originatingWindow) : 0;
|
||||||
|
if (window)
|
||||||
|
message->AddData("nodeRefsToClose", B_RAW_TYPE, window->TargetModel()->NodeRef(),
|
||||||
|
sizeof (node_ref));
|
||||||
|
ModelMenuItem *item;
|
||||||
|
if (navMenuEntries) {
|
||||||
|
BNavMenu* subMenu = new BNavMenu(model.Name(), B_REFS_RECEIVED, be_app, window);
|
||||||
|
entry_ref ref;
|
||||||
|
entry->GetRef(&ref);
|
||||||
|
subMenu->SetNavDir(&ref);
|
||||||
|
item = new ModelMenuItem(&model, subMenu);
|
||||||
|
item->SetLabel(model.Name());
|
||||||
|
item->SetMessage(message);
|
||||||
|
} else {
|
||||||
|
item = new ModelMenuItem(&model, model.Name(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addShortcuts) {
|
||||||
|
if (FSIsDeskDir(entry))
|
||||||
|
item->SetShortcut('D', B_COMMAND_KEY);
|
||||||
|
else if (FSIsHomeDir(entry))
|
||||||
|
item->SetShortcut('H', B_COMMAND_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atEnd)
|
||||||
|
AddItem(item);
|
||||||
|
else
|
||||||
|
AddItem(item, 0);
|
||||||
|
|
||||||
|
if (fMenuBar) {
|
||||||
|
ModelMenuItem *menu = dynamic_cast<ModelMenuItem *>(fMenuBar->ItemAt(0));
|
||||||
|
if (menu) {
|
||||||
|
ThrowOnError(menu->SetEntry(entry));
|
||||||
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BDirMenu::AddDisksIconToMenu(bool atEnd)
|
||||||
|
{
|
||||||
|
BEntry entry("/");
|
||||||
|
Model model(&entry);
|
||||||
|
if (model.InitCheck() != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BMessage *message = new BMessage(fCommand);
|
||||||
|
message->AddRef(fEntryName.String(), model.EntryRef());
|
||||||
|
|
||||||
|
ModelMenuItem *item = new ModelMenuItem(&model, "Disks", message);
|
||||||
|
if (atEnd)
|
||||||
|
AddItem(item);
|
||||||
|
else
|
||||||
|
AddItem(item, 0);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
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 DIR_MENU_H
|
||||||
|
#define DIR_MENU_H
|
||||||
|
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
class MenuBar;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BDirMenu : public BPopUpMenu {
|
||||||
|
public:
|
||||||
|
BDirMenu(BMenuBar *, uint32 command, const char *entryName = 0);
|
||||||
|
virtual ~BDirMenu();
|
||||||
|
|
||||||
|
void Populate(const BEntry *startDir, BWindow *originatingWindow,
|
||||||
|
bool includeStartDir = false, bool select = false, bool reverse = false,
|
||||||
|
bool addShortcuts = false, bool navMenuEntries = false);
|
||||||
|
void AddItemToDirMenu(const BEntry *, BWindow *originatingWindow,
|
||||||
|
bool atEnd, bool addShortcuts, bool navMenuEntries = false);
|
||||||
|
void AddDisksIconToMenu(bool reverse = false);
|
||||||
|
|
||||||
|
void SetMenuBar(BMenuBar *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BMenuBar *fMenuBar;
|
||||||
|
uint32 fCommand;
|
||||||
|
BString fEntryName;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void
|
||||||
|
BDirMenu::SetMenuBar(BMenuBar *bar)
|
||||||
|
{
|
||||||
|
fMenuBar = bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,490 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "EntryIterator.h"
|
||||||
|
#include "NodeWalker.h"
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
TWalkerWrapper::TWalkerWrapper(WALKER_NS::TWalker *walker)
|
||||||
|
: fWalker(walker),
|
||||||
|
fStatus(B_OK)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TWalkerWrapper::~TWalkerWrapper()
|
||||||
|
{
|
||||||
|
delete fWalker;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TWalkerWrapper::InitCheck() const
|
||||||
|
{
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TWalkerWrapper::GetNextEntry(BEntry *entry, bool traverse)
|
||||||
|
{
|
||||||
|
fStatus = fWalker->GetNextEntry(entry, traverse);
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TWalkerWrapper::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
fStatus = fWalker->GetNextRef(ref);
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
TWalkerWrapper::GetNextDirents(struct dirent *buffer, size_t length, int32 count)
|
||||||
|
{
|
||||||
|
int32 result = fWalker->GetNextDirents(buffer, length, count);
|
||||||
|
fStatus = result < 0 ? result : (result ? B_OK : B_ENTRY_NOT_FOUND);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TWalkerWrapper::Rewind()
|
||||||
|
{
|
||||||
|
return fWalker->Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
TWalkerWrapper::CountEntries()
|
||||||
|
{
|
||||||
|
return fWalker->CountEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryListBase::EntryListBase()
|
||||||
|
: fStatus(B_OK)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EntryListBase::InitCheck() const
|
||||||
|
{
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
dirent *
|
||||||
|
EntryListBase::Next(dirent *ent)
|
||||||
|
{
|
||||||
|
return (dirent *)((char *)ent + ent->d_reclen + sizeof(dirent));
|
||||||
|
}
|
||||||
|
|
||||||
|
CachedEntryIterator::CachedEntryIterator(BEntryList *iterator, int32 numEntries,
|
||||||
|
bool sortInodes)
|
||||||
|
: fIterator(iterator),
|
||||||
|
fEntryRefBuffer(NULL),
|
||||||
|
fCacheSize(numEntries),
|
||||||
|
fNumEntries(0),
|
||||||
|
fIndex(0),
|
||||||
|
fDirentBuffer(NULL),
|
||||||
|
fCurrentDirent(NULL),
|
||||||
|
fSortInodes(sortInodes),
|
||||||
|
fSortedList(NULL),
|
||||||
|
fEntryBuffer(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CachedEntryIterator::~CachedEntryIterator()
|
||||||
|
{
|
||||||
|
delete [] fEntryRefBuffer;
|
||||||
|
free(fDirentBuffer);
|
||||||
|
delete fSortedList;
|
||||||
|
delete [] fEntryBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CachedEntryIterator::GetNextEntry(BEntry *result, bool traverse)
|
||||||
|
{
|
||||||
|
ASSERT(!fDirentBuffer);
|
||||||
|
ASSERT(!fEntryRefBuffer);
|
||||||
|
|
||||||
|
if (!fEntryBuffer) {
|
||||||
|
fEntryBuffer = new BEntry [fCacheSize];
|
||||||
|
ASSERT(fIndex == 0 && fNumEntries == 0);
|
||||||
|
}
|
||||||
|
if (fIndex >= fNumEntries) {
|
||||||
|
// fill up the buffer or stop if error; keep error around
|
||||||
|
// and return it when appropriate
|
||||||
|
fStatus = B_OK;
|
||||||
|
for (fNumEntries = 0; fNumEntries < fCacheSize; fNumEntries++) {
|
||||||
|
fStatus = fIterator->GetNextEntry(&fEntryBuffer[fNumEntries],
|
||||||
|
traverse);
|
||||||
|
if (fStatus != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fIndex = 0;
|
||||||
|
}
|
||||||
|
*result = fEntryBuffer[fIndex++];
|
||||||
|
if (fIndex > fNumEntries)
|
||||||
|
// we are at the end of the cache we loaded up, time to return
|
||||||
|
// an error, if we had one
|
||||||
|
return fStatus;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CachedEntryIterator::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
ASSERT(!fDirentBuffer);
|
||||||
|
ASSERT(!fEntryBuffer);
|
||||||
|
|
||||||
|
if (!fEntryRefBuffer) {
|
||||||
|
fEntryRefBuffer = new entry_ref[fCacheSize];
|
||||||
|
ASSERT(fIndex == 0 && fNumEntries == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fIndex >= fNumEntries) {
|
||||||
|
// fill up the buffer or stop if error; keep error around
|
||||||
|
// and return it when appropriate
|
||||||
|
fStatus = B_OK;
|
||||||
|
for (fNumEntries = 0; fNumEntries < fCacheSize; fNumEntries++) {
|
||||||
|
fStatus = fIterator->GetNextRef(&fEntryRefBuffer[fNumEntries]);
|
||||||
|
if (fStatus != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fIndex = 0;
|
||||||
|
}
|
||||||
|
*ref = fEntryRefBuffer[fIndex++];
|
||||||
|
if (fIndex > fNumEntries)
|
||||||
|
// we are at the end of the cache we loaded up, time to return
|
||||||
|
// an error, if we had one
|
||||||
|
return fStatus;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
CompareInode(const dirent *ent1, const dirent *ent2)
|
||||||
|
{
|
||||||
|
if (ent1->d_ino < ent2->d_ino)
|
||||||
|
return -1;
|
||||||
|
else if (ent1->d_ino == ent2->d_ino)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CachedEntryIterator::GetNextDirents(struct dirent *ent, size_t size,
|
||||||
|
int32 count)
|
||||||
|
{
|
||||||
|
ASSERT(!fEntryRefBuffer);
|
||||||
|
if (!fDirentBuffer) {
|
||||||
|
fDirentBuffer = (dirent *)malloc(kDirentBufferSize);
|
||||||
|
ASSERT(fIndex == 0 && fNumEntries == 0);
|
||||||
|
ASSERT(size > sizeof(dirent) + B_FILE_NAME_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fIndex >= fNumEntries) {
|
||||||
|
// we are out of stock, cache em up
|
||||||
|
fCurrentDirent = fDirentBuffer;
|
||||||
|
uint32 bufferRemain = kDirentBufferSize;
|
||||||
|
for (fNumEntries = 0; fNumEntries < fCacheSize; ) {
|
||||||
|
int32 count = fIterator->GetNextDirents(fCurrentDirent,
|
||||||
|
bufferRemain, 1);
|
||||||
|
|
||||||
|
if (count <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
fNumEntries += count;
|
||||||
|
|
||||||
|
int32 currentDirentSize = fCurrentDirent->d_reclen + (ssize_t)sizeof(dirent);
|
||||||
|
bufferRemain -= currentDirentSize;
|
||||||
|
if (bufferRemain < (sizeof(dirent) + B_FILE_NAME_LENGTH))
|
||||||
|
// cant fit a big entryRef in the buffer, just bail
|
||||||
|
// and start from scratch
|
||||||
|
break;
|
||||||
|
|
||||||
|
fCurrentDirent = (dirent *)((char *)fCurrentDirent + currentDirentSize);
|
||||||
|
}
|
||||||
|
fCurrentDirent = fDirentBuffer;
|
||||||
|
if (fSortInodes) {
|
||||||
|
if (!fSortedList)
|
||||||
|
fSortedList = new BObjectList<dirent>(fCacheSize);
|
||||||
|
else
|
||||||
|
fSortedList->MakeEmpty();
|
||||||
|
|
||||||
|
for (int32 count = 0; count < fNumEntries; count++) {
|
||||||
|
fSortedList->AddItem(fCurrentDirent, 0);
|
||||||
|
fCurrentDirent = Next(fCurrentDirent);
|
||||||
|
}
|
||||||
|
fSortedList->SortItems(CompareInode);
|
||||||
|
fCurrentDirent = fDirentBuffer;
|
||||||
|
}
|
||||||
|
fIndex = 0;
|
||||||
|
}
|
||||||
|
if (fIndex >= fNumEntries)
|
||||||
|
// we are done, no more dirents left
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fSortInodes)
|
||||||
|
fCurrentDirent = fSortedList->ItemAt(fIndex);
|
||||||
|
|
||||||
|
fIndex++;
|
||||||
|
uint32 currentDirentSize = fCurrentDirent->d_reclen + sizeof(dirent);
|
||||||
|
ASSERT(currentDirentSize <= size);
|
||||||
|
if (currentDirentSize > size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memcpy(ent, fCurrentDirent, currentDirentSize);
|
||||||
|
|
||||||
|
if (!fSortInodes)
|
||||||
|
fCurrentDirent = (dirent *)((char *)fCurrentDirent + currentDirentSize);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CachedEntryIterator::Rewind()
|
||||||
|
{
|
||||||
|
fIndex = 0;
|
||||||
|
fNumEntries = 0;
|
||||||
|
fCurrentDirent = NULL;
|
||||||
|
fStatus = B_OK;
|
||||||
|
|
||||||
|
delete fSortedList;
|
||||||
|
fSortedList = NULL;
|
||||||
|
|
||||||
|
return fIterator->Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
CachedEntryIterator::CountEntries()
|
||||||
|
{
|
||||||
|
return fIterator->CountEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CachedEntryIterator::SetTo(BEntryList *iterator)
|
||||||
|
{
|
||||||
|
fIndex = 0;
|
||||||
|
fNumEntries = 0;
|
||||||
|
fStatus = B_OK;
|
||||||
|
fIterator = iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
CachedDirectoryEntryList::CachedDirectoryEntryList(const BDirectory &dir)
|
||||||
|
: CachedEntryIterator(0, 40, true),
|
||||||
|
fDir(dir)
|
||||||
|
{
|
||||||
|
fStatus = fDir.InitCheck();
|
||||||
|
SetTo(&fDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
CachedDirectoryEntryList::~CachedDirectoryEntryList()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DirectoryEntryList::DirectoryEntryList(const BDirectory &dir)
|
||||||
|
: fDir(dir)
|
||||||
|
{
|
||||||
|
fStatus = fDir.InitCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DirectoryEntryList::GetNextEntry(BEntry *entry, bool traverse)
|
||||||
|
{
|
||||||
|
fStatus = fDir.GetNextEntry(entry, traverse);
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DirectoryEntryList::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
fStatus = fDir.GetNextRef(ref);
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
DirectoryEntryList::GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count)
|
||||||
|
{
|
||||||
|
fStatus = fDir.GetNextDirents(buffer, length, count);
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DirectoryEntryList::Rewind()
|
||||||
|
{
|
||||||
|
fStatus = fDir.Rewind();
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
DirectoryEntryList::CountEntries()
|
||||||
|
{
|
||||||
|
return fDir.CountEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EntryIteratorList::EntryIteratorList()
|
||||||
|
: fList(5, true),
|
||||||
|
fCurrentIndex(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryIteratorList::~EntryIteratorList()
|
||||||
|
{
|
||||||
|
int32 count = fList.CountItems();
|
||||||
|
for (;count; count--) {
|
||||||
|
// workaround for BEntryList not having a proper destructor
|
||||||
|
BEntryList *entry = fList.RemoveItemAt(count - 1);
|
||||||
|
EntryListBase *fixedEntry = dynamic_cast<EntryListBase *>(entry);
|
||||||
|
|
||||||
|
if (fixedEntry)
|
||||||
|
delete fixedEntry;
|
||||||
|
else
|
||||||
|
delete entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EntryIteratorList::AddItem(BEntryList *walker)
|
||||||
|
{
|
||||||
|
fList.AddItem(walker);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EntryIteratorList::GetNextEntry(BEntry *entry, bool traverse)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
if (fCurrentIndex >= fList.CountItems()) {
|
||||||
|
fStatus = B_ENTRY_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fStatus = fList.ItemAt(fCurrentIndex)->GetNextEntry(entry, traverse);
|
||||||
|
if (fStatus != B_ENTRY_NOT_FOUND)
|
||||||
|
break;
|
||||||
|
|
||||||
|
fCurrentIndex++;
|
||||||
|
}
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EntryIteratorList::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
if (fCurrentIndex >= fList.CountItems()) {
|
||||||
|
fStatus = B_ENTRY_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fStatus = fList.ItemAt(fCurrentIndex)->GetNextRef(ref);
|
||||||
|
if (fStatus != B_ENTRY_NOT_FOUND)
|
||||||
|
break;
|
||||||
|
|
||||||
|
fCurrentIndex++;
|
||||||
|
}
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
EntryIteratorList::GetNextDirents(struct dirent *buffer, size_t length, int32 count)
|
||||||
|
{
|
||||||
|
int32 result = 0;
|
||||||
|
for (;;) {
|
||||||
|
if (fCurrentIndex >= fList.CountItems()) {
|
||||||
|
fStatus = B_ENTRY_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = fList.ItemAt(fCurrentIndex)->GetNextDirents(buffer, length, count);
|
||||||
|
if (result > 0) {
|
||||||
|
fStatus = B_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fCurrentIndex++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EntryIteratorList::Rewind()
|
||||||
|
{
|
||||||
|
fCurrentIndex = 0;
|
||||||
|
int32 count = fList.CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++)
|
||||||
|
fStatus = fList.ItemAt(index)->Rewind();
|
||||||
|
|
||||||
|
return fStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
EntryIteratorList::CountEntries()
|
||||||
|
{
|
||||||
|
int32 result = 0;
|
||||||
|
|
||||||
|
int32 count = fList.CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++)
|
||||||
|
result += fList.ItemAt(fCurrentIndex)->CountEntries();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CachedEntryIteratorList::CachedEntryIteratorList()
|
||||||
|
: CachedEntryIterator(0, 10, true)
|
||||||
|
{
|
||||||
|
fStatus = B_OK;
|
||||||
|
SetTo(&fIteratorList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CachedEntryIteratorList::AddItem(BEntryList *walker)
|
||||||
|
{
|
||||||
|
fIteratorList.AddItem(walker);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// A lot of the code in here wouldn't be needed if the destructor
|
||||||
|
// for BEntryList was virtual
|
||||||
|
|
||||||
|
// ToDo:
|
||||||
|
// get rid of all BEntryList API's in here, replace them with EntryListBase ones
|
||||||
|
|
||||||
|
#ifndef __ENTRY_ITERATOR__
|
||||||
|
#define __ENTRY_ITERATOR__
|
||||||
|
|
||||||
|
#include <Directory.h>
|
||||||
|
#include "ObjectList.h"
|
||||||
|
#include "NodeWalker.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class EntryListBase : public BEntryList {
|
||||||
|
// this is what BEntryList should have been
|
||||||
|
public:
|
||||||
|
EntryListBase();
|
||||||
|
virtual ~EntryListBase() {}
|
||||||
|
|
||||||
|
virtual status_t InitCheck() const;
|
||||||
|
|
||||||
|
virtual status_t GetNextEntry(BEntry *entry, bool traverse = false) = 0;
|
||||||
|
virtual status_t GetNextRef(entry_ref *ref) = 0;
|
||||||
|
virtual int32 GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count = INT_MAX) = 0;
|
||||||
|
|
||||||
|
virtual status_t Rewind() = 0;
|
||||||
|
virtual int32 CountEntries() = 0;
|
||||||
|
|
||||||
|
static dirent *Next(dirent *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
status_t fStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TWalkerWrapper : public EntryListBase {
|
||||||
|
// this is to be able to use TWalker polymorfically as BEntryListBase
|
||||||
|
public:
|
||||||
|
TWalkerWrapper(WALKER_NS::TWalker *walker);
|
||||||
|
virtual ~TWalkerWrapper();
|
||||||
|
|
||||||
|
virtual status_t InitCheck() const;
|
||||||
|
virtual status_t GetNextEntry(BEntry *entry, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *ref);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
virtual status_t Rewind();
|
||||||
|
virtual int32 CountEntries();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
WALKER_NS::TWalker *fWalker;
|
||||||
|
status_t fStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
const int32 kDirentBufferSize = 10 * 1024;
|
||||||
|
|
||||||
|
class CachedEntryIterator : public EntryListBase {
|
||||||
|
public:
|
||||||
|
// takes any iterator and runs it through a cache of a specified size
|
||||||
|
// used to cluster entry_ref reads together, away from node accesses
|
||||||
|
//
|
||||||
|
// each chunk of iterators in the cache are then returned in an order,
|
||||||
|
// sorted by their i-node number -- this turns out to give quite a bit
|
||||||
|
// better performance over just using the order in which they show up using
|
||||||
|
// the default BEntryList iterator subclass
|
||||||
|
|
||||||
|
CachedEntryIterator(BEntryList *iterator, int32 numEntries,
|
||||||
|
bool sortInodes = false);
|
||||||
|
// CachedEntryIterator does not get to own the <iterator>
|
||||||
|
virtual ~CachedEntryIterator();
|
||||||
|
|
||||||
|
virtual status_t GetNextEntry(BEntry *entry, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *ref);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
|
||||||
|
virtual status_t Rewind();
|
||||||
|
virtual int32 CountEntries();
|
||||||
|
|
||||||
|
virtual void SetTo(BEntryList *iterator);
|
||||||
|
// CachedEntryIterator does not get to own the <iterator>
|
||||||
|
|
||||||
|
private:
|
||||||
|
BEntryList *fIterator;
|
||||||
|
entry_ref *fEntryRefBuffer;
|
||||||
|
int32 fCacheSize;
|
||||||
|
int32 fNumEntries;
|
||||||
|
int32 fIndex;
|
||||||
|
|
||||||
|
dirent *fDirentBuffer;
|
||||||
|
dirent *fCurrentDirent;
|
||||||
|
bool fSortInodes;
|
||||||
|
BObjectList<dirent> *fSortedList;
|
||||||
|
|
||||||
|
BEntry *fEntryBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DirectoryEntryList : public EntryListBase {
|
||||||
|
public:
|
||||||
|
DirectoryEntryList(const BDirectory &);
|
||||||
|
|
||||||
|
virtual status_t GetNextEntry(BEntry *entry, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *ref);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
|
||||||
|
virtual status_t Rewind();
|
||||||
|
virtual int32 CountEntries();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BDirectory fDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CachedDirectoryEntryList : public CachedEntryIterator {
|
||||||
|
// this class is to work around not being able to delete
|
||||||
|
// BEntryList polymorfically - need to have a special
|
||||||
|
// caching entry list iterator for directories
|
||||||
|
public:
|
||||||
|
CachedDirectoryEntryList(const BDirectory &);
|
||||||
|
virtual ~CachedDirectoryEntryList();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BDirectory fDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EntryIteratorList : public EntryListBase {
|
||||||
|
// This wraps up several BEntryList style iterators and
|
||||||
|
// iterates them all, going from one to the other as it finishes
|
||||||
|
// up each of them
|
||||||
|
public:
|
||||||
|
EntryIteratorList();
|
||||||
|
virtual ~EntryIteratorList();
|
||||||
|
|
||||||
|
void AddItem(BEntryList *);
|
||||||
|
// list gets to own walkers
|
||||||
|
|
||||||
|
virtual status_t GetNextEntry(BEntry *entry, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *ref);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
|
||||||
|
virtual status_t Rewind();
|
||||||
|
virtual int32 CountEntries();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BObjectList<BEntryList> fList;
|
||||||
|
int32 fCurrentIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CachedEntryIteratorList : public CachedEntryIterator {
|
||||||
|
public:
|
||||||
|
CachedEntryIteratorList();
|
||||||
|
void AddItem(BEntryList *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EntryIteratorList fIteratorList;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <FilePanel.h>
|
||||||
|
|
||||||
|
#include "FilePanelPriv.h"
|
||||||
|
#include "RecentItems.h"
|
||||||
|
|
||||||
|
// FBC fluff, stick it here to not pollute real .cpp files
|
||||||
|
|
||||||
|
void BRecentItemsList::_r1() {}
|
||||||
|
void BRecentItemsList::_r2() {}
|
||||||
|
void BRecentItemsList::_r3() {}
|
||||||
|
void BRecentItemsList::_r4() {}
|
||||||
|
void BRecentItemsList::_r5() {}
|
||||||
|
void BRecentItemsList::_r6() {}
|
||||||
|
void BRecentItemsList::_r7() {}
|
||||||
|
void BRecentItemsList::_r8() {}
|
||||||
|
void BRecentItemsList::_r9() {}
|
||||||
|
void BRecentItemsList::_r10() {}
|
||||||
|
void BRecentFilesList::_r11() {}
|
||||||
|
void BRecentFilesList::_r12() {}
|
||||||
|
void BRecentFilesList::_r13() {}
|
||||||
|
void BRecentFilesList::_r14() {}
|
||||||
|
void BRecentFilesList::_r15() {}
|
||||||
|
void BRecentFilesList::_r16() {}
|
||||||
|
void BRecentFilesList::_r17() {}
|
||||||
|
void BRecentFilesList::_r18() {}
|
||||||
|
void BRecentFilesList::_r19() {}
|
||||||
|
void BRecentFilesList::_r110() {}
|
||||||
|
void BRecentFoldersList::_r21() {}
|
||||||
|
void BRecentFoldersList::_r22() {}
|
||||||
|
void BRecentFoldersList::_r23() {}
|
||||||
|
void BRecentFoldersList::_r24() {}
|
||||||
|
void BRecentFoldersList::_r25() {}
|
||||||
|
void BRecentFoldersList::_r26() {}
|
||||||
|
void BRecentFoldersList::_r27() {}
|
||||||
|
void BRecentFoldersList::_r28() {}
|
||||||
|
void BRecentFoldersList::_r29() {}
|
||||||
|
void BRecentFoldersList::_r210() {}
|
||||||
|
void BRecentAppsList::_r31() {}
|
||||||
|
void BRecentAppsList::_r32() {}
|
||||||
|
void BRecentAppsList::_r33() {}
|
||||||
|
void BRecentAppsList::_r34() {}
|
||||||
|
void BRecentAppsList::_r35() {}
|
||||||
|
void BRecentAppsList::_r36() {}
|
||||||
|
void BRecentAppsList::_r37() {}
|
||||||
|
void BRecentAppsList::_r38() {}
|
||||||
|
void BRecentAppsList::_r39() {}
|
||||||
|
void BRecentAppsList::_r310() {}
|
||||||
|
|
||||||
|
#if !_PR3_COMPATIBLE_
|
||||||
|
|
||||||
|
void BFilePanel::_ReservedFilePanel1() {}
|
||||||
|
void BFilePanel::_ReservedFilePanel2() {}
|
||||||
|
void BFilePanel::_ReservedFilePanel3() {}
|
||||||
|
void BFilePanel::_ReservedFilePanel4() {}
|
||||||
|
void BFilePanel::_ReservedFilePanel5() {}
|
||||||
|
void BFilePanel::_ReservedFilePanel6() {}
|
||||||
|
void BFilePanel::_ReservedFilePanel7() {}
|
||||||
|
void BFilePanel::_ReservedFilePanel8() {}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// deprecated cruft
|
||||||
|
|
||||||
|
#if __GNUC__ || __MWERKS__
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
_EXPORT BFilePanel*
|
||||||
|
#if __GNUC__
|
||||||
|
__10BFilePanel15file_panel_modeP10BMessengerP9entry_refUlbP8BMessageP10BRefFilterT5T5
|
||||||
|
#elif __MWERKS__
|
||||||
|
__ct__10BFilePanelF15file_panel_modeP10BMessengerP9entry_refUlbP8BMessageP10BRefFilterbb
|
||||||
|
#endif
|
||||||
|
(void *self,
|
||||||
|
file_panel_mode mode, BMessenger *target,
|
||||||
|
entry_ref *ref, uint32 nodeFlavors, bool multipleSelection,
|
||||||
|
BMessage *message, BRefFilter *filter, bool modal,
|
||||||
|
bool hideWhenDone)
|
||||||
|
{
|
||||||
|
return new (self) BFilePanel(mode, target, ref, nodeFlavors,
|
||||||
|
multipleSelection, message, filter, modal,
|
||||||
|
hideWhenDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
_EXPORT void
|
||||||
|
#if __GNUC__
|
||||||
|
SetPanelDirectory__10BFilePanelP10BDirectory
|
||||||
|
#elif __MWERKS__
|
||||||
|
SetPanelDirectory__10BFilePanelFP10BDirectory
|
||||||
|
#endif
|
||||||
|
(BFilePanel *self, BDirectory *d)
|
||||||
|
{
|
||||||
|
self->SetPanelDirectory(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
_EXPORT void
|
||||||
|
#if __GNUC__
|
||||||
|
SetPanelDirectory__10BFilePanelP6BEntry
|
||||||
|
#elif __MWERKS__
|
||||||
|
SetPanelDirectory__10BFilePanelFP6BEntry
|
||||||
|
#endif
|
||||||
|
(BFilePanel *self, BEntry *e)
|
||||||
|
{
|
||||||
|
self->SetPanelDirectory(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
_EXPORT void
|
||||||
|
#if __GNUC__
|
||||||
|
SetPanelDirectory__10BFilePanelP9entry_ref
|
||||||
|
#elif __MWERKS__
|
||||||
|
SetPanelDirectory__10BFilePanelFP9entry_ref
|
||||||
|
#endif
|
||||||
|
(BFilePanel *self, entry_ref *r)
|
||||||
|
{
|
||||||
|
self->SetPanelDirectory(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,849 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FSClipboard.h"
|
||||||
|
#include <Clipboard.h>
|
||||||
|
#include <Alert.h>
|
||||||
|
#include <NodeMonitor.h>
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "FSUtils.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
|
||||||
|
// prototypes
|
||||||
|
static void MakeNodeFromName(node_ref *node, char *name);
|
||||||
|
static inline void MakeRefName(char *refName, const node_ref *node);
|
||||||
|
static inline void MakeModeName(char *modeName, const node_ref *node);
|
||||||
|
static inline void MakeModeNameFromRefName(char *modeName, char *refName);
|
||||||
|
static inline bool CompareModeAndRefName(const char *modeName, const char *refName);
|
||||||
|
|
||||||
|
|
||||||
|
//these are from PoseView.cpp
|
||||||
|
extern const char *kNoCopyToTrashStr;
|
||||||
|
extern const char *kNoCopyToRootStr;
|
||||||
|
extern const char *kOkToMoveStr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
static bool
|
||||||
|
FSClipboardCheckIntegrity()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
FSClipboardHasRefs()
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (be_clipboard->Lock()) {
|
||||||
|
BMessage *clip = be_clipboard->Data();
|
||||||
|
if (clip != NULL) {
|
||||||
|
#ifdef B_BEOS_VERSION_DANO
|
||||||
|
const
|
||||||
|
#endif
|
||||||
|
char *refName;
|
||||||
|
#ifdef B_BEOS_VERSION_DANO
|
||||||
|
const
|
||||||
|
#endif
|
||||||
|
char *modeName;
|
||||||
|
uint32 type;
|
||||||
|
int32 count;
|
||||||
|
if (clip->GetInfo(B_REF_TYPE, 0, &refName, &type, &count) == B_OK
|
||||||
|
&& clip->GetInfo(B_INT32_TYPE, 0, &modeName, &type, &count) == B_OK)
|
||||||
|
result = CompareModeAndRefName(modeName, refName);
|
||||||
|
}
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FSClipboardStartWatch(BMessenger target)
|
||||||
|
{
|
||||||
|
if (dynamic_cast<TTracker *>(be_app) != NULL)
|
||||||
|
((TTracker *)be_app)->ClipboardRefsWatcher()->AddToNotifyList(target);
|
||||||
|
else {
|
||||||
|
// this code is used by external apps using objects using FSClipboard functions
|
||||||
|
// i.e: applications using FilePanel
|
||||||
|
BMessenger messenger(kTrackerSignature);
|
||||||
|
if (messenger.IsValid()) {
|
||||||
|
BMessage message(kStartWatchClipboardRefs);
|
||||||
|
message.AddMessenger("target", target);
|
||||||
|
messenger.SendMessage(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FSClipboardStopWatch(BMessenger target)
|
||||||
|
{
|
||||||
|
if (dynamic_cast<TTracker *>(be_app) != NULL)
|
||||||
|
((TTracker *)be_app)->ClipboardRefsWatcher()->AddToNotifyList(target);
|
||||||
|
else {
|
||||||
|
// this code is used by external apps using objects using FSClipboard functions
|
||||||
|
// i.e: applications using FilePanel
|
||||||
|
BMessenger messenger(kTrackerSignature);
|
||||||
|
if (messenger.IsValid()) {
|
||||||
|
BMessage message(kStopWatchClipboardRefs);
|
||||||
|
message.AddMessenger("target", target);
|
||||||
|
messenger.SendMessage(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
MakeNodeFromName(node_ref *node, char *name)
|
||||||
|
{
|
||||||
|
char *nodeString = strchr(name, '_');
|
||||||
|
if (nodeString != NULL) {
|
||||||
|
node->node = strtoll(nodeString + 1, (char **)NULL, 10);
|
||||||
|
node->device = atoi(name + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
MakeRefName(char *refName, const node_ref *node)
|
||||||
|
{
|
||||||
|
sprintf(refName, "r%ld_%Ld", node->device, node->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
MakeModeName(char *modeName, const node_ref *node)
|
||||||
|
{
|
||||||
|
sprintf(modeName, "m%ld_%Ld", node->device, node->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
MakeModeName(char *name)
|
||||||
|
{
|
||||||
|
name[0] = 'm';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
MakeModeNameFromRefName(char *modeName, char *refName)
|
||||||
|
{
|
||||||
|
strcpy(modeName, refName);
|
||||||
|
modeName[0] = 'm';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
CompareModeAndRefName(const char *modeName, const char *refName)
|
||||||
|
{
|
||||||
|
return !strcmp(refName + 1, modeName + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FSClipboardClear()
|
||||||
|
{
|
||||||
|
if (!be_clipboard->Lock())
|
||||||
|
return;
|
||||||
|
|
||||||
|
be_clipboard->Clear();
|
||||||
|
be_clipboard->Commit();
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** This function adds the given poses list to the clipboard, for both copy
|
||||||
|
* and cut. All poses in the list must have "directory" as parent.
|
||||||
|
* "moveMode" is either kMoveSelection or kCopySelection.
|
||||||
|
* It will check if the entries are already present, so that there can only
|
||||||
|
* be one reference to them in the clipboard.
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32
|
||||||
|
FSClipboardAddPoses(const node_ref *directory, PoseList *list, uint32 moveMode,
|
||||||
|
bool clearClipboard)
|
||||||
|
{
|
||||||
|
uint32 refsAdded = 0;
|
||||||
|
int32 listCount = list->CountItems();
|
||||||
|
|
||||||
|
if (listCount == 0 || !be_clipboard->Lock())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// update message to be send to all listeners
|
||||||
|
BMessage updateMessage(kFSClipboardChanges);
|
||||||
|
updateMessage.AddInt32("device", directory->device);
|
||||||
|
updateMessage.AddInt64("directory", directory->node);
|
||||||
|
updateMessage.AddBool("clearClipboard", clearClipboard);
|
||||||
|
|
||||||
|
TClipboardNodeRef clipNode;
|
||||||
|
clipNode.moveMode = moveMode;
|
||||||
|
|
||||||
|
if (clearClipboard)
|
||||||
|
be_clipboard->Clear();
|
||||||
|
|
||||||
|
BMessage *clip = be_clipboard->Data();
|
||||||
|
if (clip != NULL) {
|
||||||
|
for (int32 index = 0; index < listCount; index++) {
|
||||||
|
char refName[64], modeName[64];
|
||||||
|
BPose *pose = (BPose *)list->ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel();
|
||||||
|
const node_ref *node = model->NodeRef();
|
||||||
|
|
||||||
|
BEntry entry;
|
||||||
|
model->GetEntry(&entry);
|
||||||
|
if (model->IsVolume()
|
||||||
|
|| model->IsRoot()
|
||||||
|
|| FSIsTrashDir(&entry)
|
||||||
|
|| FSIsDeskDir(&entry))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MakeRefName(refName, node);
|
||||||
|
MakeModeNameFromRefName(modeName, refName);
|
||||||
|
|
||||||
|
if (clearClipboard) {
|
||||||
|
if (clip->AddInt32(modeName, (int32)moveMode) == B_OK)
|
||||||
|
if (clip->AddRef(refName, model->EntryRef()) == B_OK) {
|
||||||
|
pose->SetClipboardMode(moveMode);
|
||||||
|
|
||||||
|
clipNode.node = *node;
|
||||||
|
updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
|
||||||
|
sizeof(TClipboardNodeRef), true, listCount);
|
||||||
|
|
||||||
|
refsAdded++;
|
||||||
|
} else
|
||||||
|
clip->RemoveName(modeName);
|
||||||
|
} else {
|
||||||
|
if (clip->ReplaceInt32(modeName, (int32)moveMode) == B_OK) {
|
||||||
|
// replace old mode if entry already exists in clipboard
|
||||||
|
if (clip->ReplaceRef(refName, model->EntryRef()) == B_OK) {
|
||||||
|
pose->SetClipboardMode(moveMode);
|
||||||
|
|
||||||
|
clipNode.node = *node;
|
||||||
|
updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
|
||||||
|
sizeof(TClipboardNodeRef), true, listCount);
|
||||||
|
|
||||||
|
refsAdded++;
|
||||||
|
} else {
|
||||||
|
clip->RemoveName(modeName);
|
||||||
|
|
||||||
|
clipNode.node = *node;
|
||||||
|
clipNode.moveMode = kDelete; // note removing node
|
||||||
|
updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
|
||||||
|
sizeof(TClipboardNodeRef), true, listCount);
|
||||||
|
clipNode.moveMode = moveMode; // set it back to current value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// add if it doesn't exist
|
||||||
|
if (clip->AddRef(refName, model->EntryRef()) == B_OK
|
||||||
|
&& clip->AddInt32(modeName, (int32)moveMode) == B_OK) {
|
||||||
|
pose->SetClipboardMode(moveMode);
|
||||||
|
|
||||||
|
clipNode.node = *node;
|
||||||
|
updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
|
||||||
|
sizeof(TClipboardNodeRef), true, listCount);
|
||||||
|
|
||||||
|
refsAdded++;
|
||||||
|
} else {
|
||||||
|
clip->RemoveName(modeName);
|
||||||
|
clip->RemoveName(refName);
|
||||||
|
// here notifying delete isn't needed as node didn't exist in clipboard
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
be_clipboard->Commit();
|
||||||
|
}
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
|
||||||
|
BMessenger(kTrackerSignature).SendMessage(&updateMessage);
|
||||||
|
// Tracker will notify all listeners
|
||||||
|
|
||||||
|
return refsAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
FSClipboardRemovePoses(const node_ref *directory, PoseList *list)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!be_clipboard->Lock())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// update message to be send to all listeners
|
||||||
|
BMessage updateMessage(kFSClipboardChanges);
|
||||||
|
updateMessage.AddInt32("device", directory->device);
|
||||||
|
updateMessage.AddInt64("directory", directory->node);
|
||||||
|
updateMessage.AddBool("clearClipboard", false);
|
||||||
|
|
||||||
|
TClipboardNodeRef clipNode;
|
||||||
|
clipNode.moveMode = kDelete;
|
||||||
|
|
||||||
|
uint32 refsRemoved = 0;
|
||||||
|
|
||||||
|
BMessage *clip = be_clipboard->Data();
|
||||||
|
if (clip != NULL) {
|
||||||
|
int32 listCount = list->CountItems();
|
||||||
|
|
||||||
|
for (int32 index = 0; index < listCount; index++) {
|
||||||
|
char refName[64], modeName[64];
|
||||||
|
BPose *pose = (BPose *)list->ItemAt(index);
|
||||||
|
|
||||||
|
clipNode.node = *pose->TargetModel()->NodeRef();
|
||||||
|
MakeRefName(refName, &clipNode.node);
|
||||||
|
MakeModeName(modeName);
|
||||||
|
|
||||||
|
if (clip->RemoveName(refName) == B_OK && clip->RemoveName(modeName)) {
|
||||||
|
updateMessage.AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
|
||||||
|
sizeof(TClipboardNodeRef), true, listCount);
|
||||||
|
refsRemoved++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
be_clipboard->Commit();
|
||||||
|
}
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
|
||||||
|
BMessenger(kTrackerSignature).SendMessage(&updateMessage);
|
||||||
|
// Tracker will notify all listeners
|
||||||
|
|
||||||
|
return refsRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Pastes entries from the clipboard to the target model's directory.
|
||||||
|
* Updates moveModes and notifies listeners if necessary.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
FSClipboardPaste(Model *model, uint32 linksMode)
|
||||||
|
{
|
||||||
|
if (!FSClipboardHasRefs())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BMessenger tracker(kTrackerSignature);
|
||||||
|
|
||||||
|
node_ref *destNodeRef = (node_ref *)model->NodeRef();
|
||||||
|
|
||||||
|
// these will be passed to the asynchronous copy/move process
|
||||||
|
BObjectList<entry_ref> *moveList = new BObjectList<entry_ref>(0, true);
|
||||||
|
BObjectList<entry_ref> *copyList = new BObjectList<entry_ref>(0, true);
|
||||||
|
|
||||||
|
if ((be_clipboard->Lock())) {
|
||||||
|
BMessage *clip = be_clipboard->Data();
|
||||||
|
if (clip != NULL) {
|
||||||
|
char modeName[64];
|
||||||
|
uint32 moveMode = 0;
|
||||||
|
|
||||||
|
BMessage *updateMessage = NULL;
|
||||||
|
node_ref updateNodeRef;
|
||||||
|
updateNodeRef.device = -1;
|
||||||
|
|
||||||
|
char *refName;
|
||||||
|
type_code type;
|
||||||
|
int32 count;
|
||||||
|
for (int32 index = 0; clip->GetInfo(B_REF_TYPE, index,
|
||||||
|
#ifdef B_BEOS_VERSION_DANO
|
||||||
|
(const char **)
|
||||||
|
#endif
|
||||||
|
&refName, &type, &count) == B_OK; index++) {
|
||||||
|
entry_ref ref;
|
||||||
|
if (clip->FindRef(refName, &ref) != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If the entry_ref's directory has changed, send previous notification
|
||||||
|
// (if any), and start new one for the new directory
|
||||||
|
if (updateNodeRef.device != ref.device
|
||||||
|
|| updateNodeRef.node != ref.directory) {
|
||||||
|
if (updateMessage != NULL) {
|
||||||
|
tracker.SendMessage(updateMessage);
|
||||||
|
delete updateMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateNodeRef.device = ref.device;
|
||||||
|
updateNodeRef.node = ref.directory;
|
||||||
|
|
||||||
|
updateMessage = new BMessage(kFSClipboardChanges);
|
||||||
|
updateMessage->AddInt32("device", updateNodeRef.device);
|
||||||
|
updateMessage->AddInt64("directory", updateNodeRef.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need this data later on
|
||||||
|
MakeModeNameFromRefName(modeName, refName);
|
||||||
|
if (!linksMode && clip->FindInt32(modeName, (int32 *)&moveMode) != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BEntry entry(&ref);
|
||||||
|
|
||||||
|
uint32 newMoveMode = 0;
|
||||||
|
bool sameDirectory = destNodeRef->device == ref.device && destNodeRef->node == ref.directory;
|
||||||
|
|
||||||
|
if (!entry.Exists()) {
|
||||||
|
// The entry doesn't exist anymore, so we'll remove
|
||||||
|
// that entry from the clipboard as well
|
||||||
|
clip->RemoveName(refName);
|
||||||
|
clip->RemoveName(modeName);
|
||||||
|
|
||||||
|
newMoveMode = kDelete;
|
||||||
|
} else {
|
||||||
|
// the entry does exist, so lets see what we will
|
||||||
|
// do with it
|
||||||
|
if (!sameDirectory) {
|
||||||
|
if (linksMode || moveMode == kMoveSelectionTo) {
|
||||||
|
// the linksMode uses the moveList as well
|
||||||
|
moveList->AddItem(new entry_ref(ref));
|
||||||
|
} else if (moveMode == kCopySelectionTo)
|
||||||
|
copyList->AddItem(new entry_ref(ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the entry should have been removed from its directory,
|
||||||
|
// we want to copy that entry next time, no matter if the
|
||||||
|
// items don't have to be moved at all (source == target)
|
||||||
|
if (moveMode == kMoveSelectionTo)
|
||||||
|
newMoveMode = kCopySelectionTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the change to the update message (if necessary)
|
||||||
|
if (newMoveMode) {
|
||||||
|
clip->ReplaceInt32(modeName, kCopySelectionTo);
|
||||||
|
|
||||||
|
TClipboardNodeRef clipNode;
|
||||||
|
MakeNodeFromName(&clipNode.node, modeName);
|
||||||
|
clipNode.moveMode = kDelete;
|
||||||
|
updateMessage->AddData("tcnode", T_CLIPBOARD_NODE, &clipNode,
|
||||||
|
sizeof(TClipboardNodeRef), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
be_clipboard->Commit();
|
||||||
|
|
||||||
|
// send notification for the last directory
|
||||||
|
if (updateMessage != NULL) {
|
||||||
|
tracker.SendMessage(updateMessage);
|
||||||
|
delete updateMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool okToMove = true;
|
||||||
|
|
||||||
|
// can't copy/paste to root('/') directory
|
||||||
|
if (model->IsRoot()) {
|
||||||
|
(new BAlert("", kNoCopyToRootStr, "Cancel", NULL, NULL,
|
||||||
|
B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go();
|
||||||
|
okToMove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BEntry entry;
|
||||||
|
model->GetEntry(&entry);
|
||||||
|
|
||||||
|
// can't copy items into the trash
|
||||||
|
if (copyList->CountItems() > 0 && FSIsTrashDir(&entry)) {
|
||||||
|
(new BAlert("", kNoCopyToTrashStr, "Cancel", NULL, NULL,
|
||||||
|
B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go();
|
||||||
|
okToMove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!okToMove) {
|
||||||
|
// there was some problem with our target, so we bail out here
|
||||||
|
delete moveList;
|
||||||
|
delete copyList;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous calls take over ownership of the objects passed to it
|
||||||
|
if (moveList->CountItems() > 0)
|
||||||
|
FSMoveToFolder(moveList, new BEntry(entry), linksMode ? linksMode : kMoveSelectionTo);
|
||||||
|
else
|
||||||
|
delete moveList;
|
||||||
|
|
||||||
|
if (copyList->CountItems() > 0)
|
||||||
|
FSMoveToFolder(copyList, new BEntry(entry), kCopySelectionTo);
|
||||||
|
else
|
||||||
|
delete copyList;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Seek node in clipboard, if found return it's moveMode
|
||||||
|
* else return 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32
|
||||||
|
FSClipboardFindNodeMode(Model *model, bool updateRefIfNeeded)
|
||||||
|
{
|
||||||
|
int32 moveMode = 0;
|
||||||
|
|
||||||
|
if (be_clipboard->Lock()) {
|
||||||
|
bool remove = false;
|
||||||
|
bool change = false;
|
||||||
|
|
||||||
|
BMessage *clip = be_clipboard->Data();
|
||||||
|
if (clip != NULL) {
|
||||||
|
const node_ref *node = model->NodeRef();
|
||||||
|
char modeName[64];
|
||||||
|
MakeModeName(modeName, node);
|
||||||
|
if ((clip->FindInt32(modeName, &moveMode) == B_OK)) {
|
||||||
|
const entry_ref *ref = model->EntryRef();
|
||||||
|
entry_ref clipref;
|
||||||
|
char refName[64];
|
||||||
|
MakeRefName(refName, node);
|
||||||
|
if ((clip->FindRef(refName, &clipref) == B_OK)) {
|
||||||
|
if (clipref != *ref) {
|
||||||
|
if (updateRefIfNeeded) {
|
||||||
|
clip->ReplaceRef(refName, ref);
|
||||||
|
change = true;
|
||||||
|
} else {
|
||||||
|
clip->RemoveName(refName);
|
||||||
|
clip->RemoveName(modeName);
|
||||||
|
change = true;
|
||||||
|
remove = true;
|
||||||
|
moveMode = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clip->RemoveName(modeName);
|
||||||
|
change = true;
|
||||||
|
remove = true;
|
||||||
|
moveMode = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (change)
|
||||||
|
be_clipboard->Commit();
|
||||||
|
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
|
||||||
|
if (remove)
|
||||||
|
FSClipboardRemove(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32)moveMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FSClipboardRemove(Model *model)
|
||||||
|
{
|
||||||
|
BMessenger messenger(kTrackerSignature);
|
||||||
|
if (messenger.IsValid()) {
|
||||||
|
BMessage *report = new BMessage(kFSClipboardChanges);
|
||||||
|
TClipboardNodeRef tcnode;
|
||||||
|
tcnode.node = *model->NodeRef();
|
||||||
|
tcnode.moveMode = kDelete;
|
||||||
|
const entry_ref *ref = model->EntryRef();
|
||||||
|
report->AddInt32("device", ref->device);
|
||||||
|
report->AddInt64("directory", ref->directory);
|
||||||
|
report->AddBool("clearClipboard", false);
|
||||||
|
report->AddData("tcnode", T_CLIPBOARD_NODE, &tcnode, sizeof(tcnode), true);
|
||||||
|
messenger.SendMessage(report);
|
||||||
|
delete report;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
BClipboardRefsWatcher::BClipboardRefsWatcher()
|
||||||
|
: BLooper("ClipboardRefsWatcher", B_LOW_PRIORITY, 4096),
|
||||||
|
fNotifyList(10, false)
|
||||||
|
{
|
||||||
|
watch_node(NULL, B_WATCH_MOUNT, this);
|
||||||
|
fRefsInClipboard = FSClipboardHasRefs();
|
||||||
|
be_clipboard->StartWatching(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BClipboardRefsWatcher::~BClipboardRefsWatcher()
|
||||||
|
{
|
||||||
|
stop_watching(this);
|
||||||
|
be_clipboard->StopWatching(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::AddToNotifyList(BMessenger target)
|
||||||
|
{
|
||||||
|
if (Lock()) {
|
||||||
|
// add the messenger if it's not already in the list
|
||||||
|
// ToDo: why do we have to care about that?
|
||||||
|
BMessenger *messenger;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (int32 index = 0;(messenger = fNotifyList.ItemAt(index)) != NULL; index++) {
|
||||||
|
if (*messenger == target) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
fNotifyList.AddItem(new BMessenger(target));
|
||||||
|
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::RemoveFromNotifyList(BMessenger target)
|
||||||
|
{
|
||||||
|
if (Lock()) {
|
||||||
|
BMessenger *messenger;
|
||||||
|
|
||||||
|
for (int32 index = 0;(messenger = fNotifyList.ItemAt(index)) != NULL; index++) {
|
||||||
|
if (*messenger == target) {
|
||||||
|
delete fNotifyList.RemoveItemAt(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::AddNode(const node_ref *node)
|
||||||
|
{
|
||||||
|
TTracker::WatchNode(node, B_WATCH_NAME, this);
|
||||||
|
fRefsInClipboard = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::RemoveNode(node_ref *node, bool removeFromClipboard)
|
||||||
|
{
|
||||||
|
watch_node(node, B_STOP_WATCHING, this);
|
||||||
|
|
||||||
|
if (!removeFromClipboard)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (be_clipboard->Lock()) {
|
||||||
|
BMessage *clip = be_clipboard->Data();
|
||||||
|
if (clip != NULL) {
|
||||||
|
char name[64];
|
||||||
|
MakeRefName(name, node);
|
||||||
|
clip->RemoveName(name);
|
||||||
|
MakeModeName(name);
|
||||||
|
clip->RemoveName(name);
|
||||||
|
|
||||||
|
be_clipboard->Commit();
|
||||||
|
}
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::RemoveNodesByDevice(dev_t device)
|
||||||
|
{
|
||||||
|
if (!be_clipboard->Lock())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BMessage *clip = be_clipboard->Data();
|
||||||
|
if (clip != NULL) {
|
||||||
|
char deviceName[6];
|
||||||
|
sprintf(deviceName, "r%ld_", device);
|
||||||
|
|
||||||
|
int32 index = 0;
|
||||||
|
char *refName;
|
||||||
|
type_code type;
|
||||||
|
int32 count;
|
||||||
|
while (clip->GetInfo(B_REF_TYPE, index,
|
||||||
|
#ifdef B_BEOS_VERSION_DANO
|
||||||
|
(const char **)
|
||||||
|
#endif
|
||||||
|
&refName, &type, &count) == B_OK) {
|
||||||
|
if (!strncmp(deviceName, refName, strlen(deviceName))) {
|
||||||
|
clip->RemoveName(refName);
|
||||||
|
MakeModeName(refName);
|
||||||
|
clip->RemoveName(refName);
|
||||||
|
|
||||||
|
node_ref node;
|
||||||
|
MakeNodeFromName(&node, refName);
|
||||||
|
watch_node(&node, B_STOP_WATCHING, this);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
be_clipboard->Commit();
|
||||||
|
}
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::UpdateNode(node_ref *node, entry_ref *ref)
|
||||||
|
{
|
||||||
|
if (!be_clipboard->Lock())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BMessage *clip = be_clipboard->Data();
|
||||||
|
if (clip != NULL) {
|
||||||
|
char name[64];
|
||||||
|
MakeRefName(name, node);
|
||||||
|
if ((clip->ReplaceRef(name, ref)) != B_OK) {
|
||||||
|
clip->RemoveName(name);
|
||||||
|
MakeModeName(name);
|
||||||
|
clip->RemoveName(name);
|
||||||
|
|
||||||
|
RemoveNode(node);
|
||||||
|
}
|
||||||
|
be_clipboard->Commit();
|
||||||
|
}
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::Clear()
|
||||||
|
{
|
||||||
|
stop_watching(this);
|
||||||
|
watch_node(NULL, B_WATCH_MOUNT, this);
|
||||||
|
|
||||||
|
BMessage message(kFSClipboardChanges);
|
||||||
|
message.AddBool("clearClipboard", true);
|
||||||
|
if (Lock()) {
|
||||||
|
int32 items = fNotifyList.CountItems();
|
||||||
|
for (int32 i = 0;i < items;i++) {
|
||||||
|
fNotifyList.ItemAt(i)->SendMessage(&message);
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::UpdatePoseViews(bool clearClipboard, const node_ref *node)
|
||||||
|
{
|
||||||
|
BMessage message(kFSClipboardChanges);
|
||||||
|
message.AddInt32("device", node->device);
|
||||||
|
message.AddInt64("directory", node->node);
|
||||||
|
message.AddBool("clearClipboard", clearClipboard);
|
||||||
|
|
||||||
|
if (Lock()) {
|
||||||
|
int32 items = fNotifyList.CountItems();
|
||||||
|
for (int32 i = 0;i < items;i++) {
|
||||||
|
fNotifyList.ItemAt(i)->SendMessage(&message);
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::UpdatePoseViews(BMessage *reportMessage)
|
||||||
|
{
|
||||||
|
if (Lock()) {
|
||||||
|
// check if it was cleared, if so clear watching
|
||||||
|
bool clearClipboard = false;
|
||||||
|
if (reportMessage->FindBool("clearClipboard", &clearClipboard) == B_OK
|
||||||
|
&& clearClipboard) {
|
||||||
|
stop_watching(this);
|
||||||
|
watch_node(NULL, B_WATCH_MOUNT, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop through reported node_ref's movemodes:
|
||||||
|
// move or copy: start watching node_ref
|
||||||
|
// remove: stop watching node_ref
|
||||||
|
int32 index = 0;
|
||||||
|
TClipboardNodeRef *tcnode = NULL;
|
||||||
|
ssize_t size;
|
||||||
|
while (reportMessage->FindData("tcnode", T_CLIPBOARD_NODE, index, (const void**)&tcnode, &size) == B_OK) {
|
||||||
|
if (tcnode->moveMode == kDelete) {
|
||||||
|
watch_node(&tcnode->node, B_STOP_WATCHING, this);
|
||||||
|
} else {
|
||||||
|
watch_node(&tcnode->node, B_STOP_WATCHING, this);
|
||||||
|
TTracker::WatchNode(&tcnode->node, B_WATCH_NAME, this);
|
||||||
|
fRefsInClipboard = true;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send report
|
||||||
|
int32 items = fNotifyList.CountItems();
|
||||||
|
for (int32 i = 0;i < items;i++) {
|
||||||
|
fNotifyList.ItemAt(i)->SendMessage(reportMessage);
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BClipboardRefsWatcher::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
if (message->what == B_CLIPBOARD_CHANGED && fRefsInClipboard) {
|
||||||
|
if (!(fRefsInClipboard = FSClipboardHasRefs()))
|
||||||
|
Clear();
|
||||||
|
return;
|
||||||
|
} else if (message->what != B_NODE_MONITOR) {
|
||||||
|
_inherited::MessageReceived(message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message->FindInt32("opcode")) {
|
||||||
|
case B_ENTRY_MOVED:
|
||||||
|
{
|
||||||
|
ino_t toDir;
|
||||||
|
ino_t fromDir;
|
||||||
|
node_ref node;
|
||||||
|
const char *name = NULL;
|
||||||
|
message->FindInt64("from directory", &fromDir);
|
||||||
|
message->FindInt64("to directory", &toDir);
|
||||||
|
message->FindInt64("node", &node.node);
|
||||||
|
message->FindInt32("device", &node.device);
|
||||||
|
message->FindString("name", &name);
|
||||||
|
entry_ref ref(node.device, toDir, name);
|
||||||
|
UpdateNode(&node, &ref);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_DEVICE_UNMOUNTED:
|
||||||
|
{
|
||||||
|
dev_t device;
|
||||||
|
message->FindInt32("device", &device);
|
||||||
|
RemoveNodesByDevice(device);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_ENTRY_REMOVED:
|
||||||
|
{
|
||||||
|
node_ref node;
|
||||||
|
message->FindInt64("node", &node.node);
|
||||||
|
message->FindInt32("device", &node.device);
|
||||||
|
RemoveNode(&node, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
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 FS_CLIPBOARD_H
|
||||||
|
#define FS_CLIPBOARD_H
|
||||||
|
|
||||||
|
#include <Looper.h>
|
||||||
|
#include "Model.h"
|
||||||
|
#include "ObjectList.h"
|
||||||
|
#include "Pose.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
node_ref node;
|
||||||
|
uint32 moveMode;
|
||||||
|
} TClipboardNodeRef;
|
||||||
|
const int32 T_CLIPBOARD_NODE = 'TCNR';
|
||||||
|
|
||||||
|
class BClipboardRefsWatcher : public BLooper {
|
||||||
|
public:
|
||||||
|
BClipboardRefsWatcher();
|
||||||
|
virtual ~BClipboardRefsWatcher();
|
||||||
|
|
||||||
|
void AddToNotifyList(BMessenger target);
|
||||||
|
void RemoveFromNotifyList(BMessenger target);
|
||||||
|
void AddNode(const node_ref *node);
|
||||||
|
void RemoveNode(node_ref *node, bool removeFromClipboard = false);
|
||||||
|
void RemoveNodesByDevice(dev_t device);
|
||||||
|
void UpdateNode(node_ref *node, entry_ref *ref);
|
||||||
|
void Clear();
|
||||||
|
// void UpdatePoseViews(bool clearClipboard, const node_ref *node);
|
||||||
|
void UpdatePoseViews(BMessage *reportMessage);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fRefsInClipboard;
|
||||||
|
BObjectList<BMessenger> fNotifyList;
|
||||||
|
|
||||||
|
typedef BLooper _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
//bool FSClipboardCheckIntegrity();
|
||||||
|
bool FSClipboardHasRefs();
|
||||||
|
|
||||||
|
void FSClipboardStartWatch(BMessenger target);
|
||||||
|
void FSClipboardStopWatch(BMessenger target);
|
||||||
|
|
||||||
|
void FSClipboardClear();
|
||||||
|
uint32 FSClipboardAddPoses(const node_ref *directory, PoseList *list, uint32 moveMode, bool clearClipboard);
|
||||||
|
uint32 FSClipboardRemovePoses(const node_ref *directory, PoseList *list);
|
||||||
|
bool FSClipboardPaste(Model *model, uint32 linksMode = 0);
|
||||||
|
void FSClipboardRemove(Model *model);
|
||||||
|
uint32 FSClipboardFindNodeMode(Model *model, bool updateRefIfNeeded);
|
||||||
|
|
||||||
|
#endif /* FS_CLIPBOARD_H */
|
||||||
@@ -0,0 +1,459 @@
|
|||||||
|
#include "Commands.h"
|
||||||
|
#include "FSUndoRedo.h"
|
||||||
|
#include "FSUtils.h"
|
||||||
|
|
||||||
|
#include <Autolock.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
#include <Node.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const int32 kUndoRedoListMaxCount = 20;
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class UndoItem {
|
||||||
|
public:
|
||||||
|
virtual ~UndoItem() {}
|
||||||
|
|
||||||
|
virtual status_t Undo() = 0;
|
||||||
|
virtual status_t Redo() = 0;
|
||||||
|
|
||||||
|
virtual void UpdateEntry(BEntry */*entry*/, const char */*name*/) {}
|
||||||
|
// updates the name of the target from the source entry "entry"
|
||||||
|
};
|
||||||
|
|
||||||
|
static BObjectList<UndoItem> sUndoList, sRedoList;
|
||||||
|
static BLocker sLock("undo");
|
||||||
|
|
||||||
|
class UndoItemCopy : public UndoItem {
|
||||||
|
public:
|
||||||
|
UndoItemCopy(BObjectList<entry_ref> *sourceList, BDirectory &target,
|
||||||
|
BList *pointList, uint32 moveMode);
|
||||||
|
virtual ~UndoItemCopy();
|
||||||
|
|
||||||
|
virtual status_t Undo();
|
||||||
|
virtual status_t Redo();
|
||||||
|
virtual void UpdateEntry(BEntry *entry, const char *name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BObjectList<entry_ref> fSourceList;
|
||||||
|
BObjectList<entry_ref> fTargetList;
|
||||||
|
entry_ref fSourceRef, fTargetRef;
|
||||||
|
uint32 fMoveMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UndoItemMove : public UndoItem {
|
||||||
|
public:
|
||||||
|
/** source - list of file(s) that were moved. Assumes ownership.
|
||||||
|
* origfolder - location it was moved from
|
||||||
|
*/
|
||||||
|
UndoItemMove(BObjectList<entry_ref> *sourceList, BDirectory &target, BList *pointList);
|
||||||
|
virtual ~UndoItemMove();
|
||||||
|
|
||||||
|
virtual status_t Undo();
|
||||||
|
virtual status_t Redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BObjectList<entry_ref> fSourceList;
|
||||||
|
entry_ref fSourceRef, fTargetRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UndoItemFolder : public UndoItem {
|
||||||
|
public:
|
||||||
|
UndoItemFolder(const entry_ref &ref);
|
||||||
|
// ref - entry_ref indicating the folder created
|
||||||
|
virtual ~UndoItemFolder();
|
||||||
|
|
||||||
|
virtual status_t Undo();
|
||||||
|
virtual status_t Redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* this ref has two different meanings in the different states of this object:
|
||||||
|
- Undo() - fRef indicates the folder that was created via FSCreateNewFolderIn(...)
|
||||||
|
- Redo() - fRef indicates the folder in which FSCreateNewFolderIn() should be performed
|
||||||
|
*/
|
||||||
|
entry_ref fRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UndoItemRename : public UndoItem {
|
||||||
|
public:
|
||||||
|
UndoItemRename(const entry_ref &origRef, const entry_ref &ref);
|
||||||
|
UndoItemRename(const BEntry &entry, const char *newName);
|
||||||
|
virtual ~UndoItemRename();
|
||||||
|
|
||||||
|
virtual status_t Undo();
|
||||||
|
virtual status_t Redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
entry_ref fRef, fOrigRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UndoItemRenameVolume : public UndoItem {
|
||||||
|
public:
|
||||||
|
UndoItemRenameVolume(BVolume &volume, const char *newName);
|
||||||
|
virtual ~UndoItemRenameVolume();
|
||||||
|
|
||||||
|
virtual status_t Undo();
|
||||||
|
virtual status_t Redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BVolume fVolume;
|
||||||
|
BString fOldName, fNewName;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
ChangeListSource(BObjectList<entry_ref> &list, BEntry &entry)
|
||||||
|
{
|
||||||
|
node_ref source;
|
||||||
|
if (entry.GetNodeRef(&source) != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
for (int32 index = 0; index < list.CountItems(); index++) {
|
||||||
|
entry_ref *ref = list.ItemAt(index);
|
||||||
|
|
||||||
|
ref->device = source.device;
|
||||||
|
ref->directory = source.node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
AddUndoItem(UndoItem *item)
|
||||||
|
{
|
||||||
|
BAutolock locker(sLock);
|
||||||
|
|
||||||
|
// we have a restricted number of possible undos
|
||||||
|
if (sUndoList.CountItems() == kUndoRedoListMaxCount)
|
||||||
|
sUndoList.RemoveItem(sUndoList.LastItem());
|
||||||
|
|
||||||
|
sUndoList.AddItem(item, 0);
|
||||||
|
sRedoList.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
Undo::~Undo()
|
||||||
|
{
|
||||||
|
if (fUndo != NULL)
|
||||||
|
AddUndoItem(fUndo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Undo::UpdateEntry(BEntry *entry, const char *destName)
|
||||||
|
{
|
||||||
|
if (fUndo != NULL)
|
||||||
|
fUndo->UpdateEntry(entry, destName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Undo::Remove()
|
||||||
|
{
|
||||||
|
delete fUndo;
|
||||||
|
fUndo = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MoveCopyUndo::MoveCopyUndo(BObjectList<entry_ref> *sourceList, BDirectory &dest,
|
||||||
|
BList *pointList, uint32 moveMode)
|
||||||
|
{
|
||||||
|
if (moveMode == kMoveSelectionTo)
|
||||||
|
fUndo = new UndoItemMove(sourceList, dest, pointList);
|
||||||
|
else
|
||||||
|
fUndo = new UndoItemCopy(sourceList, dest, pointList, moveMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NewFolderUndo::NewFolderUndo(const entry_ref &ref)
|
||||||
|
{
|
||||||
|
fUndo = new UndoItemFolder(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RenameUndo::RenameUndo(BEntry &entry, const char *newName)
|
||||||
|
{
|
||||||
|
fUndo = new UndoItemRename(entry, newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RenameVolumeUndo::RenameVolumeUndo(BVolume &volume, const char *newName)
|
||||||
|
{
|
||||||
|
fUndo = new UndoItemRenameVolume(volume, newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemCopy::UndoItemCopy(BObjectList<entry_ref> *sourceList, BDirectory &target,
|
||||||
|
BList */*pointList*/, uint32 moveMode)
|
||||||
|
:
|
||||||
|
fSourceList(*sourceList),
|
||||||
|
fTargetList(*sourceList),
|
||||||
|
fMoveMode(moveMode)
|
||||||
|
{
|
||||||
|
BEntry entry(sourceList->ItemAt(0));
|
||||||
|
|
||||||
|
BEntry sourceEntry;
|
||||||
|
entry.GetParent(&sourceEntry);
|
||||||
|
sourceEntry.GetRef(&fSourceRef);
|
||||||
|
|
||||||
|
BEntry targetEntry;
|
||||||
|
target.GetEntry(&targetEntry);
|
||||||
|
targetEntry.GetRef(&fTargetRef);
|
||||||
|
ChangeListSource(fTargetList, targetEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemCopy::~UndoItemCopy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemCopy::Undo()
|
||||||
|
{
|
||||||
|
FSDeleteRefList(new BObjectList<entry_ref>(fTargetList), true, false);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemCopy::Redo()
|
||||||
|
{
|
||||||
|
FSMoveToFolder(new BObjectList<entry_ref>(fSourceList), new BEntry(&fTargetRef),
|
||||||
|
FSUndoMoveMode(fMoveMode), NULL);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
UndoItemCopy::UpdateEntry(BEntry *entry, const char *name)
|
||||||
|
{
|
||||||
|
entry_ref changedRef;
|
||||||
|
if (entry->GetRef(&changedRef) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int32 index = 0; index < fSourceList.CountItems(); index++) {
|
||||||
|
entry_ref *ref = fSourceList.ItemAt(index);
|
||||||
|
if (changedRef != *ref)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ref = fTargetList.ItemAt(index);
|
||||||
|
ref->set_name(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemMove::UndoItemMove(BObjectList<entry_ref> *sourceList, BDirectory &target,
|
||||||
|
BList */*pointList*/)
|
||||||
|
:
|
||||||
|
fSourceList(*sourceList)
|
||||||
|
{
|
||||||
|
BEntry entry(sourceList->ItemAt(0));
|
||||||
|
BEntry source;
|
||||||
|
entry.GetParent(&source);
|
||||||
|
source.GetRef(&fSourceRef);
|
||||||
|
|
||||||
|
BEntry targetEntry;
|
||||||
|
target.GetEntry(&targetEntry);
|
||||||
|
targetEntry.GetRef(&fTargetRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemMove::~UndoItemMove()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemMove::Undo()
|
||||||
|
{
|
||||||
|
BObjectList<entry_ref> *list = new BObjectList<entry_ref>(fSourceList);
|
||||||
|
BEntry entry(&fTargetRef);
|
||||||
|
ChangeListSource(*list, entry);
|
||||||
|
|
||||||
|
// FSMoveToFolder() owns its arguments
|
||||||
|
FSMoveToFolder(list, new BEntry(&fSourceRef), FSUndoMoveMode(kMoveSelectionTo), NULL);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemMove::Redo()
|
||||||
|
{
|
||||||
|
// FSMoveToFolder() owns its arguments
|
||||||
|
FSMoveToFolder(new BObjectList<entry_ref>(fSourceList), new BEntry(&fTargetRef),
|
||||||
|
FSUndoMoveMode(kMoveSelectionTo), NULL);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemFolder::UndoItemFolder(const entry_ref &ref)
|
||||||
|
:
|
||||||
|
fRef(ref)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemFolder::~UndoItemFolder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemFolder::Undo()
|
||||||
|
{
|
||||||
|
FSDelete(new entry_ref(fRef), false, false);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemFolder::Redo()
|
||||||
|
{
|
||||||
|
return FSCreateNewFolder(&fRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemRename::UndoItemRename(const entry_ref &origRef, const entry_ref &ref)
|
||||||
|
:
|
||||||
|
fRef(ref),
|
||||||
|
fOrigRef(origRef)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemRename::UndoItemRename(const BEntry &entry, const char *newName)
|
||||||
|
{
|
||||||
|
entry.GetRef(&fOrigRef);
|
||||||
|
|
||||||
|
fRef = fOrigRef;
|
||||||
|
fRef.set_name(newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemRename::~UndoItemRename()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemRename::Undo()
|
||||||
|
{
|
||||||
|
BEntry entry(&fRef, false);
|
||||||
|
return entry.Rename(fOrigRef.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemRename::Redo()
|
||||||
|
{
|
||||||
|
BEntry entry(&fOrigRef, false);
|
||||||
|
return entry.Rename(fRef.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemRenameVolume::UndoItemRenameVolume(BVolume &volume, const char *newName)
|
||||||
|
:
|
||||||
|
fVolume(volume),
|
||||||
|
fNewName(newName)
|
||||||
|
{
|
||||||
|
char *buffer = fOldName.LockBuffer(B_FILE_NAME_LENGTH);
|
||||||
|
if (buffer != NULL) {
|
||||||
|
fVolume.GetName(buffer);
|
||||||
|
fOldName.UnlockBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UndoItemRenameVolume::~UndoItemRenameVolume()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemRenameVolume::Undo()
|
||||||
|
{
|
||||||
|
return fVolume.SetName(fOldName.String());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoItemRenameVolume::Redo()
|
||||||
|
{
|
||||||
|
return fVolume.SetName(fNewName.String());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FSUndo()
|
||||||
|
{
|
||||||
|
BAutolock locker(sLock);
|
||||||
|
|
||||||
|
UndoItem *undoItem = sUndoList.FirstItem();
|
||||||
|
if (undoItem == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
undoItem->Undo();
|
||||||
|
// ToDo: evaluate return code
|
||||||
|
|
||||||
|
sUndoList.RemoveItem(undoItem);
|
||||||
|
|
||||||
|
if (sRedoList.CountItems() == kUndoRedoListMaxCount)
|
||||||
|
sRedoList.RemoveItem(sRedoList.LastItem());
|
||||||
|
|
||||||
|
sRedoList.AddItem(undoItem, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FSRedo()
|
||||||
|
{
|
||||||
|
BAutolock locker(sLock);
|
||||||
|
|
||||||
|
UndoItem *undoItem = sRedoList.FirstItem();
|
||||||
|
if (undoItem == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
undoItem->Redo();
|
||||||
|
// ToDo: evaluate return code
|
||||||
|
|
||||||
|
sRedoList.RemoveItem(undoItem);
|
||||||
|
|
||||||
|
if (sUndoList.CountItems() == kUndoRedoListMaxCount)
|
||||||
|
sUndoList.RemoveItem(sUndoList.LastItem());
|
||||||
|
|
||||||
|
sUndoList.AddItem(undoItem, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#ifndef _FS_UNDO_REDO_H
|
||||||
|
#define _FS_UNDO_REDO_H
|
||||||
|
|
||||||
|
#include "ObjectList.h"
|
||||||
|
#include <Entry.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class UndoItem;
|
||||||
|
|
||||||
|
class Undo {
|
||||||
|
public:
|
||||||
|
~Undo();
|
||||||
|
void UpdateEntry(BEntry *entry, const char *destName);
|
||||||
|
void Remove();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
UndoItem *fUndo;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MoveCopyUndo : public Undo {
|
||||||
|
public:
|
||||||
|
MoveCopyUndo(BObjectList<entry_ref> *sourceList, BDirectory &dest,
|
||||||
|
BList *pointList, uint32 moveMode);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NewFolderUndo : public Undo {
|
||||||
|
public:
|
||||||
|
NewFolderUndo(const entry_ref &ref);
|
||||||
|
};
|
||||||
|
|
||||||
|
class RenameUndo : public Undo {
|
||||||
|
public:
|
||||||
|
RenameUndo(BEntry &entry, const char *newName);
|
||||||
|
};
|
||||||
|
|
||||||
|
class RenameVolumeUndo : public Undo {
|
||||||
|
public:
|
||||||
|
RenameVolumeUndo(BVolume &volume, const char *newName);
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
inline bool FSIsUndoMoveMode(uint32 moveMode)
|
||||||
|
{
|
||||||
|
return (moveMode & '\xff\0\0\0') == 'U\0\0\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline uint32 FSUndoMoveMode(uint32 moveMode)
|
||||||
|
{
|
||||||
|
return (moveMode & ~'\xff\0\0\0') | 'U\0\0\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline uint32 FSMoveMode(uint32 moveMode)
|
||||||
|
{
|
||||||
|
return (moveMode & ~'\xff\0\0\0') | 'T\0\0\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void FSUndo();
|
||||||
|
extern void FSRedo();
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
#endif /* _FS_UNDO_REDO_H */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,311 @@
|
|||||||
|
/*
|
||||||
|
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 FS_UTILS_H
|
||||||
|
#define FS_UTILS_H
|
||||||
|
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <Point.h>
|
||||||
|
#include <StorageDefs.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Model.h"
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
// Note - APIs/code in FSUtils.h and FSUtils.cpp is slated for a major cleanup
|
||||||
|
// -- in other words, you will find a lot of ugly cruft in here
|
||||||
|
|
||||||
|
class BDirectory;
|
||||||
|
class BEntry;
|
||||||
|
class BList;
|
||||||
|
class BFile;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BInfoWindow;
|
||||||
|
|
||||||
|
class CopyLoopControl {
|
||||||
|
// controls the copy engine; may be overriden to specify how conflicts are
|
||||||
|
// handled, etc.
|
||||||
|
// Installer has it's own subclass
|
||||||
|
public:
|
||||||
|
virtual ~CopyLoopControl();
|
||||||
|
virtual bool FileError(const char *message, const char *name, status_t error,
|
||||||
|
bool allowContinue) = 0;
|
||||||
|
// inform that a file error occurred while copying <name>
|
||||||
|
// returns true if user decided to continue
|
||||||
|
|
||||||
|
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
|
||||||
|
bool optional = false) = 0;
|
||||||
|
|
||||||
|
virtual bool CheckUserCanceled() = 0;
|
||||||
|
// returns true if canceled
|
||||||
|
|
||||||
|
enum OverwriteMode {
|
||||||
|
kSkip, // do not replace, go to next entry
|
||||||
|
kReplace, // remove entry before copying new one
|
||||||
|
kMerge // for folders: leave existing folder, update contents leaving
|
||||||
|
// nonconflicting items
|
||||||
|
// for files: save original attributes on file.
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
|
||||||
|
const char *destName, const BDirectory *destDir, bool srcIsDir,
|
||||||
|
bool dstIsDir) = 0;
|
||||||
|
// override to always overwrite, never overwrite, let user decide,
|
||||||
|
// compare dates, etc.
|
||||||
|
|
||||||
|
virtual bool SkipEntry(const BEntry *, bool file) = 0;
|
||||||
|
// override to prevent copying of a given file or directory
|
||||||
|
|
||||||
|
virtual void ChecksumChunk(const char *block, size_t size);
|
||||||
|
// during a file copy, this is called every time a chunk of data
|
||||||
|
// is copied. Users may override to keep a running checksum.
|
||||||
|
|
||||||
|
virtual bool ChecksumFile(const entry_ref *);
|
||||||
|
// This is called when a file is finished copying. Users of this
|
||||||
|
// class may override to verify that the checksum they've been
|
||||||
|
// computing in ChecksumChunk matches. If this returns true,
|
||||||
|
// the copy will continue. If false, if will abort.
|
||||||
|
|
||||||
|
virtual bool SkipAttribute(const char *attributeName);
|
||||||
|
virtual bool PreserveAttribute(const char *attributeName);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TrackerCopyLoopControl : public CopyLoopControl {
|
||||||
|
// this is the Tracker copy - specific version of CopyLoopControl
|
||||||
|
public:
|
||||||
|
TrackerCopyLoopControl(thread_id);
|
||||||
|
virtual ~TrackerCopyLoopControl() {}
|
||||||
|
|
||||||
|
virtual bool FileError(const char *message, const char *name, status_t error,
|
||||||
|
bool allowContinue);
|
||||||
|
// inform that a file error occurred while copying <name>
|
||||||
|
// returns true if user decided to continue
|
||||||
|
|
||||||
|
virtual void UpdateStatus(const char *name, entry_ref ref, int32 count,
|
||||||
|
bool optional = false);
|
||||||
|
|
||||||
|
virtual bool CheckUserCanceled();
|
||||||
|
// returns true if canceled
|
||||||
|
|
||||||
|
virtual OverwriteMode OverwriteOnConflict(const BEntry *srcEntry,
|
||||||
|
const char *destName, const BDirectory *destDir, bool srcIsDir,
|
||||||
|
bool dstIsDir);
|
||||||
|
|
||||||
|
virtual bool SkipEntry(const BEntry *, bool file);
|
||||||
|
// override to prevent copying of a given file or directory
|
||||||
|
|
||||||
|
virtual bool SkipAttribute(const char *attributeName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
thread_id fThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
TrackerCopyLoopControl::TrackerCopyLoopControl(thread_id thread)
|
||||||
|
: fThread(thread)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#define B_DESKTOP_DIR_NAME "Desktop"
|
||||||
|
|
||||||
|
#if B_BEOS_VERSION_DANO
|
||||||
|
#define _IMPEXP_TRACKER
|
||||||
|
#endif
|
||||||
|
_IMPEXP_TRACKER status_t FSCopyAttributesAndStats(BNode *, BNode *);
|
||||||
|
|
||||||
|
_IMPEXP_TRACKER void FSDuplicate(BObjectList<entry_ref> *srcList, BList *pointList);
|
||||||
|
_IMPEXP_TRACKER void FSMoveToFolder(BObjectList<entry_ref> *srcList, BEntry *, uint32 moveMode,
|
||||||
|
BList *pointList = NULL);
|
||||||
|
_IMPEXP_TRACKER void FSMakeOriginalName(char *name, BDirectory *destDir, const char *suffix);
|
||||||
|
_IMPEXP_TRACKER bool FSIsTrashDir(const BEntry *);
|
||||||
|
_IMPEXP_TRACKER bool FSIsPrintersDir(const BEntry *);
|
||||||
|
_IMPEXP_TRACKER bool FSIsDeskDir(const BEntry *);
|
||||||
|
_IMPEXP_TRACKER bool FSIsSystemDir(const BEntry *);
|
||||||
|
_IMPEXP_TRACKER bool FSIsBeOSDir(const BEntry *);
|
||||||
|
_IMPEXP_TRACKER bool FSIsHomeDir(const BEntry *);
|
||||||
|
_IMPEXP_TRACKER void FSMoveToTrash(BObjectList<entry_ref> *srcList, BList *pointList = NULL,
|
||||||
|
bool async = true);
|
||||||
|
// Deprecated
|
||||||
|
|
||||||
|
void FSDeleteRefList(BObjectList<entry_ref> *, bool, bool confirm = true);
|
||||||
|
void FSDelete(entry_ref *, bool, bool confirm = true);
|
||||||
|
void FSRestoreRefList(BObjectList<entry_ref> *list, bool async);
|
||||||
|
|
||||||
|
_IMPEXP_TRACKER status_t FSLaunchItem(const entry_ref *application, const BMessage *refsReceived,
|
||||||
|
bool async, bool openWithOK);
|
||||||
|
// Preferred way of launching; only pass an actual application in <application>, not
|
||||||
|
// a document; to open documents with the preferred app, pase 0 in <application> and
|
||||||
|
// stuff all the document refs into <refsReceived>
|
||||||
|
// Consider having silent mode that does not show alerts, just returns error code
|
||||||
|
|
||||||
|
_IMPEXP_TRACKER status_t FSOpenWith(BMessage *listOfRefs);
|
||||||
|
// runs the Open With window; pas a list of refs
|
||||||
|
|
||||||
|
_IMPEXP_TRACKER void FSEmptyTrash();
|
||||||
|
_IMPEXP_TRACKER status_t FSCreateNewFolderIn(const node_ref *destDir, entry_ref *newRef,
|
||||||
|
node_ref *new_node);
|
||||||
|
_IMPEXP_TRACKER void FSCreateTrashDirs();
|
||||||
|
_IMPEXP_TRACKER status_t FSGetTrashDir(BDirectory *trashDir, dev_t volume);
|
||||||
|
_IMPEXP_TRACKER status_t FSGetDeskDir(BDirectory *deskDir, dev_t volume);
|
||||||
|
_IMPEXP_TRACKER status_t FSRecursiveCalcSize(BInfoWindow *, BDirectory *,
|
||||||
|
off_t *runningSize, int32 *fileCount, int32 *dirCount);
|
||||||
|
|
||||||
|
bool FSInTrashDir(const entry_ref *);
|
||||||
|
|
||||||
|
// doesn't need to be exported
|
||||||
|
bool FSGetPoseLocation(const BNode *node, BPoint *point);
|
||||||
|
status_t FSSetPoseLocation(BEntry *entry, BPoint point);
|
||||||
|
status_t FSSetPoseLocation(ino_t destDirInode, BNode *destNode, BPoint point);
|
||||||
|
status_t FSGetBootDeskDir(BDirectory *deskDir);
|
||||||
|
|
||||||
|
status_t FSGetOriginalPath(BEntry *entry, BPath *path);
|
||||||
|
|
||||||
|
enum ReadAttrResult {
|
||||||
|
kReadAttrFailed,
|
||||||
|
kReadAttrNativeOK,
|
||||||
|
kReadAttrForeignOK
|
||||||
|
};
|
||||||
|
|
||||||
|
ReadAttrResult ReadAttr(const BNode *, const char *hostAttrName, const char *foreignAttrName,
|
||||||
|
type_code , off_t , void *, size_t , void (*swapFunc)(void *) = 0,
|
||||||
|
bool isForeign = false);
|
||||||
|
// Endian swapping ReadAttr call; endianness is determined by trying first the
|
||||||
|
// native attribute name, then the foreign one; an endian swapping function can
|
||||||
|
// be passed, if null data won't be swapped; if <isForeign> set the foreign endianness
|
||||||
|
// will be read directly without first trying the native one
|
||||||
|
|
||||||
|
ReadAttrResult GetAttrInfo(const BNode *, const char *hostAttrName, const char *foreignAttrName,
|
||||||
|
type_code * = NULL, size_t * = NULL);
|
||||||
|
|
||||||
|
status_t FSCreateNewFolder(const entry_ref *);
|
||||||
|
status_t FSRecursiveCreateFolder(const char *path);
|
||||||
|
void FSMakeOriginalName(BString &name, const BDirectory *destDir, const char *suffix = 0);
|
||||||
|
|
||||||
|
status_t TrackerLaunch(const entry_ref *app, bool async);
|
||||||
|
status_t TrackerLaunch(const BMessage *refs, bool async, bool okToRunOpenWith = true);
|
||||||
|
status_t TrackerLaunch(const entry_ref *app, const BMessage *refs, bool async,
|
||||||
|
bool okToRunOpenWith = true);
|
||||||
|
status_t LaunchBrokenLink(const char *, const BMessage *);
|
||||||
|
|
||||||
|
status_t FSFindTrackerSettingsDir(BPath *, bool autoCreate = true);
|
||||||
|
|
||||||
|
bool FSIsDeskDir(const BEntry *, dev_t);
|
||||||
|
|
||||||
|
bool ConfirmChangeIfWellKnownDirectory(const BEntry *entry, const char *action,
|
||||||
|
bool dontAsk = false, int32 *confirmedAlready = NULL);
|
||||||
|
|
||||||
|
// Deprecated calls use newer calls above instead
|
||||||
|
_IMPEXP_TRACKER void FSLaunchItem(const entry_ref *, BMessage * = NULL, int32 workspace = -1);
|
||||||
|
_IMPEXP_TRACKER status_t FSLaunchItem(const entry_ref *, BMessage *,
|
||||||
|
int32 workspace, bool asynch);
|
||||||
|
_IMPEXP_TRACKER void FSOpenWithDocuments(const entry_ref *executableToLaunch,
|
||||||
|
BMessage *documentEntryRefs);
|
||||||
|
_IMPEXP_TRACKER status_t FSLaunchUsing(const entry_ref *ref, BMessage *listOfRefs);
|
||||||
|
|
||||||
|
|
||||||
|
// some extra directory_which values
|
||||||
|
// move these to FindDirectory.h
|
||||||
|
const uint32 B_USER_MAIL_DIRECTORY = 3500;
|
||||||
|
const uint32 B_USER_QUERIES_DIRECTORY = 3501;
|
||||||
|
const uint32 B_USER_PEOPLE_DIRECTORY = 3502;
|
||||||
|
const uint32 B_USER_DOWNLOADS_DIRECTORY = 3503;
|
||||||
|
const uint32 B_USER_DESKBAR_APPS_DIRECTORY = 3504;
|
||||||
|
const uint32 B_USER_DESKBAR_PREFERENCES_DIRECTORY = 3505;
|
||||||
|
const uint32 B_USER_DESKBAR_DEVELOP_DIRECTORY = 3506;
|
||||||
|
|
||||||
|
const int32 B_BOOT_DISK = 10000000;
|
||||||
|
// map /boot into the directory_which enum for convenience
|
||||||
|
|
||||||
|
class WellKnowEntryList {
|
||||||
|
// matches up names, id's and node_refs of well known entries in the
|
||||||
|
// system hierarchy
|
||||||
|
public:
|
||||||
|
struct WellKnownEntry {
|
||||||
|
WellKnownEntry(const node_ref *node, directory_which which, const char *name)
|
||||||
|
:
|
||||||
|
node(*node),
|
||||||
|
which(which),
|
||||||
|
name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// mwcc needs these explicitly to use vector
|
||||||
|
WellKnownEntry(const WellKnownEntry &clone)
|
||||||
|
:
|
||||||
|
node(clone.node),
|
||||||
|
which(clone.which),
|
||||||
|
name(clone.name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WellKnownEntry()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
node_ref node;
|
||||||
|
directory_which which;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static directory_which Match(const node_ref *);
|
||||||
|
static const WellKnownEntry *MatchEntry(const node_ref *);
|
||||||
|
static void Quit();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const WellKnownEntry *MatchEntryCommon(const node_ref *);
|
||||||
|
WellKnowEntryList();
|
||||||
|
void AddOne(directory_which, const char *name);
|
||||||
|
void AddOne(directory_which, const char *path, const char *name);
|
||||||
|
void AddOne(directory_which, directory_which base, const char *extension,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
|
std::vector<WellKnownEntry> entries;
|
||||||
|
static WellKnowEntryList *self;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if B_BEOS_VERSION_DANO
|
||||||
|
#undef _IMPEXP_TRACKER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif /* FS_UTILS_H */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,416 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <Query.h>
|
||||||
|
#include <Roster.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "EntryIterator.h"
|
||||||
|
#include "FavoritesMenu.h"
|
||||||
|
#include "IconMenuItem.h"
|
||||||
|
#include "NavMenu.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
#include "QueryPoseView.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
|
||||||
|
FavoritesMenu::FavoritesMenu(const char *title, BMessage *openFolderMessage,
|
||||||
|
BMessage *openFileMessage, const BMessenger &target,
|
||||||
|
bool isSavePanel)
|
||||||
|
: BSlowMenu(title),
|
||||||
|
fOpenFolderMessage(openFolderMessage),
|
||||||
|
fOpenFileMessage(openFileMessage),
|
||||||
|
fTarget(target),
|
||||||
|
fContainer(NULL),
|
||||||
|
fInitialItemCount(0),
|
||||||
|
fIsSavePanel(isSavePanel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FavoritesMenu::~FavoritesMenu()
|
||||||
|
{
|
||||||
|
delete fOpenFolderMessage;
|
||||||
|
delete fOpenFileMessage;
|
||||||
|
delete fContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FavoritesMenu::StartBuildingItemList()
|
||||||
|
{
|
||||||
|
// initialize the menu building state
|
||||||
|
|
||||||
|
if (!fInitialItemCount)
|
||||||
|
fInitialItemCount = CountItems();
|
||||||
|
else {
|
||||||
|
// strip the old items so we can add new fresh ones
|
||||||
|
int32 count = CountItems() - fInitialItemCount;
|
||||||
|
// keep the items that were added by the FavoritesMenu creator
|
||||||
|
while (count--)
|
||||||
|
delete RemoveItem(fInitialItemCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
fUniqueRefCheck.clear();
|
||||||
|
fState = kStart;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
FavoritesMenu::AddNextItem()
|
||||||
|
{
|
||||||
|
// run the next chunk of code for a given item adding state
|
||||||
|
|
||||||
|
if (fState == kStart) {
|
||||||
|
fState = kAddingFavorites;
|
||||||
|
fSectionItemCount = 0;
|
||||||
|
fAddedSeparatorForSection = false;
|
||||||
|
// set up adding the GoTo menu items
|
||||||
|
|
||||||
|
try {
|
||||||
|
BPath path;
|
||||||
|
ThrowOnError( find_directory (B_USER_SETTINGS_DIRECTORY, &path, true) );
|
||||||
|
path.Append(kGoDirectory);
|
||||||
|
mkdir(path.Path(), 0777);
|
||||||
|
|
||||||
|
BEntry entry(path.Path());
|
||||||
|
Model startModel(&entry, true);
|
||||||
|
ThrowOnInitCheckError(&startModel);
|
||||||
|
|
||||||
|
if (!startModel.IsContainer())
|
||||||
|
throw B_ERROR;
|
||||||
|
|
||||||
|
if (startModel.IsQuery())
|
||||||
|
fContainer = new QueryEntryListCollection(&startModel);
|
||||||
|
else
|
||||||
|
fContainer = new DirectoryEntryList(*dynamic_cast<BDirectory *>
|
||||||
|
(startModel.Node()));
|
||||||
|
|
||||||
|
ThrowOnInitCheckError(fContainer);
|
||||||
|
ThrowOnError( fContainer->Rewind() );
|
||||||
|
|
||||||
|
} catch (...) {
|
||||||
|
delete fContainer;
|
||||||
|
fContainer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (fState == kAddingFavorites) {
|
||||||
|
entry_ref ref;
|
||||||
|
// limit nav menus to 20 items only
|
||||||
|
if (fContainer
|
||||||
|
&& fSectionItemCount < 20
|
||||||
|
&& fContainer->GetNextRef(&ref) == B_OK) {
|
||||||
|
Model model(&ref, true);
|
||||||
|
if (model.InitCheck() != B_OK)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
BMenuItem *item = BNavMenu::NewModelItem(&model,
|
||||||
|
model.IsDirectory() ? fOpenFolderMessage : fOpenFileMessage,
|
||||||
|
fTarget);
|
||||||
|
|
||||||
|
item->SetLabel(ref.name); // this is the name of the link in the Go dir
|
||||||
|
|
||||||
|
if (!fAddedSeparatorForSection) {
|
||||||
|
fAddedSeparatorForSection = true;
|
||||||
|
AddItem(new TitledSeparatorItem("Favorite Folders"));
|
||||||
|
}
|
||||||
|
fUniqueRefCheck.push_back(*model.EntryRef());
|
||||||
|
AddItem(item);
|
||||||
|
fSectionItemCount++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// done with favorites, set up for adding recent files
|
||||||
|
fState = kAddingFiles;
|
||||||
|
|
||||||
|
fAddedSeparatorForSection = false;
|
||||||
|
|
||||||
|
app_info info;
|
||||||
|
be_app->GetAppInfo(&info);
|
||||||
|
fItems.MakeEmpty();
|
||||||
|
|
||||||
|
int32 apps, docs, folders;
|
||||||
|
TrackerSettings().RecentCounts(&apps, &docs, &folders);
|
||||||
|
|
||||||
|
BRoster().GetRecentDocuments(&fItems, docs, NULL, info.signature);
|
||||||
|
fIndex = 0;
|
||||||
|
fSectionItemCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fState == kAddingFiles) {
|
||||||
|
// if this is a Save panel, not an Open panel
|
||||||
|
// then don't add the recent documents
|
||||||
|
if (!fIsSavePanel) {
|
||||||
|
for (;;) {
|
||||||
|
entry_ref ref;
|
||||||
|
if (fItems.FindRef("refs", fIndex++, &ref) != B_OK)
|
||||||
|
break;
|
||||||
|
Model model(&ref, true);
|
||||||
|
if (model.InitCheck() != B_OK)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
BMenuItem *item = BNavMenu::NewModelItem(&model, fOpenFileMessage, fTarget);
|
||||||
|
if (item) {
|
||||||
|
if (!fAddedSeparatorForSection) {
|
||||||
|
fAddedSeparatorForSection = true;
|
||||||
|
AddItem(new TitledSeparatorItem("Recent Documents"));
|
||||||
|
}
|
||||||
|
AddItem(item);
|
||||||
|
fSectionItemCount++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// done with recent files, set up for adding recent folders
|
||||||
|
fState = kAddingFolders;
|
||||||
|
|
||||||
|
fAddedSeparatorForSection = false;
|
||||||
|
|
||||||
|
app_info info;
|
||||||
|
be_app->GetAppInfo(&info);
|
||||||
|
fItems.MakeEmpty();
|
||||||
|
|
||||||
|
int32 apps, docs, folders;
|
||||||
|
TrackerSettings().RecentCounts(&apps, &docs, &folders);
|
||||||
|
|
||||||
|
BRoster().GetRecentFolders(&fItems, folders, info.signature);
|
||||||
|
fIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fState == kAddingFolders) {
|
||||||
|
for (;;) {
|
||||||
|
entry_ref ref;
|
||||||
|
if (fItems.FindRef("refs", fIndex++, &ref) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// don't add folders that are already in the GoTo section
|
||||||
|
if (find_if(fUniqueRefCheck.begin(), fUniqueRefCheck.end(),
|
||||||
|
bind2nd(std::equal_to<entry_ref>(), ref)) != fUniqueRefCheck.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Model model(&ref, true);
|
||||||
|
if (model.InitCheck() != B_OK)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
BMenuItem *item = BNavMenu::NewModelItem(&model, fOpenFolderMessage,
|
||||||
|
fTarget, true);
|
||||||
|
if (item) {
|
||||||
|
if (!fAddedSeparatorForSection) {
|
||||||
|
fAddedSeparatorForSection = true;
|
||||||
|
AddItem(new TitledSeparatorItem("Recent Folders"));
|
||||||
|
}
|
||||||
|
AddItem(item);
|
||||||
|
item->SetEnabled(true);
|
||||||
|
// BNavMenu::NewModelItem returns a disabled item here -
|
||||||
|
// need to fix this in BNavMenu::NewModelItem
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FavoritesMenu::DoneBuildingItemList()
|
||||||
|
{
|
||||||
|
SetTargetForItems(fTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FavoritesMenu::ClearMenuBuildingState()
|
||||||
|
{
|
||||||
|
delete fContainer;
|
||||||
|
fContainer = NULL;
|
||||||
|
fState = kDone;
|
||||||
|
|
||||||
|
// force the menu to get rebuilt each time
|
||||||
|
fMenuBuilt = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
RecentsMenu::RecentsMenu(const char *name,int32 which,uint32 what,BHandler *target)
|
||||||
|
: BNavMenu(name, what, target),
|
||||||
|
fWhich(which),
|
||||||
|
fRecentsCount(0),
|
||||||
|
fItemIndex(0)
|
||||||
|
{
|
||||||
|
int32 applications;
|
||||||
|
int32 documents;
|
||||||
|
int32 folders;
|
||||||
|
TrackerSettings().RecentCounts(&applications,&documents,&folders);
|
||||||
|
|
||||||
|
if (fWhich == 0)
|
||||||
|
fRecentsCount = documents;
|
||||||
|
else if (fWhich == 1)
|
||||||
|
fRecentsCount = applications;
|
||||||
|
else if (fWhich == 2)
|
||||||
|
fRecentsCount = folders;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RecentsMenu::DetachedFromWindow()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// BNavMenu::DetachedFromWindow sets the TypesList to NULL
|
||||||
|
//
|
||||||
|
BMenu::DetachedFromWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
RecentsMenu::StartBuildingItemList()
|
||||||
|
{
|
||||||
|
int32 count = CountItems()-1;
|
||||||
|
for (int32 index = count; index >= 0; index--) {
|
||||||
|
BMenuItem *item = ItemAt(index);
|
||||||
|
ASSERT(item);
|
||||||
|
|
||||||
|
RemoveItem(index);
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// !! note: don't call inherited from here
|
||||||
|
// the navref is not set for this menu
|
||||||
|
// but it still needs to be a draggable navmenu
|
||||||
|
// simply return true so that AddNextItem is called
|
||||||
|
//
|
||||||
|
// return BNavMenu::StartBuildingItemList();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
RecentsMenu::AddNextItem()
|
||||||
|
{
|
||||||
|
if (fRecentsCount > 0 && AddRecents(fRecentsCount))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
fItemIndex = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
RecentsMenu::AddRecents(int32 count)
|
||||||
|
{
|
||||||
|
if (fItemIndex == 0) {
|
||||||
|
fRecentList.MakeEmpty();
|
||||||
|
BRoster roster;
|
||||||
|
|
||||||
|
switch(fWhich) {
|
||||||
|
case 0:
|
||||||
|
roster.GetRecentDocuments(&fRecentList, count);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
roster.GetRecentApps(&fRecentList, count);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
roster.GetRecentFolders(&fRecentList, count);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
entry_ref ref;
|
||||||
|
if (fRecentList.FindRef("refs", fItemIndex++, &ref) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ref.name && strlen(ref.name) > 0) {
|
||||||
|
Model model(&ref, true);
|
||||||
|
ModelMenuItem *item = BNavMenu::NewModelItem(&model,
|
||||||
|
new BMessage(fMessage.what),
|
||||||
|
Target(), false, NULL, TypesList());
|
||||||
|
|
||||||
|
if (item) {
|
||||||
|
AddItem(item);
|
||||||
|
|
||||||
|
// return true so that we know to reenter this list
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// return false if we are done with this list
|
||||||
|
//
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RecentsMenu::DoneBuildingItemList()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// !! note: don't call inherited here
|
||||||
|
// the object list is not built
|
||||||
|
// and this list does not need to be sorted
|
||||||
|
// BNavMenu::DoneBuildingItemList();
|
||||||
|
//
|
||||||
|
|
||||||
|
if (CountItems() <= 0) {
|
||||||
|
BMenuItem *item = new BMenuItem("<No Recent Items>", 0);
|
||||||
|
item->SetEnabled(false);
|
||||||
|
AddItem(item);
|
||||||
|
} else
|
||||||
|
SetTargetForItems(Target());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RecentsMenu::ClearMenuBuildingState()
|
||||||
|
{
|
||||||
|
fMenuBuilt = false;
|
||||||
|
BNavMenu::ClearMenuBuildingState();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
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 __FAVORITES_MENU__
|
||||||
|
#define __FAVORITES_MENU__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "NavMenu.h"
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class EntryListBase;
|
||||||
|
|
||||||
|
#define kGoDirectory "Tracker/Go"
|
||||||
|
|
||||||
|
class FavoritesMenu : public BSlowMenu {
|
||||||
|
// FavoritesMenu is used in the FilePanel -
|
||||||
|
// displays recent files, recent folders and favorites items
|
||||||
|
public:
|
||||||
|
FavoritesMenu(const char *title, BMessage *openFolderMessage,
|
||||||
|
BMessage *openFileMessage, const BMessenger &,
|
||||||
|
bool isSavePanel);
|
||||||
|
virtual ~FavoritesMenu();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// override the necessary SlowMenu hooks
|
||||||
|
virtual bool StartBuildingItemList();
|
||||||
|
virtual bool AddNextItem();
|
||||||
|
virtual void DoneBuildingItemList();
|
||||||
|
virtual void ClearMenuBuildingState();
|
||||||
|
|
||||||
|
BMessage *fOpenFolderMessage;
|
||||||
|
BMessage *fOpenFileMessage;
|
||||||
|
BMessenger fTarget;
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
kStart,
|
||||||
|
kAddingFavorites,
|
||||||
|
kAddingFiles,
|
||||||
|
kAddingFolders,
|
||||||
|
kDone
|
||||||
|
};
|
||||||
|
|
||||||
|
State fState;
|
||||||
|
|
||||||
|
int32 fIndex;
|
||||||
|
int32 fSectionItemCount;
|
||||||
|
bool fAddedSeparatorForSection;
|
||||||
|
// keeps track wether a separator will be needed before the
|
||||||
|
// next inserted item
|
||||||
|
BMessage fItems;
|
||||||
|
|
||||||
|
EntryListBase *fContainer;
|
||||||
|
BObjectList<BMenuItem> *fItemList;
|
||||||
|
int32 fInitialItemCount;
|
||||||
|
std::vector<entry_ref> fUniqueRefCheck;
|
||||||
|
bool fIsSavePanel;
|
||||||
|
|
||||||
|
typedef BSlowMenu _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum recent_type {
|
||||||
|
kRecentDocuments = 0,
|
||||||
|
kRecentApplications = 1,
|
||||||
|
kRecentFolders = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
class RecentsMenu : public BNavMenu {
|
||||||
|
public:
|
||||||
|
RecentsMenu(const char *name,int32 which,uint32 what,BHandler *target);
|
||||||
|
|
||||||
|
void DetachedFromWindow();
|
||||||
|
|
||||||
|
int32 RecentsCount();
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool StartBuildingItemList();
|
||||||
|
virtual bool AddNextItem();
|
||||||
|
bool AddRecents(int32 count);
|
||||||
|
virtual void DoneBuildingItemList();
|
||||||
|
virtual void ClearMenuBuildingState();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 fWhich;
|
||||||
|
int32 fRecentsCount;
|
||||||
|
|
||||||
|
int32 fItemIndex;
|
||||||
|
BMessage fRecentList;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,347 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Implementation for the public FilePanel object.
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <FilePanel.h>
|
||||||
|
|
||||||
|
#include "AutoLock.h"
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "FilePanelPriv.h"
|
||||||
|
|
||||||
|
// prototypes for some private kernel calls that will some day be public
|
||||||
|
#if B_BEOS_VERSION_DANO
|
||||||
|
#define _IMPEXP_ROOT
|
||||||
|
#endif
|
||||||
|
extern "C" _IMPEXP_ROOT int _kset_fd_limit_(int num);
|
||||||
|
#if B_BEOS_VERSION_DANO
|
||||||
|
#undef _IMPEXP_ROOT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
run_open_panel()
|
||||||
|
{
|
||||||
|
(new TFilePanel())->Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
run_save_panel()
|
||||||
|
{
|
||||||
|
(new TFilePanel(B_SAVE_PANEL))->Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BFilePanel::BFilePanel(file_panel_mode mode, BMessenger *target,
|
||||||
|
const entry_ref *ref, uint32 nodeFlavors, bool multipleSelection,
|
||||||
|
BMessage *message, BRefFilter *filter, bool modal,
|
||||||
|
bool hideWhenDone)
|
||||||
|
{
|
||||||
|
// boost file descriptor limit so file panels in other apps don't have
|
||||||
|
// problems
|
||||||
|
_kset_fd_limit_ (512);
|
||||||
|
BEntry startDir(ref);
|
||||||
|
fWindow = new TFilePanel(mode, target, &startDir, nodeFlavors,
|
||||||
|
multipleSelection, message, filter, 0, B_DOCUMENT_WINDOW_LOOK,
|
||||||
|
modal ? B_MODAL_APP_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL,
|
||||||
|
hideWhenDone);
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->SetClientObject(this);
|
||||||
|
|
||||||
|
fWindow->SetIsFilePanel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
BFilePanel::~BFilePanel()
|
||||||
|
{
|
||||||
|
if (fWindow->Lock())
|
||||||
|
fWindow->Quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::Show()
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// if the window is already showing, don't jerk the workspaces around,
|
||||||
|
// just pull it to us
|
||||||
|
uint32 workspace = 1UL << (uint32)current_workspace();
|
||||||
|
uint32 windowWorkspaces = fWindow->Workspaces();
|
||||||
|
if (!(windowWorkspaces & workspace))
|
||||||
|
// window in a different workspace, reopen in current
|
||||||
|
fWindow->SetWorkspaces(workspace);
|
||||||
|
|
||||||
|
if (!IsShowing())
|
||||||
|
fWindow->Show();
|
||||||
|
|
||||||
|
fWindow->Activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::Hide()
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!fWindow->IsHidden())
|
||||||
|
fWindow->QuitRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BFilePanel::IsShowing() const
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !fWindow->IsHidden();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SendMessage(const BMessenger *messenger, BMessage *message)
|
||||||
|
{
|
||||||
|
messenger->SendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_panel_mode
|
||||||
|
BFilePanel::PanelMode() const
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return B_OPEN_PANEL;
|
||||||
|
|
||||||
|
if (static_cast<TFilePanel *>(fWindow)->IsSavePanel())
|
||||||
|
return B_SAVE_PANEL;
|
||||||
|
|
||||||
|
return B_OPEN_PANEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessenger
|
||||||
|
BFilePanel::Messenger() const
|
||||||
|
{
|
||||||
|
BMessenger target;
|
||||||
|
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return target;
|
||||||
|
|
||||||
|
return *static_cast<TFilePanel *>(fWindow)->Target();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetTarget(BMessenger target)
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->SetTarget(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetMessage(BMessage *message)
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->SetMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::Refresh()
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
BRefFilter *
|
||||||
|
BFilePanel::RefFilter() const
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return static_cast<TFilePanel *>(fWindow)->Filter();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetRefFilter(BRefFilter *filter)
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->SetRefFilter(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetButtonLabel(file_panel_button button, const char *text)
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->SetButtonLabel(button, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::GetPanelDirectory(entry_ref *ref) const
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*ref = *static_cast<TFilePanel *>(fWindow)->TargetModel()->EntryRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetSaveText(const char *text)
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->SetSaveText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetPanelDirectory(const entry_ref *ref)
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->SetTo(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetPanelDirectory(const char *path)
|
||||||
|
{
|
||||||
|
entry_ref ref;
|
||||||
|
status_t err = get_ref_for_path(path, &ref);
|
||||||
|
if (err < B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->SetTo(&ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetPanelDirectory(const BEntry *entry)
|
||||||
|
{
|
||||||
|
entry_ref ref;
|
||||||
|
|
||||||
|
if (entry && entry->GetRef(&ref) == B_OK)
|
||||||
|
SetPanelDirectory(&ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetPanelDirectory(const BDirectory *dir)
|
||||||
|
{
|
||||||
|
BEntry entry;
|
||||||
|
|
||||||
|
if (dir && (dir->GetEntry(&entry) == B_OK))
|
||||||
|
SetPanelDirectory(&entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
BWindow *
|
||||||
|
BFilePanel::Window() const
|
||||||
|
{
|
||||||
|
return fWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::Rewind()
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BFilePanel::GetNextSelectedRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
return static_cast<TFilePanel *>(fWindow)->GetNextEntryRef(ref);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SetHideWhenDone(bool on)
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return;
|
||||||
|
|
||||||
|
static_cast<TFilePanel *>(fWindow)->SetHideWhenDone(on);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BFilePanel::HidesWhenDone(void) const
|
||||||
|
{
|
||||||
|
AutoLock<BWindow> lock(fWindow);
|
||||||
|
if (!lock)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return static_cast<TFilePanel *>(fWindow)->HidesWhenDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::WasHidden()
|
||||||
|
{
|
||||||
|
// hook function
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BFilePanel::SelectionChanged()
|
||||||
|
{
|
||||||
|
// hook function
|
||||||
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,244 @@
|
|||||||
|
/*
|
||||||
|
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 _FILE_PANEL_PRIV_H
|
||||||
|
#define _FILE_PANEL_PRIV_H
|
||||||
|
|
||||||
|
#include <FilePanel.h>
|
||||||
|
|
||||||
|
#include "ContainerWindow.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
#include "TaskLoop.h"
|
||||||
|
|
||||||
|
class BTextControl;
|
||||||
|
class BFilePanel;
|
||||||
|
class BRefFilter;
|
||||||
|
class BMessenger;
|
||||||
|
class BMenuField;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BackgroundView;
|
||||||
|
class BDirMenu;
|
||||||
|
class AttributeStreamNode;
|
||||||
|
class BFilePanelPoseView;
|
||||||
|
class TFavoritesConfigWindow;
|
||||||
|
|
||||||
|
class TFilePanel : public BContainerWindow {
|
||||||
|
public:
|
||||||
|
TFilePanel(file_panel_mode = B_OPEN_PANEL,
|
||||||
|
BMessenger *target = NULL, const BEntry *startDirectory = NULL,
|
||||||
|
uint32 nodeFlavors = B_FILE_NODE | B_SYMLINK_NODE,
|
||||||
|
bool multipleSelection = true, BMessage * = NULL, BRefFilter * = NULL,
|
||||||
|
uint32 containerWindowFlags = 0,
|
||||||
|
window_look look = B_DOCUMENT_WINDOW_LOOK,
|
||||||
|
window_feel feel = B_NORMAL_WINDOW_FEEL,
|
||||||
|
bool hideWhenDone = true);
|
||||||
|
|
||||||
|
virtual ~TFilePanel();
|
||||||
|
|
||||||
|
BFilePanelPoseView *PoseView() const;
|
||||||
|
|
||||||
|
virtual bool QuitRequested();
|
||||||
|
virtual void MenusBeginning();
|
||||||
|
virtual void MenusEnded();
|
||||||
|
virtual void DispatchMessage(BMessage *message, BHandler *handler);
|
||||||
|
virtual void ShowContextMenu(BPoint, const entry_ref *, BView *);
|
||||||
|
|
||||||
|
void SetClientObject(BFilePanel *);
|
||||||
|
void SetRefFilter(BRefFilter *);
|
||||||
|
void SetSaveText(const char *text);
|
||||||
|
void SetButtonLabel(file_panel_button, const char *text);
|
||||||
|
void SetTo(const entry_ref *ref);
|
||||||
|
virtual void SelectionChanged();
|
||||||
|
void HandleOpenButton();
|
||||||
|
void HandleSaveButton();
|
||||||
|
void Rewind();
|
||||||
|
bool IsSavePanel() const;
|
||||||
|
void Refresh();
|
||||||
|
const BMessenger *Target() const;
|
||||||
|
BRefFilter *Filter() const;
|
||||||
|
|
||||||
|
void SetTarget(BMessenger);
|
||||||
|
void SetMessage(BMessage *message);
|
||||||
|
|
||||||
|
virtual status_t GetNextEntryRef(entry_ref *);
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
void SetHideWhenDone(bool);
|
||||||
|
bool HidesWhenDone(void);
|
||||||
|
|
||||||
|
bool TrackingMenu() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BPoseView *NewPoseView(Model *model, BRect rect, uint32 viewMode);
|
||||||
|
virtual void Init(const BMessage *message = NULL);
|
||||||
|
virtual void SaveState(bool hide = true);
|
||||||
|
virtual void SaveState(BMessage &) const;
|
||||||
|
virtual void RestoreState();
|
||||||
|
virtual void RestoreWindowState(AttributeStreamNode *);
|
||||||
|
virtual void RestoreWindowState(const BMessage &);
|
||||||
|
virtual void RestoreState(const BMessage &);
|
||||||
|
|
||||||
|
virtual void AddFileContextMenus(BMenu *);
|
||||||
|
virtual void AddWindowContextMenus(BMenu *);
|
||||||
|
virtual void AddDropContextMenus(BMenu *);
|
||||||
|
virtual void AddVolumeContextMenus(BMenu *);
|
||||||
|
|
||||||
|
virtual void SetupNavigationMenu(const entry_ref *, BMenu *);
|
||||||
|
virtual void OpenDirectory();
|
||||||
|
virtual void OpenParent();
|
||||||
|
virtual void WindowActivated(bool state);
|
||||||
|
|
||||||
|
static filter_result FSFilter(BMessage *, BHandler **, BMessageFilter *);
|
||||||
|
static filter_result MessageDropFilter(BMessage *, BHandler **, BMessageFilter *);
|
||||||
|
int32 ShowCenteredAlert(const char *text, const char *button1, const char *button2 = NULL,
|
||||||
|
const char *button3 = NULL);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool SwitchDirToDesktopIfNeeded(entry_ref &ref);
|
||||||
|
bool CanOpenParent() const;
|
||||||
|
void SwitchDirMenuTo(const entry_ref *ref);
|
||||||
|
void AdjustButton();
|
||||||
|
bool SelectChildInParent(const entry_ref *parent, const node_ref *child);
|
||||||
|
void OpenSelectionCommon(BMessage *);
|
||||||
|
|
||||||
|
|
||||||
|
bool fIsSavePanel;
|
||||||
|
uint32 fNodeFlavors;
|
||||||
|
BackgroundView *fBackView;
|
||||||
|
BDirMenu *fDirMenu;
|
||||||
|
BMenuField *fDirMenuField;
|
||||||
|
BTextControl *fTextControl;
|
||||||
|
BMessenger fTarget;
|
||||||
|
BFilePanel *fClientObject;
|
||||||
|
int32 fSelectionIterator;
|
||||||
|
BMessage *fMessage;
|
||||||
|
BString fButtonText;
|
||||||
|
bool fHideWhenDone;
|
||||||
|
bool fIsTrackingMenu;
|
||||||
|
TFavoritesConfigWindow *fConfigWindow;
|
||||||
|
|
||||||
|
typedef BContainerWindow _inherited;
|
||||||
|
|
||||||
|
friend class BackgroundView;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BFilePanelPoseView : public BPoseView {
|
||||||
|
public:
|
||||||
|
BFilePanelPoseView(Model *, BRect, uint32 resizeMask = B_FOLLOW_ALL);
|
||||||
|
|
||||||
|
virtual bool IsFilePanel() const;
|
||||||
|
virtual bool FSNotification(const BMessage *);
|
||||||
|
|
||||||
|
void SetIsDesktop(bool);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// don't do any volume watching and memtamime watching in file panels for now
|
||||||
|
virtual void StartWatching();
|
||||||
|
virtual void StopWatching();
|
||||||
|
|
||||||
|
virtual void RestoreState(AttributeStreamNode *);
|
||||||
|
virtual void RestoreState(const BMessage &);
|
||||||
|
virtual void SavePoseLocations(BRect * = NULL);
|
||||||
|
|
||||||
|
virtual EntryListBase *InitDirentIterator(const entry_ref *);
|
||||||
|
virtual bool ShouldShowPose(const Model *, const PoseInfo *);
|
||||||
|
virtual bool IsDesktopView() const;
|
||||||
|
|
||||||
|
void ShowVolumes(bool visible, bool showShared);
|
||||||
|
|
||||||
|
void AdaptToVolumeChange(BMessage *);
|
||||||
|
void AdaptToDesktopIntegrationChange(BMessage *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fIsDesktop;
|
||||||
|
// this flags makes the distinction between the Desktop as the Root of
|
||||||
|
// the world and "/boot/home/Desktop" to which we might have navigated
|
||||||
|
// from the home dir
|
||||||
|
|
||||||
|
typedef BPoseView _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
// inlines follow
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BFilePanelPoseView::IsFilePanel() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
TFilePanel::IsSavePanel() const
|
||||||
|
{
|
||||||
|
return fIsSavePanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const BMessenger *
|
||||||
|
TFilePanel::Target() const
|
||||||
|
{
|
||||||
|
return &fTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
TFilePanel::Refresh()
|
||||||
|
{
|
||||||
|
fPoseView->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
TFilePanel::HidesWhenDone(void)
|
||||||
|
{
|
||||||
|
return fHideWhenDone;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
TFilePanel::SetHideWhenDone(bool on)
|
||||||
|
{
|
||||||
|
fHideWhenDone = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
TFilePanel::TrackingMenu() const
|
||||||
|
{
|
||||||
|
return fIsTrackingMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,347 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Beep.h>
|
||||||
|
|
||||||
|
#include "FilePermissionsView.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
const uint32 kPermissionsChanged = 'prch';
|
||||||
|
const uint32 kNewOwnerEntered = 'nwow';
|
||||||
|
const uint32 kNewGroupEntered = 'nwgr';
|
||||||
|
|
||||||
|
|
||||||
|
FilePermissionsView::FilePermissionsView(BRect rect, Model *model)
|
||||||
|
: BView(rect, "FilePermissionsView", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW),
|
||||||
|
fModel(model)
|
||||||
|
{
|
||||||
|
// Constants for the column labels: "User", "Group" and "Other".
|
||||||
|
const float kColumnLabelMiddle = 77, kColumnLabelTop = 6, kColumnLabelSpacing = 37,
|
||||||
|
kColumnLabelBottom = 20, kColumnLabelWidth = 35, kAttribFontHeight = 10;
|
||||||
|
|
||||||
|
BStringView *strView;
|
||||||
|
|
||||||
|
strView = new BStringView(BRect(kColumnLabelMiddle - kColumnLabelWidth / 2,
|
||||||
|
kColumnLabelTop, kColumnLabelMiddle + kColumnLabelWidth / 2, kColumnLabelBottom),
|
||||||
|
"", "Owner");
|
||||||
|
AddChild(strView);
|
||||||
|
strView->SetAlignment(B_ALIGN_CENTER);
|
||||||
|
strView->SetFontSize(kAttribFontHeight);
|
||||||
|
|
||||||
|
strView = new BStringView(BRect(kColumnLabelMiddle - kColumnLabelWidth / 2
|
||||||
|
+ kColumnLabelSpacing, kColumnLabelTop, kColumnLabelMiddle + kColumnLabelWidth / 2
|
||||||
|
+ kColumnLabelSpacing, kColumnLabelBottom), "", "Group");
|
||||||
|
AddChild(strView);
|
||||||
|
strView->SetAlignment(B_ALIGN_CENTER);
|
||||||
|
strView->SetFontSize(kAttribFontHeight);
|
||||||
|
|
||||||
|
strView = new BStringView(BRect(kColumnLabelMiddle - kColumnLabelWidth / 2
|
||||||
|
+ 2 * kColumnLabelSpacing, kColumnLabelTop, kColumnLabelMiddle + kColumnLabelWidth / 2
|
||||||
|
+ 2 * kColumnLabelSpacing, kColumnLabelBottom), "", "Other");
|
||||||
|
AddChild(strView);
|
||||||
|
strView->SetAlignment(B_ALIGN_CENTER);
|
||||||
|
strView->SetFontSize(kAttribFontHeight);
|
||||||
|
|
||||||
|
// Constants for the row labels: "Read", "Write" and "Execute".
|
||||||
|
const float kRowLabelLeft = 10, kRowLabelTop = kColumnLabelTop + 15,
|
||||||
|
kRowLabelVerticalSpacing = 18, kRowLabelRight = kColumnLabelMiddle
|
||||||
|
- kColumnLabelWidth / 2 - 5, kRowLabelHeight = 14;
|
||||||
|
|
||||||
|
strView = new BStringView(BRect(kRowLabelLeft, kRowLabelTop, kRowLabelRight,
|
||||||
|
kRowLabelTop + kRowLabelHeight), "", "Read");
|
||||||
|
AddChild(strView);
|
||||||
|
strView->SetAlignment(B_ALIGN_RIGHT);
|
||||||
|
strView->SetFontSize(kAttribFontHeight);
|
||||||
|
|
||||||
|
strView = new BStringView(BRect(kRowLabelLeft, kRowLabelTop
|
||||||
|
+ kRowLabelVerticalSpacing, kRowLabelRight, kRowLabelTop
|
||||||
|
+ kRowLabelVerticalSpacing + kRowLabelHeight), "", "Write");
|
||||||
|
AddChild(strView);
|
||||||
|
strView->SetAlignment(B_ALIGN_RIGHT);
|
||||||
|
strView->SetFontSize(kAttribFontHeight);
|
||||||
|
|
||||||
|
strView = new BStringView(BRect(kRowLabelLeft, kRowLabelTop
|
||||||
|
+ 2 * kRowLabelVerticalSpacing, kRowLabelRight, kRowLabelTop
|
||||||
|
+ 2 * kRowLabelVerticalSpacing + kRowLabelHeight), "", "Execute");
|
||||||
|
AddChild(strView);
|
||||||
|
strView->SetAlignment(B_ALIGN_RIGHT);
|
||||||
|
strView->SetFontSize(kAttribFontHeight);
|
||||||
|
|
||||||
|
// Constants for the 3x3 check box array.
|
||||||
|
const float kLeftMargin = kRowLabelRight + 15, kTopMargin = kRowLabelTop - 2,
|
||||||
|
kHorizontalSpacing = kColumnLabelSpacing, kVerticalSpacing = kRowLabelVerticalSpacing,
|
||||||
|
kCheckBoxWidth = 18, kCheckBoxHeight = 18;
|
||||||
|
|
||||||
|
FocusCheckBox **checkBoxArray[3][3] = {
|
||||||
|
{ &fReadUserCheckBox, &fReadGroupCheckBox, &fReadOtherCheckBox },
|
||||||
|
{ &fWriteUserCheckBox, &fWriteGroupCheckBox, &fWriteOtherCheckBox },
|
||||||
|
{ &fExecuteUserCheckBox, &fExecuteGroupCheckBox, &fExecuteOtherCheckBox }};
|
||||||
|
|
||||||
|
for (int32 x = 0; x < 3; x++) {
|
||||||
|
for (int32 y = 0; y < 3; y++) {
|
||||||
|
*checkBoxArray[y][x] =
|
||||||
|
new FocusCheckBox(BRect(kLeftMargin + kHorizontalSpacing * x,
|
||||||
|
kTopMargin + kVerticalSpacing * y,
|
||||||
|
kLeftMargin + kHorizontalSpacing * x + kCheckBoxWidth,
|
||||||
|
kTopMargin + kVerticalSpacing * y + kCheckBoxHeight),
|
||||||
|
"", "", new BMessage(kPermissionsChanged));
|
||||||
|
AddChild(*checkBoxArray[y][x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const float kTextControlLeft = 170, kTextControlRight = 270,
|
||||||
|
kTextControlTop = kColumnLabelTop, kTextControlHeight = 14, kTextControlSpacing = 16;
|
||||||
|
|
||||||
|
strView = new BStringView(BRect(kTextControlLeft, kTextControlTop, kTextControlRight,
|
||||||
|
kTextControlTop + kTextControlHeight), "", "Owner");
|
||||||
|
strView->SetAlignment(B_ALIGN_CENTER);
|
||||||
|
strView->SetFontSize(kAttribFontHeight);
|
||||||
|
AddChild(strView);
|
||||||
|
|
||||||
|
fOwnerTextControl = new BTextControl(BRect(kTextControlLeft, kTextControlTop - 2
|
||||||
|
+ kTextControlSpacing, kTextControlRight, kTextControlTop + kTextControlHeight - 2
|
||||||
|
+ kTextControlSpacing), "", "", "", new BMessage(kNewOwnerEntered));
|
||||||
|
fOwnerTextControl->SetDivider(0);
|
||||||
|
AddChild(fOwnerTextControl);
|
||||||
|
|
||||||
|
strView = new BStringView(BRect(kTextControlLeft, kTextControlTop + 5
|
||||||
|
+ 2 * kTextControlSpacing, kTextControlRight, kTextControlTop + 2
|
||||||
|
+ 2 * kTextControlSpacing + kTextControlHeight), "", "Group");
|
||||||
|
strView->SetAlignment(B_ALIGN_CENTER);
|
||||||
|
strView->SetFontSize(kAttribFontHeight);
|
||||||
|
AddChild(strView);
|
||||||
|
|
||||||
|
fGroupTextControl = new BTextControl(BRect(kTextControlLeft, kTextControlTop
|
||||||
|
+ 3 * kTextControlSpacing, kTextControlRight, kTextControlTop
|
||||||
|
+ 3 * kTextControlSpacing + kTextControlHeight), "", "", "",
|
||||||
|
new BMessage(kNewGroupEntered));
|
||||||
|
fGroupTextControl->SetDivider(0);
|
||||||
|
AddChild(fGroupTextControl);
|
||||||
|
|
||||||
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
|
ModelChanged(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FilePermissionsView::ModelChanged(Model *model)
|
||||||
|
{
|
||||||
|
fModel = model;
|
||||||
|
|
||||||
|
bool hideCheckBoxes = false;
|
||||||
|
uid_t nodeOwner = 0;
|
||||||
|
gid_t nodeGroup = 0;
|
||||||
|
mode_t perms = 0;
|
||||||
|
|
||||||
|
if (fModel != NULL) {
|
||||||
|
BNode node(fModel->EntryRef());
|
||||||
|
|
||||||
|
if (node.InitCheck() == B_OK) {
|
||||||
|
if (fReadUserCheckBox->IsHidden()) {
|
||||||
|
fReadUserCheckBox->Show();
|
||||||
|
fReadGroupCheckBox->Show();
|
||||||
|
fReadOtherCheckBox->Show();
|
||||||
|
fWriteUserCheckBox->Show();
|
||||||
|
fWriteGroupCheckBox->Show();
|
||||||
|
fWriteOtherCheckBox->Show();
|
||||||
|
fExecuteUserCheckBox->Show();
|
||||||
|
fExecuteGroupCheckBox->Show();
|
||||||
|
fExecuteOtherCheckBox->Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.GetPermissions(&perms) == B_OK) {
|
||||||
|
fReadUserCheckBox->SetValue((int32)(perms & S_IRUSR));
|
||||||
|
fReadGroupCheckBox->SetValue((int32)(perms & S_IRGRP));
|
||||||
|
fReadOtherCheckBox->SetValue((int32)(perms & S_IROTH));
|
||||||
|
fWriteUserCheckBox->SetValue((int32)(perms & S_IWUSR));
|
||||||
|
fWriteGroupCheckBox->SetValue((int32)(perms & S_IWGRP));
|
||||||
|
fWriteOtherCheckBox->SetValue((int32)(perms & S_IWOTH));
|
||||||
|
fExecuteUserCheckBox->SetValue((int32)(perms & S_IXUSR));
|
||||||
|
fExecuteGroupCheckBox->SetValue((int32)(perms & S_IXGRP));
|
||||||
|
fExecuteOtherCheckBox->SetValue((int32)(perms & S_IXOTH));
|
||||||
|
} else
|
||||||
|
hideCheckBoxes = true;
|
||||||
|
|
||||||
|
if (node.GetOwner(&nodeOwner) == B_OK) {
|
||||||
|
BString user;
|
||||||
|
if (nodeOwner == 0)
|
||||||
|
if (getenv("USER") != NULL)
|
||||||
|
user << getenv("USER");
|
||||||
|
else
|
||||||
|
user << "root";
|
||||||
|
else
|
||||||
|
user << nodeOwner;
|
||||||
|
fOwnerTextControl->SetText(user.String());
|
||||||
|
} else
|
||||||
|
fOwnerTextControl->SetText("Unknown");
|
||||||
|
|
||||||
|
if (node.GetGroup(&nodeGroup) == B_OK) {
|
||||||
|
BString group;
|
||||||
|
if (nodeGroup == 0)
|
||||||
|
if (getenv("GROUP") != NULL)
|
||||||
|
group << getenv("GROUP");
|
||||||
|
else
|
||||||
|
group << "0";
|
||||||
|
else
|
||||||
|
group << nodeGroup;
|
||||||
|
fGroupTextControl->SetText(group.String());
|
||||||
|
} else
|
||||||
|
fGroupTextControl->SetText("Unknown");
|
||||||
|
|
||||||
|
// Unless we're root, only allow the owner to transfer the ownership,
|
||||||
|
// i.e. disable text controls if uid:s doesn't match:
|
||||||
|
thread_id thisThread = find_thread(NULL);
|
||||||
|
thread_info threadInfo;
|
||||||
|
get_thread_info(thisThread, &threadInfo);
|
||||||
|
team_info teamInfo;
|
||||||
|
get_team_info(threadInfo.team, &teamInfo);
|
||||||
|
if (teamInfo.uid != 0 && nodeOwner != teamInfo.uid) {
|
||||||
|
fOwnerTextControl->SetEnabled(false);
|
||||||
|
fGroupTextControl->SetEnabled(false);
|
||||||
|
} else {
|
||||||
|
fOwnerTextControl->SetEnabled(true);
|
||||||
|
fGroupTextControl->SetEnabled(true);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
hideCheckBoxes = true;
|
||||||
|
} else
|
||||||
|
hideCheckBoxes = true;
|
||||||
|
|
||||||
|
if (hideCheckBoxes) {
|
||||||
|
fReadUserCheckBox->Hide();
|
||||||
|
fReadGroupCheckBox->Hide();
|
||||||
|
fReadOtherCheckBox->Hide();
|
||||||
|
fWriteUserCheckBox->Hide();
|
||||||
|
fWriteGroupCheckBox->Hide();
|
||||||
|
fWriteOtherCheckBox->Hide();
|
||||||
|
fExecuteUserCheckBox->Hide();
|
||||||
|
fExecuteGroupCheckBox->Hide();
|
||||||
|
fExecuteOtherCheckBox->Hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FilePermissionsView::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
switch(message->what) {
|
||||||
|
case kPermissionsChanged:
|
||||||
|
if (fModel != NULL) {
|
||||||
|
mode_t newPermissions = 0;
|
||||||
|
newPermissions = (mode_t)((fReadUserCheckBox->Value() ? S_IRUSR : 0)
|
||||||
|
| (fReadGroupCheckBox->Value() ? S_IRGRP : 0)
|
||||||
|
| (fReadOtherCheckBox->Value() ? S_IROTH : 0)
|
||||||
|
|
||||||
|
| (fWriteUserCheckBox->Value() ? S_IWUSR : 0)
|
||||||
|
| (fWriteGroupCheckBox->Value() ? S_IWGRP : 0)
|
||||||
|
| (fWriteOtherCheckBox->Value() ? S_IWOTH : 0)
|
||||||
|
|
||||||
|
| (fExecuteUserCheckBox->Value() ? S_IXUSR : 0)
|
||||||
|
| (fExecuteGroupCheckBox->Value() ? S_IXGRP :0)
|
||||||
|
| (fExecuteOtherCheckBox->Value() ? S_IXOTH : 0));
|
||||||
|
|
||||||
|
BNode node(fModel->EntryRef());
|
||||||
|
|
||||||
|
if (node.InitCheck() == B_OK)
|
||||||
|
node.SetPermissions(newPermissions);
|
||||||
|
else {
|
||||||
|
ModelChanged(fModel);
|
||||||
|
beep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kNewOwnerEntered:
|
||||||
|
if (fModel != NULL) {
|
||||||
|
uid_t owner;
|
||||||
|
if (sscanf(fOwnerTextControl->Text(), "%d", &owner) == 1) {
|
||||||
|
BNode node(fModel->EntryRef());
|
||||||
|
if (node.InitCheck() == B_OK)
|
||||||
|
node.SetOwner(owner);
|
||||||
|
else {
|
||||||
|
ModelChanged(fModel);
|
||||||
|
beep();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ModelChanged(fModel);
|
||||||
|
beep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kNewGroupEntered:
|
||||||
|
if (fModel != NULL) {
|
||||||
|
gid_t group;
|
||||||
|
if (sscanf(fGroupTextControl->Text(), "%d", &group) == 1) {
|
||||||
|
BNode node(fModel->EntryRef());
|
||||||
|
if (node.InitCheck() == B_OK)
|
||||||
|
node.SetGroup(group);
|
||||||
|
else {
|
||||||
|
ModelChanged(fModel);
|
||||||
|
beep();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ModelChanged(fModel);
|
||||||
|
beep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_inherited::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FilePermissionsView::AttachedToWindow()
|
||||||
|
{
|
||||||
|
fReadUserCheckBox->SetTarget(this);
|
||||||
|
fReadGroupCheckBox->SetTarget(this);
|
||||||
|
fReadOtherCheckBox->SetTarget(this);
|
||||||
|
fWriteUserCheckBox->SetTarget(this);
|
||||||
|
fWriteGroupCheckBox->SetTarget(this);
|
||||||
|
fWriteOtherCheckBox->SetTarget(this);
|
||||||
|
fExecuteUserCheckBox->SetTarget(this);
|
||||||
|
fExecuteGroupCheckBox->SetTarget(this);
|
||||||
|
fExecuteOtherCheckBox->SetTarget(this);
|
||||||
|
|
||||||
|
fOwnerTextControl->SetTarget(this);
|
||||||
|
fGroupTextControl->SetTarget(this);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
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 FILE_PERMISSIONS_VIEW_H
|
||||||
|
#define FILE_PERMISSIONS_VIEW_H
|
||||||
|
|
||||||
|
#include <CheckBox.h>
|
||||||
|
#include <TextControl.h>
|
||||||
|
|
||||||
|
#include "Model.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class FocusCheckBox : public BCheckBox {
|
||||||
|
public:
|
||||||
|
FocusCheckBox(BRect rect, const char *name, const char *label,
|
||||||
|
BMessage *message)
|
||||||
|
: BCheckBox(rect, name, label, message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Draw(BRect rect)
|
||||||
|
{
|
||||||
|
BCheckBox::Draw(rect);
|
||||||
|
|
||||||
|
if (IsFocus()) {
|
||||||
|
SetHighColor(0, 0, 255);
|
||||||
|
StrokeRect(BRect(2 , 4, 12, 14));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FilePermissionsView : public BView {
|
||||||
|
public:
|
||||||
|
FilePermissionsView(BRect, Model *);
|
||||||
|
|
||||||
|
void ModelChanged(Model *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Model *fModel;
|
||||||
|
|
||||||
|
FocusCheckBox *fReadUserCheckBox;
|
||||||
|
FocusCheckBox *fReadGroupCheckBox;
|
||||||
|
FocusCheckBox *fReadOtherCheckBox;
|
||||||
|
|
||||||
|
FocusCheckBox *fWriteUserCheckBox;
|
||||||
|
FocusCheckBox *fWriteGroupCheckBox;
|
||||||
|
FocusCheckBox *fWriteOtherCheckBox;
|
||||||
|
|
||||||
|
FocusCheckBox *fExecuteUserCheckBox;
|
||||||
|
FocusCheckBox *fExecuteGroupCheckBox;
|
||||||
|
FocusCheckBox *fExecuteOtherCheckBox;
|
||||||
|
|
||||||
|
BTextControl *fOwnerTextControl;
|
||||||
|
BTextControl *fGroupTextControl;
|
||||||
|
|
||||||
|
typedef BView _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif /* FILE_PERMISSIONS_VIEW_H */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,375 @@
|
|||||||
|
/*
|
||||||
|
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 _FIND_PANEL_H
|
||||||
|
#define _FIND_PANEL_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <Window.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "DialogPane.h"
|
||||||
|
#include "ObjectList.h"
|
||||||
|
#include "MimeTypeList.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
#include "NodeWalker.h"
|
||||||
|
|
||||||
|
class BFilePanel;
|
||||||
|
class BQuery;
|
||||||
|
class BBox;
|
||||||
|
class BTextControl;
|
||||||
|
class BCheckBox;
|
||||||
|
class BMenuField;
|
||||||
|
class BFile;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class FindPanel;
|
||||||
|
class Model;
|
||||||
|
class DraggableIcon;
|
||||||
|
class TAttrView;
|
||||||
|
|
||||||
|
const uint32 kVolumeItem = 'Fvol';
|
||||||
|
const uint32 kAttributeItemMain = 'Fatr';
|
||||||
|
const uint32 kByNameItem = 'Fbyn';
|
||||||
|
const uint32 kByAttributeItem = 'Fbya';
|
||||||
|
const uint32 kByForumlaItem = 'Fbyq';
|
||||||
|
const uint32 kAddItem = 'Fadd';
|
||||||
|
const uint32 kRemoveItem = 'Frem';
|
||||||
|
|
||||||
|
#if !B_BEOS_VERSION_DANO
|
||||||
|
_IMPEXP_TRACKER
|
||||||
|
#endif
|
||||||
|
BMenu *TrackerBuildRecentFindItemsMenu(const char *);
|
||||||
|
|
||||||
|
struct MoreOptionsStruct {
|
||||||
|
bool showMoreOptions;
|
||||||
|
bool searchTrash;
|
||||||
|
int32 reserved1;
|
||||||
|
bool temporary;
|
||||||
|
bool reserved9;
|
||||||
|
bool reserved10;
|
||||||
|
bool reserved11;
|
||||||
|
int32 reserved3;
|
||||||
|
int32 reserved4;
|
||||||
|
int32 reserved5;
|
||||||
|
int32 reserved6;
|
||||||
|
int32 reserved7;
|
||||||
|
int32 reserved8;
|
||||||
|
// reserve a bunch of fields so that we can add stuff later but not
|
||||||
|
// make old queries incompatible. Reserved fields are set to 0 when
|
||||||
|
// saved
|
||||||
|
|
||||||
|
MoreOptionsStruct()
|
||||||
|
: showMoreOptions(false),
|
||||||
|
searchTrash(false),
|
||||||
|
reserved1(0),
|
||||||
|
temporary(true),
|
||||||
|
reserved9(false),
|
||||||
|
reserved10(false),
|
||||||
|
reserved11(false),
|
||||||
|
reserved3(0),
|
||||||
|
reserved4(0),
|
||||||
|
reserved5(0),
|
||||||
|
reserved6(0),
|
||||||
|
reserved7(0),
|
||||||
|
reserved8(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static void EndianSwap(void *castToThis);
|
||||||
|
|
||||||
|
static void SetQueryTemporary(BNode *, bool on);
|
||||||
|
static bool QueryTemporary(const BNode *);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FindWindow : public BWindow {
|
||||||
|
public:
|
||||||
|
FindWindow(const entry_ref * = NULL, bool editIfTemplateOnly = false);
|
||||||
|
virtual ~FindWindow();
|
||||||
|
|
||||||
|
FindPanel *BackgroundView() const
|
||||||
|
{ return fBackground; }
|
||||||
|
|
||||||
|
BNode *QueryNode() const
|
||||||
|
{ return fFile; }
|
||||||
|
|
||||||
|
const char *QueryName() const;
|
||||||
|
// reads in the query name from either a saved name in a template or
|
||||||
|
// form a saved query name
|
||||||
|
|
||||||
|
static bool IsQueryTemplate(BNode *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static BFile *TryOpening(const entry_ref *);
|
||||||
|
static void GetDefaultQuery(BEntry &entry);
|
||||||
|
// when opening an empty panel, use the default query to set the panel up
|
||||||
|
void SaveQueryAttributes(BNode *, bool templateQuery);
|
||||||
|
|
||||||
|
void Find();
|
||||||
|
// retrieve the results
|
||||||
|
void Save();
|
||||||
|
// save the contents of the find window into the query file
|
||||||
|
|
||||||
|
void SwitchToTemplate(const entry_ref *);
|
||||||
|
bool FindSaveCommon(bool find);
|
||||||
|
|
||||||
|
status_t SaveQueryAsAttributes(BNode *, BEntry *, bool queryTemplate,
|
||||||
|
const BMessage *oldAttributes = 0, const BPoint *oldLocation = 0);
|
||||||
|
|
||||||
|
void GetDefaultName(BString &);
|
||||||
|
void GetPredicateString(BString &, bool &dynamicDate);
|
||||||
|
// dynamic date is a date such as 'today'
|
||||||
|
|
||||||
|
BFile *fFile;
|
||||||
|
entry_ref fRef;
|
||||||
|
bool fFromTemplate;
|
||||||
|
bool fEditTemplateOnly;
|
||||||
|
FindPanel *fBackground;
|
||||||
|
mutable BString fQueryNameFromTemplate;
|
||||||
|
BFilePanel *fSaveAsTemplatePanel;
|
||||||
|
|
||||||
|
typedef BWindow _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FindPanel : public BView {
|
||||||
|
public:
|
||||||
|
FindPanel(BRect, BFile *, FindWindow *parent, bool fromTemplate,
|
||||||
|
bool editTemplateOnly);
|
||||||
|
virtual ~FindPanel();
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void MessageReceived(BMessage*);
|
||||||
|
|
||||||
|
void BuildAttrQuery(BQuery *, bool &dynamicDate) const;
|
||||||
|
BPopUpMenu *MimeTypeMenu() const
|
||||||
|
{ return fMimeTypeMenu; }
|
||||||
|
BMenuItem *CurrentMimeType(const char **type = NULL) const;
|
||||||
|
status_t SetCurrentMimeType(BMenuItem *item);
|
||||||
|
status_t SetCurrentMimeType(const char *label);
|
||||||
|
|
||||||
|
BPopUpMenu *VolMenu() const
|
||||||
|
{ return fVolMenu; }
|
||||||
|
uint32 Mode() const
|
||||||
|
{ return fMode; }
|
||||||
|
|
||||||
|
static BRect InitialViewSize(const BNode *);
|
||||||
|
// used when showing window, does not account for more options,
|
||||||
|
// those if used will force a resize later
|
||||||
|
|
||||||
|
static uint32 InitialMode(const BNode *entry);
|
||||||
|
void SaveWindowState(BNode *, bool editTemplate);
|
||||||
|
|
||||||
|
void SwitchToTemplate(const BNode *);
|
||||||
|
|
||||||
|
void GetByAttrPredicate(BQuery *, bool &dynamicDate) const;
|
||||||
|
// build up a query from by-attribute items
|
||||||
|
void GetByNamePredicate(BQuery *) const;
|
||||||
|
// build up a simple query from the name we are searching for
|
||||||
|
|
||||||
|
void GetDefaultName(BString &) const;
|
||||||
|
const char *UserSpecifiedName() const;
|
||||||
|
// name filled out in the query name text field
|
||||||
|
|
||||||
|
static void AddRecentQueries(BMenu *, bool addSaveAsItem,
|
||||||
|
const BMessenger *target, uint32 what);
|
||||||
|
// populate the recent query menu with query templates and recent
|
||||||
|
// queries
|
||||||
|
|
||||||
|
private:
|
||||||
|
static float ViewHeightForMode(uint32 mode, bool moreOptions);
|
||||||
|
// accouts for moreOptions
|
||||||
|
// if in attributeView, only returns valid result if one attr only
|
||||||
|
static float BoxHeightForMode(uint32 mode, bool moreOptions);
|
||||||
|
|
||||||
|
void AddMimeTypesToMenu();
|
||||||
|
// populates the type menu
|
||||||
|
static bool AddOneMimeTypeToMenu(const ShortMimeInfo *, void *);
|
||||||
|
|
||||||
|
void AddVolumes(BMenu *);
|
||||||
|
// populates the volume menu
|
||||||
|
void ShowVolumeMenuLabel();
|
||||||
|
|
||||||
|
void AddAttrView();
|
||||||
|
// add one more attribute item to the attr view
|
||||||
|
void RemoveAttrView();
|
||||||
|
// remove the last attribute item
|
||||||
|
void AddFirstAttr();
|
||||||
|
|
||||||
|
// panel building/restoring calls
|
||||||
|
void RestoreWindowState(const BNode *);
|
||||||
|
void RestoreMimeTypeMenuSelection(const BNode *);
|
||||||
|
void AddByAttributeItems(const BNode *);
|
||||||
|
void ResizeAttributeBox(const BNode *);
|
||||||
|
void RemoveByAttributeItems();
|
||||||
|
void RemoveAttrViewItems();
|
||||||
|
void ShowOrHideMimeTypeMenu();
|
||||||
|
// MimeTypeWindow is only shown in kByNameItem and kByAttributeItem modes
|
||||||
|
|
||||||
|
void ShowOrHideMoreOptions(bool show);
|
||||||
|
// fMode gets set by this and the call relies on it being up-to-date
|
||||||
|
static int32 InitialAttrCount(const BNode *);
|
||||||
|
void FillCurrentQueryName(BTextControl *, FindWindow *);
|
||||||
|
void AddByNameOrFormulaItems();
|
||||||
|
void AddOneAttributeItem(BBox *box, BRect);
|
||||||
|
void SetUpAddRemoveButtons(BBox *box);
|
||||||
|
|
||||||
|
void SwitchMode(uint32);
|
||||||
|
// go from search by name to search by attribute, etc.
|
||||||
|
|
||||||
|
void PushMimeType(BQuery *query) const;
|
||||||
|
|
||||||
|
void SaveAsQueryOrTemplate(const entry_ref *, const char *, bool queryTemplate);
|
||||||
|
|
||||||
|
uint32 fMode;
|
||||||
|
BObjectList<TAttrView> fAttrViewList;
|
||||||
|
BPopUpMenu *fMimeTypeMenu;
|
||||||
|
BMenuField *fMimeTypeField;
|
||||||
|
BPopUpMenu *fVolMenu;
|
||||||
|
BPopUpMenu *fSearchModeMenu;
|
||||||
|
BPopUpMenu *fRecentQueries;
|
||||||
|
DialogPane *fMoreOptionsPane;
|
||||||
|
BTextControl *fQueryName;
|
||||||
|
BString fInitialQueryName;
|
||||||
|
|
||||||
|
BCheckBox *fTemporaryCheck;
|
||||||
|
BCheckBox *fSearchTrashCheck;
|
||||||
|
|
||||||
|
PaneSwitch *fLatch;
|
||||||
|
DraggableIcon *fDraggableIcon;
|
||||||
|
|
||||||
|
typedef BView _inherited;
|
||||||
|
|
||||||
|
friend class RecentQueriesPopUp;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TAttrView : public BView {
|
||||||
|
// a single attribute item - the search by attribute view
|
||||||
|
// can add several of these
|
||||||
|
public:
|
||||||
|
TAttrView(BRect, int32 index);
|
||||||
|
~TAttrView();
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
|
void RestoreState(const BMessage &, int32);
|
||||||
|
void SaveState(BMessage *, int32);
|
||||||
|
|
||||||
|
virtual void Draw(BRect);
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
void AddLogicMenu(bool selectAnd = true);
|
||||||
|
void RemoveLogicMenu();
|
||||||
|
void AddMimeTypeAttrs();
|
||||||
|
void MakeTextViewFocus();
|
||||||
|
|
||||||
|
void GetDefaultName(BString &result) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void AddMimeTypeAttrs(BMenu *);
|
||||||
|
|
||||||
|
BMenuField *fMenuField;
|
||||||
|
BTextControl *fTextControl;
|
||||||
|
|
||||||
|
typedef BView _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteTransientQueriesTask {
|
||||||
|
// transient queries get deleted if they didn't get used in a while;
|
||||||
|
// this is the task that takes care of it
|
||||||
|
public:
|
||||||
|
static void StartUpTransientQueryCleaner();
|
||||||
|
|
||||||
|
bool DoSomeWork();
|
||||||
|
virtual ~DeleteTransientQueriesTask();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DeleteTransientQueriesTask();
|
||||||
|
// returns true when done
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
kInitial,
|
||||||
|
kAllocatedWalker,
|
||||||
|
kTraversing,
|
||||||
|
kError
|
||||||
|
};
|
||||||
|
|
||||||
|
State state;
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
bool GetSome();
|
||||||
|
|
||||||
|
bool ProcessOneRef(Model *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
WALKER_NS::TNodeWalker *fWalker;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RecentFindItemsMenu : public BMenu {
|
||||||
|
public:
|
||||||
|
RecentFindItemsMenu(const char *title, const BMessenger *target, uint32 what);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BMessenger fTarget;
|
||||||
|
uint32 fWhat;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DraggableQueryIcon : public DraggableIcon {
|
||||||
|
// query/query template drag&drop helper
|
||||||
|
public:
|
||||||
|
DraggableQueryIcon(BRect frame, const char *name, const BMessage *message,
|
||||||
|
BMessenger target, uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||||
|
uint32 flags = B_WILL_DRAW);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool DragStarted(BMessage *);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,536 @@
|
|||||||
|
/*
|
||||||
|
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 __FUNCTION_OBJECT__
|
||||||
|
#define __FUNCTION_OBJECT__
|
||||||
|
|
||||||
|
#include <Message.h>
|
||||||
|
#include <MessageFilter.h>
|
||||||
|
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Node.h>
|
||||||
|
|
||||||
|
// parameter binders serve to store a copy of a struct and
|
||||||
|
// pass it in and out by pointers, allowing struct parameters to share
|
||||||
|
// the same syntax as scalar ones
|
||||||
|
|
||||||
|
// You will mostly want to use the NewFunctionObject... convenience
|
||||||
|
// factories
|
||||||
|
//
|
||||||
|
|
||||||
|
// add more function objects and specialized binders as needed
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
template<class P>
|
||||||
|
class ParameterBinder {
|
||||||
|
// primitive default binder for scalars
|
||||||
|
public:
|
||||||
|
ParameterBinder() {}
|
||||||
|
ParameterBinder(P p)
|
||||||
|
: p(p)
|
||||||
|
{}
|
||||||
|
|
||||||
|
P Pass() const
|
||||||
|
{ return p; }
|
||||||
|
private:
|
||||||
|
P p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class ParameterBinder<const BEntry *> {
|
||||||
|
public:
|
||||||
|
ParameterBinder() {}
|
||||||
|
ParameterBinder(const BEntry *p)
|
||||||
|
: p(*p)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ParameterBinder &operator=(const BEntry *newp)
|
||||||
|
{ p = *newp; return *this; }
|
||||||
|
|
||||||
|
const BEntry *Pass() const
|
||||||
|
{ return &p; }
|
||||||
|
private:
|
||||||
|
BEntry p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class ParameterBinder<const entry_ref *> {
|
||||||
|
public:
|
||||||
|
ParameterBinder() {}
|
||||||
|
ParameterBinder(const entry_ref *p)
|
||||||
|
{
|
||||||
|
if (p)
|
||||||
|
this->p = *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParameterBinder &operator=(const entry_ref *newp)
|
||||||
|
{ p = *newp; return *this; }
|
||||||
|
|
||||||
|
const entry_ref *Pass() const
|
||||||
|
{ return &p; }
|
||||||
|
private:
|
||||||
|
entry_ref p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class ParameterBinder<const node_ref *> {
|
||||||
|
public:
|
||||||
|
ParameterBinder() {}
|
||||||
|
ParameterBinder(const node_ref * p)
|
||||||
|
: p(*p)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ParameterBinder &operator=(const node_ref *newp)
|
||||||
|
{ p = *newp; return *this; }
|
||||||
|
|
||||||
|
const node_ref *Pass() const
|
||||||
|
{ return &p; }
|
||||||
|
private:
|
||||||
|
node_ref p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class ParameterBinder<const BMessage *> {
|
||||||
|
public:
|
||||||
|
ParameterBinder() {}
|
||||||
|
ParameterBinder(const BMessage *p)
|
||||||
|
: p(p ? new BMessage(*p) : NULL)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~ParameterBinder()
|
||||||
|
{
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParameterBinder &operator=(const BMessage *newp)
|
||||||
|
{
|
||||||
|
delete p;
|
||||||
|
p = (newp ? new BMessage(*newp) : NULL);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BMessage *Pass() const
|
||||||
|
{ return p; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
BMessage *p;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FunctionObject {
|
||||||
|
public:
|
||||||
|
virtual void operator()() = 0;
|
||||||
|
virtual ~FunctionObject() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R>
|
||||||
|
class FunctionObjectWithResult : public FunctionObject {
|
||||||
|
public:
|
||||||
|
const R &Result() const
|
||||||
|
{ return result; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
R result;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Param1>
|
||||||
|
class SingleParamFunctionObject : public FunctionObject {
|
||||||
|
public:
|
||||||
|
SingleParamFunctionObject(void (*callThis)(Param1),
|
||||||
|
Param1 p1)
|
||||||
|
: function(callThis),
|
||||||
|
p1(p1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ (function)(p1.Pass()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void (*function)(Param1);
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Result, class Param1>
|
||||||
|
class SingleParamFunctionObjectWithResult : public FunctionObjectWithResult<Result> {
|
||||||
|
public:
|
||||||
|
SingleParamFunctionObjectWithResult(Result (*function)(Param1), Param1 p1)
|
||||||
|
: function(function),
|
||||||
|
p1(p1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ result = (function)(p1.Pass()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Result (*function)(Param1);
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Param1, class Param2>
|
||||||
|
class TwoParamFunctionObject : public FunctionObject {
|
||||||
|
public:
|
||||||
|
TwoParamFunctionObject(void (*callThis)(Param1, Param2),
|
||||||
|
Param1 p1, Param2 p2)
|
||||||
|
: function(callThis),
|
||||||
|
p1(p1),
|
||||||
|
p2(p2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ (function)(p1.Pass(), p2.Pass()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void (*function)(Param1, Param2);
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
ParameterBinder<Param2> p2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Param1, class Param2, class Param3>
|
||||||
|
class ThreeParamFunctionObject : public FunctionObject {
|
||||||
|
public:
|
||||||
|
ThreeParamFunctionObject(void (*callThis)(Param1, Param2, Param3),
|
||||||
|
Param1 p1, Param2 p2, Param3 p3)
|
||||||
|
: function(callThis),
|
||||||
|
p1(p1),
|
||||||
|
p2(p2),
|
||||||
|
p3(p3)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ (function)(p1.Pass(), p2.Pass(), p3.Pass()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void (*function)(Param1, Param2, Param3);
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
ParameterBinder<Param2> p2;
|
||||||
|
ParameterBinder<Param3> p3;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Result, class Param1, class Param2, class Param3>
|
||||||
|
class ThreeParamFunctionObjectWithResult : public FunctionObjectWithResult<Result> {
|
||||||
|
public:
|
||||||
|
ThreeParamFunctionObjectWithResult(Result (*callThis)(Param1, Param2, Param3),
|
||||||
|
Param1 p1, Param2 p2, Param3 p3)
|
||||||
|
: function(callThis),
|
||||||
|
p1(p1),
|
||||||
|
p2(p2),
|
||||||
|
p3(p3)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ result = (function)(p1.Pass(), p2.Pass(), p3.Pass()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Result (*function)(Param1, Param2, Param3);
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
ParameterBinder<Param2> p2;
|
||||||
|
ParameterBinder<Param3> p3;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Param1, class Param2, class Param3, class Param4>
|
||||||
|
class FourParamFunctionObject : public FunctionObject {
|
||||||
|
public:
|
||||||
|
FourParamFunctionObject(void (*callThis)(Param1, Param2, Param3, Param4),
|
||||||
|
Param1 p1, Param2 p2, Param3 p3, Param4 p4)
|
||||||
|
: function(callThis),
|
||||||
|
p1(p1),
|
||||||
|
p2(p2),
|
||||||
|
p3(p3),
|
||||||
|
p4(p4)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ (function)(p1.Pass(), p2.Pass(), p3.Pass(), p4.Pass()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void (*function)(Param1, Param2, Param3, Param4);
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
ParameterBinder<Param2> p2;
|
||||||
|
ParameterBinder<Param3> p3;
|
||||||
|
ParameterBinder<Param4> p4;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Result, class Param1, class Param2, class Param3, class Param4>
|
||||||
|
class FourParamFunctionObjectWithResult : public FunctionObjectWithResult<Result> {
|
||||||
|
public:
|
||||||
|
FourParamFunctionObjectWithResult(Result (*callThis)(Param1, Param2, Param3, Param4),
|
||||||
|
Param1 p1, Param2 p2, Param3 p3, Param4 p4)
|
||||||
|
: function(callThis),
|
||||||
|
p1(p1),
|
||||||
|
p2(p2),
|
||||||
|
p3(p3),
|
||||||
|
p4(p4)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ result = (function)(p1.Pass(), p2.Pass(), p3.Pass(), p4.Pass()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Result (*function)(Param1, Param2, Param3, Param4);
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
ParameterBinder<Param2> p2;
|
||||||
|
ParameterBinder<Param3> p3;
|
||||||
|
ParameterBinder<Param4> p4;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class PlainMemberFunctionObject : public FunctionObject {
|
||||||
|
public:
|
||||||
|
PlainMemberFunctionObject(void (T::*function)(), T *onThis)
|
||||||
|
: function(function),
|
||||||
|
target(onThis)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ (target->*function)(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void (T::*function)();
|
||||||
|
T *target;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class PlainLockingMemberFunctionObject : public FunctionObject {
|
||||||
|
public:
|
||||||
|
PlainLockingMemberFunctionObject(void (T::*function)(), T *target)
|
||||||
|
: function(function),
|
||||||
|
messenger(target)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{
|
||||||
|
T *target = dynamic_cast<T *>(messenger.Target(NULL));
|
||||||
|
if (!target || !messenger.LockTarget())
|
||||||
|
return;
|
||||||
|
(target->*function)();
|
||||||
|
target->Looper()->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void (T::*function)();
|
||||||
|
BMessenger messenger;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class R>
|
||||||
|
class PlainMemberFunctionObjectWitResult : public FunctionObjectWithResult<R> {
|
||||||
|
public:
|
||||||
|
PlainMemberFunctionObjectWitResult(R (T::*function)(), T *onThis)
|
||||||
|
: function(function),
|
||||||
|
target(onThis)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ result = (target->*function)(); }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
R (T::*function)();
|
||||||
|
T *target;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class Param1>
|
||||||
|
class SingleParamMemberFunctionObject : public FunctionObject {
|
||||||
|
public:
|
||||||
|
SingleParamMemberFunctionObject(void (T::*function)(Param1), T *onThis, Param1 p1)
|
||||||
|
: function(function),
|
||||||
|
target(onThis),
|
||||||
|
p1(p1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ (target->*function)(p1.Pass()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void (T::*function)(Param1);
|
||||||
|
T *target;
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class Param1, class Param2>
|
||||||
|
class TwoParamMemberFunctionObject : public FunctionObject {
|
||||||
|
public:
|
||||||
|
TwoParamMemberFunctionObject(void (T::*function)(Param1, Param2), T *onThis,
|
||||||
|
Param1 p1, Param2 p2)
|
||||||
|
: function(function),
|
||||||
|
target(onThis),
|
||||||
|
p1(p1),
|
||||||
|
p2(p2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ (target->*function)(p1.Pass(), p2.Pass()); }
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void (T::*function)(Param1, Param2);
|
||||||
|
T *target;
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
ParameterBinder<Param2> p2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, class R, class Param1>
|
||||||
|
class SingleParamMemberFunctionObjectWitResult : public FunctionObjectWithResult<R> {
|
||||||
|
public:
|
||||||
|
SingleParamMemberFunctionObjectWitResult(R (T::*function)(Param1), T *onThis,
|
||||||
|
Param1 p1)
|
||||||
|
: function(function),
|
||||||
|
target(onThis),
|
||||||
|
p1(p1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ result = (target->*function)(p1.Pass()); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
R (T::*function)(Param1);
|
||||||
|
T *target;
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class R, class Param1, class Param2>
|
||||||
|
class TwoParamMemberFunctionObjectWithResult : public FunctionObjectWithResult<R> {
|
||||||
|
public:
|
||||||
|
TwoParamMemberFunctionObjectWithResult(R (T::*function)(Param1, Param2), T *onThis,
|
||||||
|
Param1 p1, Param2 p2)
|
||||||
|
: function(function),
|
||||||
|
target(onThis),
|
||||||
|
p1(p1),
|
||||||
|
p2(p2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void operator()()
|
||||||
|
{ result = (target->*function)(p1.Pass(), p2.Pass()); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
R (T::*function)(Param1, Param2);
|
||||||
|
T *target;
|
||||||
|
ParameterBinder<Param1> p1;
|
||||||
|
ParameterBinder<Param2> p2;
|
||||||
|
};
|
||||||
|
|
||||||
|
// convenience factory functions
|
||||||
|
// NewFunctionObject
|
||||||
|
// NewMemberFunctionObject
|
||||||
|
// NewMemberFunctionObjectWithResult
|
||||||
|
// NewLockingMemberFunctionObject
|
||||||
|
//
|
||||||
|
// ... add the missing ones as needed
|
||||||
|
|
||||||
|
template<class Param1>
|
||||||
|
SingleParamFunctionObject<Param1> *
|
||||||
|
NewFunctionObject(void (*function)(Param1), Param1 p1)
|
||||||
|
{
|
||||||
|
return new SingleParamFunctionObject<Param1>(function, p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Param1, class Param2>
|
||||||
|
TwoParamFunctionObject<Param1, Param2> *
|
||||||
|
NewFunctionObject(void (*function)(Param1, Param2), Param1 p1, Param2 p2)
|
||||||
|
{
|
||||||
|
return new TwoParamFunctionObject<Param1, Param2>(function, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Param1, class Param2, class Param3>
|
||||||
|
ThreeParamFunctionObject<Param1, Param2, Param3> *
|
||||||
|
NewFunctionObject(void (*function)(Param1, Param2, Param3),
|
||||||
|
Param1 p1, Param2 p2, Param3 p3)
|
||||||
|
{
|
||||||
|
return new ThreeParamFunctionObject<Param1, Param2, Param3>(function, p1, p2, p3);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
PlainMemberFunctionObject<T> *
|
||||||
|
NewMemberFunctionObject(void (T::*function)(), T *onThis)
|
||||||
|
{
|
||||||
|
return new PlainMemberFunctionObject<T>(function, onThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class Param1>
|
||||||
|
SingleParamMemberFunctionObject<T, Param1> *
|
||||||
|
NewMemberFunctionObject(void (T::*function)(Param1), T *onThis, Param1 p1)
|
||||||
|
{
|
||||||
|
return new SingleParamMemberFunctionObject<T, Param1>(function, onThis, p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class Param1, class Param2>
|
||||||
|
TwoParamMemberFunctionObject<T, Param1, Param2> *
|
||||||
|
NewMemberFunctionObject(void (T::*function)(Param1, Param2), T *onThis,
|
||||||
|
Param1 p1, Param2 p2)
|
||||||
|
{
|
||||||
|
return new TwoParamMemberFunctionObject<T, Param1, Param2>(function, onThis,
|
||||||
|
p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class R, class Param1, class Param2>
|
||||||
|
TwoParamMemberFunctionObjectWithResult<T, R, Param1, Param2> *
|
||||||
|
NewMemberFunctionObjectWithResult(R (T::*function)(Param1, Param2),
|
||||||
|
T *onThis, Param1 p1, Param2 p2)
|
||||||
|
{
|
||||||
|
return new TwoParamMemberFunctionObjectWithResult<T, R, Param1, Param2>
|
||||||
|
(function, onThis, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class HandlerOrSubclass>
|
||||||
|
PlainLockingMemberFunctionObject<HandlerOrSubclass> *
|
||||||
|
NewLockingMemberFunctionObject(void (HandlerOrSubclass::*function)(),
|
||||||
|
HandlerOrSubclass *onThis)
|
||||||
|
{
|
||||||
|
return new PlainLockingMemberFunctionObject<HandlerOrSubclass>(function, onThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,323 @@
|
|||||||
|
#include "GroupedMenu.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
|
||||||
|
TMenuItemGroup::TMenuItemGroup(const char *name)
|
||||||
|
:
|
||||||
|
fMenu(NULL),
|
||||||
|
fFirstItemIndex(-1),
|
||||||
|
fItemsTotal(0),
|
||||||
|
fHasSeparator(false)
|
||||||
|
{
|
||||||
|
if (name != NULL && name[0] != '\0')
|
||||||
|
fName = strdup(name);
|
||||||
|
else
|
||||||
|
fName = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TMenuItemGroup::~TMenuItemGroup()
|
||||||
|
{
|
||||||
|
free((char *)fName);
|
||||||
|
|
||||||
|
if (fMenu == NULL) {
|
||||||
|
BMenuItem *item;
|
||||||
|
while ((item = RemoveItem(0L)) != NULL)
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TMenuItemGroup::AddItem(BMenuItem *item)
|
||||||
|
{
|
||||||
|
if (!fList.AddItem(item))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fMenu)
|
||||||
|
fMenu->AddGroupItem(this, item, fList.IndexOf(item));
|
||||||
|
|
||||||
|
fItemsTotal++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TMenuItemGroup::AddItem(BMenuItem *item, int32 atIndex)
|
||||||
|
{
|
||||||
|
if (!fList.AddItem(item, atIndex))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fMenu)
|
||||||
|
fMenu->AddGroupItem(this, item, atIndex);
|
||||||
|
|
||||||
|
fItemsTotal++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TMenuItemGroup::AddItem(BMenu *menu)
|
||||||
|
{
|
||||||
|
BMenuItem *item = new BMenuItem(menu);
|
||||||
|
if (item == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AddItem(item)) {
|
||||||
|
delete item;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TMenuItemGroup::AddItem(BMenu *menu, int32 atIndex)
|
||||||
|
{
|
||||||
|
BMenuItem *item = new BMenuItem(menu);
|
||||||
|
if (item == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!AddItem(item, atIndex)) {
|
||||||
|
delete item;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TMenuItemGroup::RemoveItem(BMenuItem *item)
|
||||||
|
{
|
||||||
|
if (fMenu)
|
||||||
|
fMenu->RemoveGroupItem(this, item);
|
||||||
|
|
||||||
|
return fList.RemoveItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TMenuItemGroup::RemoveItem(BMenu *menu)
|
||||||
|
{
|
||||||
|
BMenuItem *item = menu->Superitem();
|
||||||
|
if (item == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return RemoveItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMenuItem *
|
||||||
|
TMenuItemGroup::RemoveItem(int32 index)
|
||||||
|
{
|
||||||
|
BMenuItem *item = ItemAt(index);
|
||||||
|
if (item == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (RemoveItem(item))
|
||||||
|
return item;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMenuItem *
|
||||||
|
TMenuItemGroup::ItemAt(int32 index)
|
||||||
|
{
|
||||||
|
return static_cast<BMenuItem *>(fList.ItemAt(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
TMenuItemGroup::CountItems()
|
||||||
|
{
|
||||||
|
return fList.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TMenuItemGroup::Separated(bool separated)
|
||||||
|
{
|
||||||
|
if (separated == fHasSeparator)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fHasSeparator = separated;
|
||||||
|
|
||||||
|
if (separated)
|
||||||
|
fItemsTotal++;
|
||||||
|
else
|
||||||
|
fItemsTotal--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TMenuItemGroup::HasSeparator()
|
||||||
|
{
|
||||||
|
return fHasSeparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
TGroupedMenu::TGroupedMenu(const char *name)
|
||||||
|
: BMenu(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TGroupedMenu::~TGroupedMenu()
|
||||||
|
{
|
||||||
|
TMenuItemGroup *group;
|
||||||
|
while ((group = static_cast<TMenuItemGroup *>(fGroups.RemoveItem(0L))) != NULL)
|
||||||
|
delete group;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TGroupedMenu::AddGroup(TMenuItemGroup *group)
|
||||||
|
{
|
||||||
|
if (!fGroups.AddItem(group))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
group->fMenu = this;
|
||||||
|
|
||||||
|
for (int32 i = 0; i < group->CountItems(); i++) {
|
||||||
|
AddGroupItem(group, group->ItemAt(i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TGroupedMenu::AddGroup(TMenuItemGroup *group, int32 atIndex)
|
||||||
|
{
|
||||||
|
if (!fGroups.AddItem(group, atIndex))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
group->fMenu = this;
|
||||||
|
|
||||||
|
for (int32 i = 0; i < group->CountItems(); i++) {
|
||||||
|
AddGroupItem(group, group->ItemAt(i), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TGroupedMenu::RemoveGroup(TMenuItemGroup *group)
|
||||||
|
{
|
||||||
|
if (group->HasSeparator()) {
|
||||||
|
delete RemoveItem(group->fFirstItemIndex);
|
||||||
|
group->Separated(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
group->fMenu = NULL;
|
||||||
|
group->fFirstItemIndex = -1;
|
||||||
|
|
||||||
|
for (int32 i = 0; i < group->CountItems(); i++) {
|
||||||
|
RemoveItem(group->ItemAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fGroups.RemoveItem(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TMenuItemGroup *
|
||||||
|
TGroupedMenu::GroupAt(int32 index)
|
||||||
|
{
|
||||||
|
return static_cast<TMenuItemGroup *>(fGroups.ItemAt(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
TGroupedMenu::CountGroups()
|
||||||
|
{
|
||||||
|
return fGroups.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TGroupedMenu::AddGroupItem(TMenuItemGroup *group, BMenuItem *item, int32 atIndex)
|
||||||
|
{
|
||||||
|
int32 groupIndex = fGroups.IndexOf(group);
|
||||||
|
bool addSeparator = false;
|
||||||
|
|
||||||
|
if (group->fFirstItemIndex == -1) {
|
||||||
|
// find new home for this group
|
||||||
|
if (groupIndex > 0) {
|
||||||
|
// add this group after an existing one
|
||||||
|
TMenuItemGroup *previous = GroupAt(groupIndex - 1);
|
||||||
|
group->fFirstItemIndex = previous->fFirstItemIndex + previous->fItemsTotal;
|
||||||
|
addSeparator = true;
|
||||||
|
} else {
|
||||||
|
// this is the first group
|
||||||
|
TMenuItemGroup *successor = GroupAt(groupIndex + 1);
|
||||||
|
if (successor != NULL) {
|
||||||
|
group->fFirstItemIndex = successor->fFirstItemIndex;
|
||||||
|
if (successor->fHasSeparator) {
|
||||||
|
// we'll need one as well
|
||||||
|
addSeparator = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
group->fFirstItemIndex = CountItems();
|
||||||
|
if (group->fFirstItemIndex > 0)
|
||||||
|
addSeparator = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addSeparator) {
|
||||||
|
AddItem(new BSeparatorItem(), group->fFirstItemIndex);
|
||||||
|
group->Separated(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert item for real
|
||||||
|
|
||||||
|
AddItem(item, atIndex + group->fFirstItemIndex + (group->HasSeparator() ? 1 : 0));
|
||||||
|
|
||||||
|
// move the groups after this one
|
||||||
|
|
||||||
|
for (int32 i = groupIndex + 1; i < CountGroups(); i++) {
|
||||||
|
group = GroupAt(i);
|
||||||
|
group->fFirstItemIndex += addSeparator ? 2 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TGroupedMenu::RemoveGroupItem(TMenuItemGroup *group, BMenuItem *item)
|
||||||
|
{
|
||||||
|
int32 groupIndex = fGroups.IndexOf(group);
|
||||||
|
bool removedSeparator = false;
|
||||||
|
|
||||||
|
if (group->CountItems() == 1) {
|
||||||
|
// this is the last item
|
||||||
|
if (group->HasSeparator()) {
|
||||||
|
RemoveItem(group->fFirstItemIndex);
|
||||||
|
group->Separated(false);
|
||||||
|
removedSeparator = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert item for real
|
||||||
|
|
||||||
|
RemoveItem(item);
|
||||||
|
|
||||||
|
// move the groups after this one
|
||||||
|
|
||||||
|
for (int32 i = groupIndex + 1; i < CountGroups(); i++) {
|
||||||
|
group = GroupAt(i);
|
||||||
|
group->fFirstItemIndex -= removedSeparator ? 2 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#ifndef GROUPED_MENU_H
|
||||||
|
#define GROUPED_MENU_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Menu.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class TGroupedMenu;
|
||||||
|
|
||||||
|
class TMenuItemGroup {
|
||||||
|
public:
|
||||||
|
TMenuItemGroup(const char *name);
|
||||||
|
~TMenuItemGroup();
|
||||||
|
|
||||||
|
bool AddItem(BMenuItem *item);
|
||||||
|
bool AddItem(BMenuItem *item, int32 atIndex);
|
||||||
|
bool AddItem(BMenu *menu);
|
||||||
|
bool AddItem(BMenu *menu, int32 atIndex);
|
||||||
|
|
||||||
|
bool RemoveItem(BMenuItem *item);
|
||||||
|
bool RemoveItem(BMenu *menu);
|
||||||
|
BMenuItem *RemoveItem(int32 index);
|
||||||
|
|
||||||
|
BMenuItem *ItemAt(int32 index);
|
||||||
|
int32 CountItems();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class TGroupedMenu;
|
||||||
|
void Separated(bool separated);
|
||||||
|
bool HasSeparator();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char *fName;
|
||||||
|
BList fList;
|
||||||
|
TGroupedMenu *fMenu;
|
||||||
|
int32 fFirstItemIndex;
|
||||||
|
int32 fItemsTotal;
|
||||||
|
bool fHasSeparator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TGroupedMenu : public BMenu {
|
||||||
|
public:
|
||||||
|
TGroupedMenu(const char *name);
|
||||||
|
~TGroupedMenu();
|
||||||
|
|
||||||
|
bool AddGroup(TMenuItemGroup *group);
|
||||||
|
bool AddGroup(TMenuItemGroup *group, int32 atIndex);
|
||||||
|
|
||||||
|
bool RemoveGroup(TMenuItemGroup *group);
|
||||||
|
|
||||||
|
TMenuItemGroup *GroupAt(int32 index);
|
||||||
|
int32 CountGroups();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class TMenuItemGroup;
|
||||||
|
void AddGroupItem(TMenuItemGroup *group, BMenuItem *item, int32 atIndex);
|
||||||
|
void RemoveGroupItem(TMenuItemGroup *group, BMenuItem *item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BList fGroups;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
#endif /* GROUPED_MENU_H */
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,502 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Icon cache is used for drawing node icons; it caches icons
|
||||||
|
// and reuses them for successive draws
|
||||||
|
|
||||||
|
#ifndef __NU_ICON_CACHE__
|
||||||
|
#define __NU_ICON_CACHE__
|
||||||
|
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <Mime.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include "AutoLock.h"
|
||||||
|
#include "ObjectList.h"
|
||||||
|
#include "OpenHashTable.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
// Icon cache splits icons into two caches - the shared cache, likely to get the
|
||||||
|
// most hits and the node cache. Every icon that is found in a mime based
|
||||||
|
// structure goes into the shared cache, only files that have their own private
|
||||||
|
// icon use the node cache;
|
||||||
|
// Entries are only deleted from the shared cache if an icon for a mime type changes,
|
||||||
|
// this makes async icon drawing easier. Node cache deletes it's entries whenever a
|
||||||
|
// file gets deleted.
|
||||||
|
|
||||||
|
// if a view ever uses the cache to draw in async mode, it needs to call
|
||||||
|
// it when it is being destroyed
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class Model;
|
||||||
|
class ModelNodeLazyOpener;
|
||||||
|
class LazyBitmapAllocator;
|
||||||
|
class SharedIconCache;
|
||||||
|
class SharedCacheEntry;
|
||||||
|
|
||||||
|
enum IconDrawMode {
|
||||||
|
// Difrent states of icon drawing
|
||||||
|
kSelected = 0x01,
|
||||||
|
kNotFocused = 0x02, // Tracker window
|
||||||
|
kOpen = 0x04, // open folder, trash
|
||||||
|
kNotEmpty = 0x08, // full trash
|
||||||
|
kDisabled = 0x10, // inactive nav menu entry
|
||||||
|
kActive = 0x20, // active home dir, boot volume
|
||||||
|
kLink = 0x40, // symbolic link
|
||||||
|
kTrackerSpecialized = 0x80,
|
||||||
|
|
||||||
|
// some common combinations
|
||||||
|
kNormalIcon = 0,
|
||||||
|
kSelectedIcon = kSelected,
|
||||||
|
kSelectedInBackgroundIcon = kSelected | kNotFocused,
|
||||||
|
kOpenIcon = kOpen,
|
||||||
|
kOpenSelectedIcon = kSelected | kOpen,
|
||||||
|
kOpenSelectedInBackgroundIcon = kSelected | kNotFocused | kOpen,
|
||||||
|
kFullIcon = kNotEmpty,
|
||||||
|
kFullSelectedIcon = kNotEmpty | kOpen,
|
||||||
|
kDimmedIcon
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NORMAL_ICON_ONLY kNormalIcon
|
||||||
|
// replace use of these defines with mode once the respective getters
|
||||||
|
// can get non-plain icons
|
||||||
|
|
||||||
|
|
||||||
|
// Where did an icon come from
|
||||||
|
enum IconSource {
|
||||||
|
kUnknownSource,
|
||||||
|
kUnknownNotFromNode, // icon origin not known but determined not to be from
|
||||||
|
// the node itself
|
||||||
|
kTrackerDefault, // file has no type, Tracker provides generic, folder,
|
||||||
|
// symlink or app
|
||||||
|
kTrackerSupplied, // home directory, boot volume, trash, etc.
|
||||||
|
kMetaMime, // from BMimeType
|
||||||
|
kPreferredAppForType, // have a preferred application for a type, has an icon
|
||||||
|
kPreferredAppForNode, // have a preferred application for this node,
|
||||||
|
// has an icon
|
||||||
|
kVolume,
|
||||||
|
kNode
|
||||||
|
};
|
||||||
|
|
||||||
|
class IconCacheEntry {
|
||||||
|
// aliased entries don't own their icons, just point
|
||||||
|
// to some other entry that does
|
||||||
|
|
||||||
|
// This is used for icons that are defined by a preferred app for
|
||||||
|
// a metamime, types that do not have an icon an get to point to
|
||||||
|
// generic, etc.
|
||||||
|
|
||||||
|
public:
|
||||||
|
IconCacheEntry();
|
||||||
|
~IconCacheEntry();
|
||||||
|
|
||||||
|
void SetAliasFor(const SharedIconCache *, const SharedCacheEntry *);
|
||||||
|
static IconCacheEntry *ResolveIfAlias(const SharedIconCache *, IconCacheEntry *);
|
||||||
|
IconCacheEntry *ResolveIfAlias(const SharedIconCache *);
|
||||||
|
|
||||||
|
void SetIcon(BBitmap *bitmap, IconDrawMode mode, icon_size size,
|
||||||
|
bool create = false);
|
||||||
|
|
||||||
|
bool HaveIconBitmap(IconDrawMode mode, icon_size size) const;
|
||||||
|
bool CanConstructBitmap(IconDrawMode mode, icon_size size) const;
|
||||||
|
static bool AlternateModeForIconConstructing(IconDrawMode requestedMode,
|
||||||
|
IconDrawMode &alternate, icon_size size);
|
||||||
|
BBitmap *ConstructBitmap(BBitmap *constructFrom, IconDrawMode requestedMode,
|
||||||
|
IconDrawMode constructFromMode, icon_size size,
|
||||||
|
LazyBitmapAllocator *);
|
||||||
|
BBitmap *ConstructBitmap(IconDrawMode requestedMode, icon_size size,
|
||||||
|
LazyBitmapAllocator *);
|
||||||
|
// same as above, always uses normal icon as source
|
||||||
|
|
||||||
|
bool IconHitTest(BPoint, IconDrawMode , icon_size) const;
|
||||||
|
// given a point, returns true if a non-transparent pixel was hit
|
||||||
|
|
||||||
|
void RetireIcons(BObjectList<BBitmap> *retiredBitmapList);
|
||||||
|
// can't just delete icons, they may be still drawing
|
||||||
|
// async; instead, put them on the retired list and
|
||||||
|
// only delete the list if it grows too much, way after
|
||||||
|
// the icon finishes drawing
|
||||||
|
//
|
||||||
|
// This could fail if we retire a lot of icons (10 * 1024)
|
||||||
|
// while we are drawing them, shouldn't be a practical problem
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
BBitmap *IconForMode(IconDrawMode mode, icon_size size) const;
|
||||||
|
void SetIconForMode(BBitmap *bitmap, IconDrawMode mode, icon_size size);
|
||||||
|
|
||||||
|
// list of most common icons
|
||||||
|
BBitmap *fLargeIcon;
|
||||||
|
BBitmap *fMiniIcon;
|
||||||
|
BBitmap *fHilitedLargeIcon;
|
||||||
|
BBitmap *fHilitedMiniIcon;
|
||||||
|
int32 fAliasForIndex;
|
||||||
|
|
||||||
|
// list of other icon kinds would be added here
|
||||||
|
|
||||||
|
friend class SharedIconCache;
|
||||||
|
friend class NodeIconCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SimpleIconCache {
|
||||||
|
public:
|
||||||
|
SimpleIconCache(const char *);
|
||||||
|
virtual ~SimpleIconCache() {}
|
||||||
|
|
||||||
|
virtual void Draw(IconCacheEntry *, BView *, BPoint, IconDrawMode mode,
|
||||||
|
icon_size size, bool async = false) = 0;
|
||||||
|
virtual void Draw(IconCacheEntry *, BView *, BPoint , IconDrawMode ,
|
||||||
|
icon_size , void (*)(BView *, BPoint, BBitmap *, void *), void * = NULL) = 0;
|
||||||
|
|
||||||
|
bool Lock();
|
||||||
|
void Unlock();
|
||||||
|
bool IsLocked() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Benaphore fLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SharedCacheEntry : public IconCacheEntry {
|
||||||
|
public:
|
||||||
|
SharedCacheEntry();
|
||||||
|
SharedCacheEntry(const char *fileType, const char *appSignature = 0);
|
||||||
|
|
||||||
|
void Draw(BView *, BPoint, IconDrawMode mode, icon_size size,
|
||||||
|
bool async = false);
|
||||||
|
|
||||||
|
void Draw(BView *, BPoint , IconDrawMode , icon_size ,
|
||||||
|
void (*)(BView *, BPoint, BBitmap *, void *), void * = NULL);
|
||||||
|
|
||||||
|
const char *FileType() const;
|
||||||
|
const char *AppSignature() const;
|
||||||
|
|
||||||
|
// hash table support
|
||||||
|
uint32 Hash() const;
|
||||||
|
static uint32 Hash(const char *fileType, const char *appSignature = 0);
|
||||||
|
bool operator==(const SharedCacheEntry &) const;
|
||||||
|
void SetTo(const char *fileType, const char *appSignature = 0);
|
||||||
|
|
||||||
|
int32 fNext;
|
||||||
|
private:
|
||||||
|
BString fFileType;
|
||||||
|
BString fAppSignature;
|
||||||
|
|
||||||
|
friend class SharedIconCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SharedCacheEntryArray : public OpenHashElementArray<SharedCacheEntry> {
|
||||||
|
// SharedIconCache stores all it's elements in this array
|
||||||
|
public:
|
||||||
|
SharedCacheEntryArray(int32 initialSize);
|
||||||
|
SharedCacheEntry *Add();
|
||||||
|
};
|
||||||
|
|
||||||
|
class SharedIconCache : public SimpleIconCache {
|
||||||
|
// SharedIconCache is used for icons that come from the mime database
|
||||||
|
public:
|
||||||
|
SharedIconCache();
|
||||||
|
|
||||||
|
virtual void Draw(IconCacheEntry *, BView *, BPoint, IconDrawMode mode,
|
||||||
|
icon_size size, bool async = false);
|
||||||
|
virtual void Draw(IconCacheEntry *, BView *, BPoint , IconDrawMode ,
|
||||||
|
icon_size , void (*)(BView *, BPoint, BBitmap *, void *), void * = NULL);
|
||||||
|
|
||||||
|
SharedCacheEntry *FindItem(const char *fileType, const char *appSignature = 0)
|
||||||
|
const;
|
||||||
|
SharedCacheEntry *AddItem(const char *fileType, const char *appSignature = 0);
|
||||||
|
SharedCacheEntry *AddItem(SharedCacheEntry **outstandingEntry, const char *fileType,
|
||||||
|
const char *appSignature = 0);
|
||||||
|
// same as previous AddItem, updates the pointer to outstandingEntry, because
|
||||||
|
// adding to the hash table makes any pending pointer invalid
|
||||||
|
void IconChanged(SharedCacheEntry *);
|
||||||
|
|
||||||
|
void SetAliasFor(IconCacheEntry *alias, const SharedCacheEntry *original) const;
|
||||||
|
IconCacheEntry *ResolveIfAlias(IconCacheEntry *entry) const;
|
||||||
|
int32 EntryIndex(const SharedCacheEntry *entry) const;
|
||||||
|
|
||||||
|
void RemoveAliasesTo(int32 index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpenHashTable<SharedCacheEntry, SharedCacheEntryArray> fHashTable;
|
||||||
|
SharedCacheEntryArray fElementArray;
|
||||||
|
BObjectList<BBitmap> fRetiredBitmaps;
|
||||||
|
// icons are drawn asynchronously, can't just delete them
|
||||||
|
// right away, instead have to place them onto the retired bitmap list
|
||||||
|
// and wait for the next sync to delete them
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeCacheEntry : public IconCacheEntry {
|
||||||
|
public:
|
||||||
|
NodeCacheEntry(bool permanent = false);
|
||||||
|
NodeCacheEntry(const node_ref *, bool permanent = false);
|
||||||
|
void Draw(BView *, BPoint, IconDrawMode mode, icon_size size,
|
||||||
|
bool async = false);
|
||||||
|
|
||||||
|
void Draw(BView *, BPoint , IconDrawMode , icon_size ,
|
||||||
|
void (*)(BView *, BPoint, BBitmap *, void *), void * = NULL);
|
||||||
|
|
||||||
|
const node_ref *Node() const;
|
||||||
|
|
||||||
|
uint32 Hash() const;
|
||||||
|
static uint32 Hash(const node_ref *);
|
||||||
|
bool operator==(const NodeCacheEntry &) const;
|
||||||
|
void SetTo(const node_ref *);
|
||||||
|
void MakePermanent();
|
||||||
|
bool Permanent() const;
|
||||||
|
|
||||||
|
int32 fNext;
|
||||||
|
private:
|
||||||
|
node_ref fRef;
|
||||||
|
bool fPermanent;
|
||||||
|
// special cache entry that has to be deleted explicitly
|
||||||
|
|
||||||
|
friend class NodeIconCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeCacheEntryArray : public OpenHashElementArray<NodeCacheEntry> {
|
||||||
|
// NodeIconCache stores all it's elements in this array
|
||||||
|
public:
|
||||||
|
NodeCacheEntryArray(int32 initialSize);
|
||||||
|
NodeCacheEntry *Add();
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeIconCache : public SimpleIconCache {
|
||||||
|
// NodeIconCache is used for nodes that define their own icon icons
|
||||||
|
public:
|
||||||
|
NodeIconCache();
|
||||||
|
|
||||||
|
virtual void Draw(IconCacheEntry *, BView *, BPoint, IconDrawMode ,
|
||||||
|
icon_size , bool async = false);
|
||||||
|
|
||||||
|
virtual void Draw(IconCacheEntry *, BView *, BPoint , IconDrawMode ,
|
||||||
|
icon_size , void (*)(BView *, BPoint, BBitmap *, void *), void * = 0);
|
||||||
|
|
||||||
|
NodeCacheEntry *FindItem(const node_ref *) const;
|
||||||
|
NodeCacheEntry *AddItem(const node_ref *, bool permanent = false);
|
||||||
|
NodeCacheEntry *AddItem(NodeCacheEntry **outstandingEntry, const node_ref *);
|
||||||
|
// same as previous AddItem, updates the pointer to outstandingEntry, because
|
||||||
|
// adding to the hash table makes any pending pointer invalid
|
||||||
|
void Deleting(const node_ref *);
|
||||||
|
// model for this node is getting deleted (not necessarily the node itself)
|
||||||
|
void Removing(const node_ref *);
|
||||||
|
// used by permanent NodeIconCache entries, when an entry gets
|
||||||
|
// deleted
|
||||||
|
void Deleting(const BView *);
|
||||||
|
void IconChanged(const Model *);
|
||||||
|
|
||||||
|
|
||||||
|
void RemoveAliasesTo(int32 index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
OpenHashTable<NodeCacheEntry, NodeCacheEntryArray> fHashTable;
|
||||||
|
NodeCacheEntryArray fElementArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
const int32 kColorTransformTableSize = 256;
|
||||||
|
|
||||||
|
class IconCache {
|
||||||
|
public:
|
||||||
|
IconCache();
|
||||||
|
|
||||||
|
void Draw(Model *, BView *, BPoint where, IconDrawMode mode,
|
||||||
|
icon_size size, bool async = false);
|
||||||
|
// draw an icon for a model, load the icon from the appropriate
|
||||||
|
// location if not cached already
|
||||||
|
|
||||||
|
void SyncDraw(Model *, BView *, BPoint , IconDrawMode ,
|
||||||
|
icon_size , void (*)(BView *, BPoint, BBitmap *, void *),
|
||||||
|
void *passThruState = 0);
|
||||||
|
// draw an icon for a model, load the icon from the appropriate
|
||||||
|
// location if not cached already; only works for sync draws,
|
||||||
|
// once the call returns, the bitmap may be deleted
|
||||||
|
|
||||||
|
// preload calls used to ensure successive cache hit for the respective
|
||||||
|
// icon, used for common tracker types, etc; Not calling these should only
|
||||||
|
// cause a slowdown
|
||||||
|
void Preload(Model *, IconDrawMode mode, icon_size size, bool permanent = false);
|
||||||
|
status_t Preload(const char *mimeType, IconDrawMode mode, icon_size size);
|
||||||
|
|
||||||
|
void Deleting(const Model *);
|
||||||
|
// hook to manage unloading icons for nodes that are going away
|
||||||
|
void Removing(const Model *model);
|
||||||
|
// used by permanent NodeIconCache entries, when an entry gets
|
||||||
|
// deleted
|
||||||
|
void Deleting(const BView *);
|
||||||
|
// hook to manage deleting draw view caches for views that are
|
||||||
|
// going away
|
||||||
|
|
||||||
|
// icon changed calls, used when a node or a file type has an icon changed
|
||||||
|
// the icons for the node/file type will be flushed and re-cached during
|
||||||
|
// the next draw
|
||||||
|
void IconChanged(Model *);
|
||||||
|
void IconChanged(const char *mimeType, const char *appSignature);
|
||||||
|
|
||||||
|
bool IsIconFrom(const Model *, const char *mimeType,
|
||||||
|
const char *appSignature) const;
|
||||||
|
// called when metamime database changed to figure out which models
|
||||||
|
// to redraw
|
||||||
|
|
||||||
|
bool IconHitTest(BPoint, const Model *, IconDrawMode , icon_size );
|
||||||
|
|
||||||
|
// utility calls for building specialized icons
|
||||||
|
BBitmap *MakeSelectedIcon(const BBitmap *normal, icon_size,
|
||||||
|
LazyBitmapAllocator *);
|
||||||
|
|
||||||
|
|
||||||
|
static bool NeedsDeletionNotification(IconSource);
|
||||||
|
|
||||||
|
static IconCache *sIconCache;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// shared calls
|
||||||
|
IconCacheEntry *Preload(AutoLock<SimpleIconCache> *nodeCache,
|
||||||
|
AutoLock<SimpleIconCache> *sharedCache,
|
||||||
|
AutoLock<SimpleIconCache> **resultingLockedCache,
|
||||||
|
Model *, IconDrawMode mode, icon_size size, bool permanent);
|
||||||
|
// preload uses lazy locking, returning the cache we decided
|
||||||
|
// to use to get the icon
|
||||||
|
// <resultingLockedCache> may be null if we don't care
|
||||||
|
|
||||||
|
// shared mime-based icon retrieval calls
|
||||||
|
IconCacheEntry *GetIconForPreferredApp(const char *mimeTypeSignature,
|
||||||
|
const char *preferredApp, IconDrawMode mode, icon_size size,
|
||||||
|
LazyBitmapAllocator *, IconCacheEntry *);
|
||||||
|
IconCacheEntry *GetIconFromFileTypes(ModelNodeLazyOpener *, IconSource &source,
|
||||||
|
IconDrawMode mode, icon_size size, LazyBitmapAllocator *,
|
||||||
|
IconCacheEntry *);
|
||||||
|
IconCacheEntry *GetIconFromMetaMime(const char *fileType, IconDrawMode mode,
|
||||||
|
icon_size size, LazyBitmapAllocator *,
|
||||||
|
IconCacheEntry *);
|
||||||
|
IconCacheEntry *GetVolumeIcon(AutoLock<SimpleIconCache> *nodeCache,
|
||||||
|
AutoLock<SimpleIconCache> *sharedCache,
|
||||||
|
AutoLock<SimpleIconCache> **resultingLockedCache,
|
||||||
|
Model *, IconSource &, IconDrawMode mode,
|
||||||
|
icon_size size, LazyBitmapAllocator *);
|
||||||
|
IconCacheEntry *GetRootIcon(AutoLock<SimpleIconCache> *nodeCache,
|
||||||
|
AutoLock<SimpleIconCache> *sharedCache,
|
||||||
|
AutoLock<SimpleIconCache> **resultingLockedCache,
|
||||||
|
Model *, IconSource &, IconDrawMode mode,
|
||||||
|
icon_size size, LazyBitmapAllocator *);
|
||||||
|
IconCacheEntry *GetWellKnownIcon(AutoLock<SimpleIconCache> *nodeCache,
|
||||||
|
AutoLock<SimpleIconCache> *sharedCache,
|
||||||
|
AutoLock<SimpleIconCache> **resultingLockedCache,
|
||||||
|
Model *, IconSource &, IconDrawMode mode,
|
||||||
|
icon_size size, LazyBitmapAllocator *);
|
||||||
|
IconCacheEntry *GetNodeIcon(ModelNodeLazyOpener *,
|
||||||
|
AutoLock<SimpleIconCache> *nodeCache,
|
||||||
|
AutoLock<SimpleIconCache> **resultingLockedCache,
|
||||||
|
Model *, IconSource &, IconDrawMode mode,
|
||||||
|
icon_size size, LazyBitmapAllocator *, IconCacheEntry *, bool permanent);
|
||||||
|
IconCacheEntry *GetGenericIcon(AutoLock<SimpleIconCache> *sharedCache,
|
||||||
|
AutoLock<SimpleIconCache> **resultingLockedCache,
|
||||||
|
Model *, IconSource &, IconDrawMode mode,
|
||||||
|
icon_size size, LazyBitmapAllocator *, IconCacheEntry *);
|
||||||
|
IconCacheEntry *GetFallbackIcon(AutoLock<SimpleIconCache> *sharedCacheLocker,
|
||||||
|
AutoLock<SimpleIconCache> **resultingOpenCache,
|
||||||
|
Model *model, IconDrawMode mode, icon_size size,
|
||||||
|
LazyBitmapAllocator *lazyBitmap, IconCacheEntry *entry);
|
||||||
|
|
||||||
|
BBitmap *MakeTransformedIcon(const BBitmap *, icon_size,
|
||||||
|
int32 colorTransformTable [], LazyBitmapAllocator *);
|
||||||
|
|
||||||
|
NodeIconCache fNodeCache;
|
||||||
|
SharedIconCache fSharedCache;
|
||||||
|
|
||||||
|
void InitHiliteTable();
|
||||||
|
|
||||||
|
int32 fHiliteTable[kColorTransformTableSize];
|
||||||
|
bool fInitHiliteTable;
|
||||||
|
// on if we still need to initialize the hilite table
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LazyBitmapAllocator {
|
||||||
|
// Utility class used when we aren't sure that we will keep a bitmap,
|
||||||
|
// need a bitmap or be able to construct it properly
|
||||||
|
public:
|
||||||
|
LazyBitmapAllocator(icon_size size, color_space colorSpace = kDefaultIconDepth,
|
||||||
|
bool preallocate = false);
|
||||||
|
~LazyBitmapAllocator();
|
||||||
|
|
||||||
|
BBitmap *Get();
|
||||||
|
BBitmap *Adopt();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BBitmap *fBitmap;
|
||||||
|
icon_size fSize;
|
||||||
|
color_space fColorSpace;
|
||||||
|
};
|
||||||
|
|
||||||
|
// nothing but inlines after here
|
||||||
|
|
||||||
|
inline const char *
|
||||||
|
SharedCacheEntry::FileType() const
|
||||||
|
{
|
||||||
|
return fFileType.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char *
|
||||||
|
SharedCacheEntry::AppSignature() const
|
||||||
|
{
|
||||||
|
return fAppSignature.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
IconCache::NeedsDeletionNotification(IconSource from)
|
||||||
|
{
|
||||||
|
return from == kNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline IconCacheEntry *
|
||||||
|
SharedIconCache::ResolveIfAlias(IconCacheEntry *entry) const
|
||||||
|
{
|
||||||
|
if (entry->fAliasForIndex < 0)
|
||||||
|
return entry;
|
||||||
|
|
||||||
|
return fHashTable.ElementAt(entry->fAliasForIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32
|
||||||
|
SharedIconCache::EntryIndex(const SharedCacheEntry *entry) const
|
||||||
|
{
|
||||||
|
return fHashTable.ElementIndex(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,330 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// menu items with small icons.
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <Menu.h>
|
||||||
|
#include <NodeInfo.h>
|
||||||
|
|
||||||
|
#include "IconCache.h"
|
||||||
|
#include "IconMenuItem.h"
|
||||||
|
|
||||||
|
|
||||||
|
ModelMenuItem::ModelMenuItem(const Model *model, const char *title,
|
||||||
|
BMessage *message, char shortcut, uint32 modifiers,
|
||||||
|
bool drawText, bool extraPad)
|
||||||
|
: BMenuItem(title, message, shortcut, modifiers),
|
||||||
|
fModel(*model),
|
||||||
|
fHeightDelta(0),
|
||||||
|
fDrawText(drawText),
|
||||||
|
fExtraPad(extraPad)
|
||||||
|
{
|
||||||
|
ThrowOnInitCheckError(&fModel);
|
||||||
|
// The 'fExtraPad' field is used to when this menu item is added to
|
||||||
|
// a menubar instead of a menu. Menus and MenuBars space out items
|
||||||
|
// differently (more space around items in a menu). This class wants
|
||||||
|
// to be able to space item the same, no matter where they are. The
|
||||||
|
// fExtraPad field allows for that.
|
||||||
|
|
||||||
|
if (model->IsRoot())
|
||||||
|
SetLabel(model->Name());
|
||||||
|
|
||||||
|
// ModelMenuItem is used in synchronously invoked menus, make sure
|
||||||
|
// we invoke with a timeout
|
||||||
|
SetTimeout(kSynchMenuInvokeTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModelMenuItem::ModelMenuItem(const Model *model, BMenu *menu, bool drawText,
|
||||||
|
bool extraPad)
|
||||||
|
: BMenuItem(menu),
|
||||||
|
fModel(*model),
|
||||||
|
fHeightDelta(0),
|
||||||
|
fDrawText(drawText),
|
||||||
|
fExtraPad(extraPad)
|
||||||
|
{
|
||||||
|
ThrowOnInitCheckError(&fModel);
|
||||||
|
// ModelMenuItem is used in synchronously invoked menus, make sure
|
||||||
|
// we invoke with a timeout
|
||||||
|
SetTimeout(kSynchMenuInvokeTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModelMenuItem::~ModelMenuItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ModelMenuItem::SetEntry(const BEntry *entry)
|
||||||
|
{
|
||||||
|
return fModel.SetTo(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ModelMenuItem::DrawContent()
|
||||||
|
{
|
||||||
|
if (fDrawText) {
|
||||||
|
BPoint drawPoint(ContentLocation());
|
||||||
|
drawPoint.x += 20 + (fExtraPad ? 6 : 0);
|
||||||
|
if (fHeightDelta > 0)
|
||||||
|
drawPoint.y += ceil(fHeightDelta / 2);
|
||||||
|
Menu()->MovePenTo(drawPoint);
|
||||||
|
_inherited::DrawContent();
|
||||||
|
}
|
||||||
|
DrawIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ModelMenuItem::Highlight(bool hilited)
|
||||||
|
{
|
||||||
|
_inherited::Highlight(hilited);
|
||||||
|
DrawIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
DimmedIconBlitter(BView *view, BPoint where, BBitmap *bitmap, void *)
|
||||||
|
{
|
||||||
|
view->SetDrawingMode(B_OP_BLEND);
|
||||||
|
view->DrawBitmap(bitmap, where);
|
||||||
|
view->SetDrawingMode(B_OP_OVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ModelMenuItem::DrawIcon()
|
||||||
|
{
|
||||||
|
Menu()->PushState();
|
||||||
|
|
||||||
|
BPoint where(ContentLocation());
|
||||||
|
// center icon with text.
|
||||||
|
|
||||||
|
float deltaHeight = fHeightDelta < 0 ? -fHeightDelta : 0;
|
||||||
|
where.y += ceil( deltaHeight/2 );
|
||||||
|
|
||||||
|
if (fExtraPad)
|
||||||
|
where.x += 6;
|
||||||
|
|
||||||
|
Menu()->SetDrawingMode(B_OP_OVER);
|
||||||
|
Menu()->SetLowColor(B_TRANSPARENT_32_BIT);
|
||||||
|
|
||||||
|
// draw small icon, synchronously
|
||||||
|
if (IsEnabled())
|
||||||
|
IconCache::sIconCache->Draw(fModel.ResolveIfLink(), Menu(), where,
|
||||||
|
kNormalIcon, B_MINI_ICON);
|
||||||
|
else {
|
||||||
|
// dimmed, for now use a special blitter; icon cache should
|
||||||
|
// know how to blit one eventually
|
||||||
|
IconCache::sIconCache->SyncDraw(fModel.ResolveIfLink(), Menu(), where,
|
||||||
|
kNormalIcon, B_MINI_ICON, DimmedIconBlitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu()->PopState();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ModelMenuItem::GetContentSize(float *width, float *height)
|
||||||
|
{
|
||||||
|
_inherited::GetContentSize(width, height);
|
||||||
|
fHeightDelta = 16 - *height;
|
||||||
|
if (*height < 16)
|
||||||
|
*height = 16;
|
||||||
|
*width = *width + 20 + (fExtraPad ? 18 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ModelMenuItem::Invoke(BMessage *message)
|
||||||
|
{
|
||||||
|
if (!Menu())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (!IsEnabled())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (!message)
|
||||||
|
message = Message();
|
||||||
|
|
||||||
|
if (!message)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BMessage clone(*message);
|
||||||
|
clone.AddInt32("index", Menu()->IndexOf(this));
|
||||||
|
clone.AddInt64("when", system_time());
|
||||||
|
clone.AddPointer("source", this);
|
||||||
|
|
||||||
|
if ((modifiers() & B_OPTION_KEY) == 0)
|
||||||
|
// if option not held, remove refs to close to prevent closing
|
||||||
|
// parent window
|
||||||
|
clone.RemoveData("nodeRefsToClose");
|
||||||
|
|
||||||
|
return BInvoker::Invoke(&clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
SpecialModelMenuItem::SpecialModelMenuItem(const Model *model,BMenu *menu)
|
||||||
|
: ModelMenuItem(model,menu)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SpecialModelMenuItem::DrawContent()
|
||||||
|
{
|
||||||
|
Menu()->PushState();
|
||||||
|
|
||||||
|
BFont font;
|
||||||
|
Menu()->GetFont(&font);
|
||||||
|
font.SetFace(B_ITALIC_FACE);
|
||||||
|
Menu()->SetFont(&font);
|
||||||
|
|
||||||
|
_inherited::DrawContent();
|
||||||
|
Menu()->PopState();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
IconMenuItem::IconMenuItem(const char *label, BMessage *message, BBitmap *icon)
|
||||||
|
: PositionPassingMenuItem(label, message),
|
||||||
|
fDeviceIcon(icon)
|
||||||
|
{
|
||||||
|
// IconMenuItem is used in synchronously invoked menus, make sure
|
||||||
|
// we invoke with a timeout
|
||||||
|
SetTimeout(kSynchMenuInvokeTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IconMenuItem::IconMenuItem(const char *label, BMessage *message,
|
||||||
|
const BNodeInfo *nodeInfo, icon_size which)
|
||||||
|
: PositionPassingMenuItem(label, message),
|
||||||
|
fDeviceIcon(NULL)
|
||||||
|
{
|
||||||
|
if (nodeInfo) {
|
||||||
|
fDeviceIcon = new BBitmap(BRect(0, 0, which - 1, which - 1), B_COLOR_8_BIT);
|
||||||
|
if (nodeInfo->GetTrackerIcon(fDeviceIcon, B_MINI_ICON)) {
|
||||||
|
delete fDeviceIcon;
|
||||||
|
fDeviceIcon = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IconMenuItem is used in synchronously invoked menus, make sure
|
||||||
|
// we invoke with a timeout
|
||||||
|
SetTimeout(kSynchMenuInvokeTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IconMenuItem::IconMenuItem(const char *label, BMessage *message,
|
||||||
|
const char *iconType, icon_size which)
|
||||||
|
: PositionPassingMenuItem(label, message),
|
||||||
|
fDeviceIcon(NULL)
|
||||||
|
{
|
||||||
|
BMimeType mime(iconType);
|
||||||
|
fDeviceIcon = new BBitmap(BRect(0, 0, which - 1, which - 1), B_COLOR_8_BIT);
|
||||||
|
|
||||||
|
if (mime.GetIcon(fDeviceIcon, which) != B_OK) {
|
||||||
|
delete fDeviceIcon;
|
||||||
|
fDeviceIcon = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IconMenuItem is used in synchronously invoked menus, make sure
|
||||||
|
// we invoke with a timeout
|
||||||
|
SetTimeout(kSynchMenuInvokeTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IconMenuItem::IconMenuItem(BMenu *submenu, BMessage *message,
|
||||||
|
const char *iconType, icon_size which)
|
||||||
|
: PositionPassingMenuItem(submenu, message),
|
||||||
|
fDeviceIcon(NULL)
|
||||||
|
{
|
||||||
|
BMimeType mime(iconType);
|
||||||
|
fDeviceIcon = new BBitmap(BRect(0, 0, which - 1, which - 1), B_COLOR_8_BIT);
|
||||||
|
|
||||||
|
if (mime.GetIcon(fDeviceIcon, which) != B_OK) {
|
||||||
|
delete fDeviceIcon;
|
||||||
|
fDeviceIcon = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IconMenuItem is used in synchronously invoked menus, make sure
|
||||||
|
// we invoke with a timeout
|
||||||
|
SetTimeout(kSynchMenuInvokeTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IconMenuItem::~IconMenuItem()
|
||||||
|
{
|
||||||
|
delete fDeviceIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
IconMenuItem::GetContentSize(float *width, float *height)
|
||||||
|
{
|
||||||
|
_inherited::GetContentSize(width, height);
|
||||||
|
*width += 20;
|
||||||
|
*height += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
IconMenuItem::DrawContent()
|
||||||
|
{
|
||||||
|
BPoint drawPoint(ContentLocation());
|
||||||
|
drawPoint.x += 20;
|
||||||
|
Menu()->MovePenTo(drawPoint);
|
||||||
|
_inherited::DrawContent();
|
||||||
|
|
||||||
|
BPoint where(ContentLocation());
|
||||||
|
where.y = Frame().top;
|
||||||
|
|
||||||
|
if (fDeviceIcon) {
|
||||||
|
if (IsEnabled())
|
||||||
|
Menu()->SetDrawingMode(B_OP_OVER);
|
||||||
|
else
|
||||||
|
Menu()->SetDrawingMode(B_OP_BLEND);
|
||||||
|
|
||||||
|
Menu()->DrawBitmapAsync(fDeviceIcon, where);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Menu item class with small icons.
|
||||||
|
|
||||||
|
#ifndef ICON_MENU_ITEM_H
|
||||||
|
#define ICON_MENU_ITEM_H
|
||||||
|
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include "Model.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
class BNodeInfo;
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
const bigtime_t kSynchMenuInvokeTimeout = 5000000;
|
||||||
|
|
||||||
|
class IconMenuItem : public PositionPassingMenuItem {
|
||||||
|
public:
|
||||||
|
IconMenuItem(const char *, BMessage *, BBitmap *);
|
||||||
|
IconMenuItem(const char *, BMessage *, const char *iconType, icon_size which);
|
||||||
|
IconMenuItem(const char *, BMessage *, const BNodeInfo *nodeInfo, icon_size which);
|
||||||
|
IconMenuItem(BMenu *, BMessage *, const char *iconType, icon_size which);
|
||||||
|
virtual ~IconMenuItem();
|
||||||
|
|
||||||
|
virtual void GetContentSize(float *width, float *height);
|
||||||
|
virtual void DrawContent();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BBitmap *fDeviceIcon;
|
||||||
|
|
||||||
|
typedef BMenuItem _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ModelMenuItem : public BMenuItem {
|
||||||
|
public:
|
||||||
|
ModelMenuItem(const Model *, const char *title, BMessage *, char shortcut = '\0',
|
||||||
|
uint32 modifiers = 0, bool drawText = true, bool extraPad = false);
|
||||||
|
ModelMenuItem(const Model *, BMenu *, bool drawText = true, bool extraPad = false);
|
||||||
|
virtual ~ModelMenuItem();
|
||||||
|
|
||||||
|
virtual status_t SetEntry(const BEntry *);
|
||||||
|
virtual void DrawContent();
|
||||||
|
virtual void Highlight(bool isHighlighted);
|
||||||
|
virtual void GetContentSize(float *width, float *height);
|
||||||
|
|
||||||
|
const Model *TargetModel() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual status_t Invoke(BMessage * = NULL);
|
||||||
|
// overriden to support B_OPTION_KEY
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DrawIcon();
|
||||||
|
|
||||||
|
Model fModel;
|
||||||
|
float fHeightDelta;
|
||||||
|
bool fDrawText;
|
||||||
|
bool fExtraPad;
|
||||||
|
|
||||||
|
typedef BMenuItem _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline const Model *
|
||||||
|
ModelMenuItem::TargetModel() const
|
||||||
|
{
|
||||||
|
return &fModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SpecialModelMenuItem : public ModelMenuItem {
|
||||||
|
public:
|
||||||
|
SpecialModelMenuItem(const Model *model,BMenu *menu);
|
||||||
|
|
||||||
|
virtual void DrawContent();
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef ModelMenuItem _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
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 INFO_WINDOW_H
|
||||||
|
#define INFO_WINDOW_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
#include <Window.h>
|
||||||
|
#include <MessageFilter.h>
|
||||||
|
|
||||||
|
#include "DialogPane.h"
|
||||||
|
#include "FilePermissionsView.h"
|
||||||
|
#include "LockingList.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
class BMenuField;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class Model;
|
||||||
|
class AttributeView;
|
||||||
|
class TrackingView;
|
||||||
|
|
||||||
|
// States for tracking the mouse
|
||||||
|
enum track_state {
|
||||||
|
no_track = 0,
|
||||||
|
link_track,
|
||||||
|
path_track,
|
||||||
|
icon_track,
|
||||||
|
size_track,
|
||||||
|
open_only_track // This is for items that can be opened, but can't be
|
||||||
|
// drag and dropped or renamed (Trash, Desktop Folder...)
|
||||||
|
};
|
||||||
|
|
||||||
|
class TrackingView : public BControl {
|
||||||
|
public:
|
||||||
|
TrackingView(BRect, const char *str, const BFont *font, BMessage *message);
|
||||||
|
|
||||||
|
virtual void MouseDown(BPoint);
|
||||||
|
virtual void MouseMoved(BPoint, uint32 transit, const BMessage *message);
|
||||||
|
virtual void MouseUp(BPoint);
|
||||||
|
virtual void Draw(BRect);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool fMouseDown;
|
||||||
|
bool fMouseInView;
|
||||||
|
BFont fFont;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeView : public BView {
|
||||||
|
public:
|
||||||
|
AttributeView(BRect, Model *);
|
||||||
|
~AttributeView();
|
||||||
|
|
||||||
|
void ModelChanged(Model *, BMessage *);
|
||||||
|
void ReLinkTargetModel(Model *);
|
||||||
|
void BeginEditingTitle();
|
||||||
|
void FinishEditingTitle(bool);
|
||||||
|
float CurrentFontHeight(float size = -1);
|
||||||
|
|
||||||
|
BTextView *TextView() const { return fTitleEditView; }
|
||||||
|
|
||||||
|
static filter_result TextViewFilter(BMessage *, BHandler **, BMessageFilter *);
|
||||||
|
|
||||||
|
off_t LastSize() const;
|
||||||
|
void SetLastSize(off_t);
|
||||||
|
|
||||||
|
void SetSizeStr(const char *);
|
||||||
|
|
||||||
|
status_t BuildContextMenu(BMenu *parent);
|
||||||
|
|
||||||
|
void SetPermissionsSwitchState(int32 state);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void MouseDown(BPoint);
|
||||||
|
virtual void MouseMoved(BPoint, uint32, const BMessage *);
|
||||||
|
virtual void MouseUp(BPoint);
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void Draw(BRect);
|
||||||
|
virtual void Pulse();
|
||||||
|
virtual void MakeFocus(bool);
|
||||||
|
virtual void WindowActivated(bool);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitStrings(const Model *);
|
||||||
|
void CheckAndSetSize();
|
||||||
|
void OpenLinkSource();
|
||||||
|
void OpenLinkTarget();
|
||||||
|
|
||||||
|
BString fPathStr;
|
||||||
|
BString fLinkToStr;
|
||||||
|
BString fSizeStr;
|
||||||
|
BString fModifiedStr;
|
||||||
|
BString fCreatedStr;
|
||||||
|
BString fKindStr;
|
||||||
|
BString fDescStr;
|
||||||
|
|
||||||
|
off_t fFreeBytes;
|
||||||
|
off_t fLastSize;
|
||||||
|
|
||||||
|
BRect fPathRect;
|
||||||
|
BRect fLinkRect;
|
||||||
|
BRect fDescRect;
|
||||||
|
BRect fTitleRect;
|
||||||
|
BRect fIconRect;
|
||||||
|
BRect fSizeRect;
|
||||||
|
BPoint fClickPoint;
|
||||||
|
float fDivider;
|
||||||
|
|
||||||
|
BMenuField *fPreferredAppMenu;
|
||||||
|
Model *fModel;
|
||||||
|
Model *fIconModel;
|
||||||
|
BBitmap *fIcon;
|
||||||
|
bool fMouseDown;
|
||||||
|
bool fDragging;
|
||||||
|
bool fDoubleClick;
|
||||||
|
track_state fTrackingState;
|
||||||
|
bool fIsDropTarget;
|
||||||
|
BTextView *fTitleEditView;
|
||||||
|
PaneSwitch *fPermissionsSwitch;
|
||||||
|
BWindow *fPathWindow;
|
||||||
|
BWindow *fLinkWindow;
|
||||||
|
BWindow *fDescWindow;
|
||||||
|
|
||||||
|
typedef BView _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BInfoWindow : public BWindow {
|
||||||
|
public:
|
||||||
|
BInfoWindow(Model *, int32 groupIndex, LockingList<BWindow> *list = NULL);
|
||||||
|
~BInfoWindow();
|
||||||
|
|
||||||
|
virtual bool IsShowing(const node_ref *) const;
|
||||||
|
Model *TargetModel() const;
|
||||||
|
void SetSizeStr(const char *);
|
||||||
|
bool StopCalc();
|
||||||
|
void OpenFilePanel(const entry_ref *);
|
||||||
|
|
||||||
|
static void GetSizeString(BString &result, off_t size, int32 fileCount);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void Quit();
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
virtual void Show();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static BRect InfoWindowRect(bool displayingSymlink);
|
||||||
|
static int32 CalcSize(void *);
|
||||||
|
|
||||||
|
Model *fModel;
|
||||||
|
volatile bool fStopCalc;
|
||||||
|
int32 fIndex; // tells where it lives with respect to other
|
||||||
|
thread_id fCalcThreadID;
|
||||||
|
LockingList<BWindow> *fWindowList;
|
||||||
|
FilePermissionsView *fPermissionsView;
|
||||||
|
AttributeView *fAttributeView;
|
||||||
|
BFilePanel *fFilePanel;
|
||||||
|
bool fFilePanelOpen;
|
||||||
|
|
||||||
|
typedef BWindow _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BInfoWindow::StopCalc()
|
||||||
|
{
|
||||||
|
return fStopCalc;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Model *
|
||||||
|
BInfoWindow::TargetModel() const
|
||||||
|
{
|
||||||
|
return fModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
SubDir OBOS_TOP src kits tracker ;
|
||||||
|
|
||||||
|
UsePrivateHeaders shared ;
|
||||||
|
UsePrivateHeaders tracker ;
|
||||||
|
|
||||||
|
AddResources libtracker.so : TrackerIcons.rdef ;
|
||||||
|
|
||||||
|
SubDirC++Flags
|
||||||
|
-D_BUILDING_tracker=1 -DOPEN_TRACKER=1
|
||||||
|
# -D_INCLUDES_CLASS_DEVICE_MAP=1
|
||||||
|
-D_SUPPORTS_RESOURCES=1
|
||||||
|
-D_SUPPORTS_FEATURE_SCRIPTING=1
|
||||||
|
# -D_SILENTLY_CORRECT_FILE_NAMES=1
|
||||||
|
;
|
||||||
|
|
||||||
|
SharedLibrary tracker :
|
||||||
|
AttributeStream.cpp
|
||||||
|
AutoMounter.cpp
|
||||||
|
AutoMounterSettings.cpp
|
||||||
|
BackgroundImage.cpp
|
||||||
|
Bitmaps.cpp
|
||||||
|
ContainerWindow.cpp
|
||||||
|
CountView.cpp
|
||||||
|
DeskWindow.cpp
|
||||||
|
DesktopPoseView.cpp
|
||||||
|
DialogPane.cpp
|
||||||
|
DirMenu.cpp
|
||||||
|
EntryIterator.cpp
|
||||||
|
FBCPadding.cpp
|
||||||
|
FSClipboard.cpp
|
||||||
|
FSUndoRedo.cpp
|
||||||
|
FSUtils.cpp
|
||||||
|
FavoritesConfig.cpp
|
||||||
|
FavoritesMenu.cpp
|
||||||
|
FilePanel.cpp
|
||||||
|
FilePanelPriv.cpp
|
||||||
|
FilePermissionsView.cpp
|
||||||
|
FindPanel.cpp
|
||||||
|
GroupedMenu.cpp
|
||||||
|
IconCache.cpp
|
||||||
|
IconMenuItem.cpp
|
||||||
|
InfoWindow.cpp
|
||||||
|
MimeTypeList.cpp
|
||||||
|
MiniMenuField.cpp
|
||||||
|
Model.cpp
|
||||||
|
MountMenu.cpp
|
||||||
|
Navigator.cpp
|
||||||
|
NavMenu.cpp
|
||||||
|
NodePreloader.cpp
|
||||||
|
NodeWalker.cpp
|
||||||
|
OpenWithWindow.cpp
|
||||||
|
OverrideAlert.cpp
|
||||||
|
PendingNodeMonitorCache.cpp
|
||||||
|
Pose.cpp
|
||||||
|
PoseList.cpp
|
||||||
|
PoseView.cpp
|
||||||
|
PoseViewScripting.cpp
|
||||||
|
QueryContainerWindow.cpp
|
||||||
|
QueryPoseView.cpp
|
||||||
|
RecentItems.cpp
|
||||||
|
RegExp.cpp
|
||||||
|
SelectionWindow.cpp
|
||||||
|
Settings.cpp
|
||||||
|
SettingsHandler.cpp
|
||||||
|
SettingsViews.cpp
|
||||||
|
SlowContextPopup.cpp
|
||||||
|
SlowMenu.cpp
|
||||||
|
StatusWindow.cpp
|
||||||
|
TaskLoop.cpp
|
||||||
|
TemplatesMenu.cpp
|
||||||
|
Tests.cpp
|
||||||
|
TextWidget.cpp
|
||||||
|
Thread.cpp
|
||||||
|
TitleView.cpp
|
||||||
|
Tracker.cpp
|
||||||
|
TrackerInitialState.cpp
|
||||||
|
TrackerScripting.cpp
|
||||||
|
TrackerSettings.cpp
|
||||||
|
TrackerSettingsWindow.cpp
|
||||||
|
TrackerString.cpp
|
||||||
|
TrashWatcher.cpp
|
||||||
|
Utilities.cpp
|
||||||
|
ViewState.cpp
|
||||||
|
VolumeWindow.cpp
|
||||||
|
WidgetAttributeText.cpp
|
||||||
|
;
|
||||||
|
|
||||||
|
LinkSharedOSLibs libtracker.so : libroot.so libbe.so libtranslation.so ;
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
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 _LOCKING_LIST_H
|
||||||
|
#define _LOCKING_LIST_H
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class LockingList : public BObjectList<T> {
|
||||||
|
public:
|
||||||
|
LockingList(int32 itemsPerBlock = 20, bool owning = false);
|
||||||
|
~LockingList()
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lock();
|
||||||
|
void Unlock();
|
||||||
|
bool IsLocked() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BLocker lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
LockingList<T>::LockingList(int32 itemsPerBlock, bool owning)
|
||||||
|
: BObjectList<T>(itemsPerBlock, owning)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
bool
|
||||||
|
LockingList<T>::Lock()
|
||||||
|
{
|
||||||
|
return lock.Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void
|
||||||
|
LockingList<T>::Unlock()
|
||||||
|
{
|
||||||
|
lock.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
bool
|
||||||
|
LockingList<T>::IsLocked() const
|
||||||
|
{
|
||||||
|
return lock.IsLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Mime.h>
|
||||||
|
|
||||||
|
#include "AutoLock.h"
|
||||||
|
#include "MimeTypeList.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
|
||||||
|
|
||||||
|
ShortMimeInfo::ShortMimeInfo(const BMimeType &mimeType)
|
||||||
|
: fCommonMimeType(true)
|
||||||
|
{
|
||||||
|
fPrivateName = mimeType.Type();
|
||||||
|
|
||||||
|
char buffer[B_MIME_TYPE_LENGTH];
|
||||||
|
|
||||||
|
// weed out apps - their preferred handler is themselves
|
||||||
|
if (mimeType.GetPreferredApp(buffer) == B_OK
|
||||||
|
&& fPrivateName.ICompare(buffer) == 0)
|
||||||
|
fCommonMimeType = false;
|
||||||
|
|
||||||
|
// weed out metamimes without a short description
|
||||||
|
if (mimeType.GetShortDescription(buffer) != B_OK || buffer[0] == 0)
|
||||||
|
fCommonMimeType = false;
|
||||||
|
else
|
||||||
|
fShortDescription = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ShortMimeInfo::ShortMimeInfo(const char *shortDescription)
|
||||||
|
: fShortDescription(shortDescription)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
ShortMimeInfo::InternalName() const
|
||||||
|
{
|
||||||
|
return fPrivateName.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
ShortMimeInfo::ShortDescription() const
|
||||||
|
{
|
||||||
|
return fShortDescription.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ShortMimeInfo::CompareShortDescription(const ShortMimeInfo *a, const ShortMimeInfo *b)
|
||||||
|
{
|
||||||
|
return a->fShortDescription.ICompare(b->fShortDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ShortMimeInfo::IsCommonMimeType() const
|
||||||
|
{
|
||||||
|
return fCommonMimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
MimeTypeList::MimeTypeList()
|
||||||
|
: fMimeList(100, true),
|
||||||
|
fCommonMimeList(30, false),
|
||||||
|
fLock("mimeListLock")
|
||||||
|
{
|
||||||
|
fLock.Lock();
|
||||||
|
Thread::Launch(NewMemberFunctionObject(&MimeTypeList::Build, this),
|
||||||
|
B_NORMAL_PRIORITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
MatchOneShortDescription(const ShortMimeInfo *a, const ShortMimeInfo *b)
|
||||||
|
{
|
||||||
|
return strcasecmp(a->ShortDescription(), b->ShortDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
const ShortMimeInfo *
|
||||||
|
MimeTypeList::FindMimeType(const char *shortDescription) const
|
||||||
|
{
|
||||||
|
ShortMimeInfo tmp(shortDescription);
|
||||||
|
const ShortMimeInfo *result = fCommonMimeList.BinarySearch(tmp,
|
||||||
|
&MatchOneShortDescription);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ShortMimeInfo *
|
||||||
|
MimeTypeList::EachCommonType(bool (*func)(const ShortMimeInfo *, void *),
|
||||||
|
void *state) const
|
||||||
|
{
|
||||||
|
AutoLock<Benaphore> locker(fLock);
|
||||||
|
int32 count = fCommonMimeList.CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++) {
|
||||||
|
if ((func)(fCommonMimeList.ItemAt(index), state))
|
||||||
|
return fCommonMimeList.ItemAt(index);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MimeTypeList::Build()
|
||||||
|
{
|
||||||
|
ASSERT(fLock.IsLocked());
|
||||||
|
|
||||||
|
BMessage message;
|
||||||
|
BMimeType::GetInstalledTypes(&message);
|
||||||
|
|
||||||
|
int32 count;
|
||||||
|
uint32 type;
|
||||||
|
message.GetInfo("types", &type, &count);
|
||||||
|
|
||||||
|
for (int32 index = 0; index < count; index++) {
|
||||||
|
const char *str;
|
||||||
|
if (message.FindString("types", index, &str) != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BMimeType mimetype(str);
|
||||||
|
if (mimetype.InitCheck() != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ShortMimeInfo *mimeInfo = new ShortMimeInfo(mimetype);
|
||||||
|
fMimeList.AddItem(mimeInfo);
|
||||||
|
if (mimeInfo->IsCommonMimeType())
|
||||||
|
fCommonMimeList.AddItem(mimeInfo);
|
||||||
|
}
|
||||||
|
fCommonMimeList.SortItems(&ShortMimeInfo::CompareShortDescription);
|
||||||
|
fLock.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
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 __MIME_TYPE_LIST__
|
||||||
|
#define __MIME_TYPE_LIST__
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
#include "ObjectList.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class MimeTypeList;
|
||||||
|
|
||||||
|
class ShortMimeInfo {
|
||||||
|
public:
|
||||||
|
ShortMimeInfo(const BMimeType &);
|
||||||
|
|
||||||
|
const char *InternalName() const;
|
||||||
|
const char *ShortDescription() const;
|
||||||
|
bool IsCommonMimeType() const;
|
||||||
|
static int CompareShortDescription(const ShortMimeInfo *,
|
||||||
|
const ShortMimeInfo *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ShortMimeInfo(const char *shortDescription);
|
||||||
|
|
||||||
|
BString fPrivateName;
|
||||||
|
BString fShortDescription;
|
||||||
|
bool fCommonMimeType;
|
||||||
|
|
||||||
|
friend class MimeTypeList;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MimeTypeList {
|
||||||
|
public:
|
||||||
|
MimeTypeList();
|
||||||
|
|
||||||
|
// attributes for type
|
||||||
|
// internal name from short description
|
||||||
|
// update notification
|
||||||
|
|
||||||
|
const ShortMimeInfo *FindMimeType(const char *shortDescription) const;
|
||||||
|
const ShortMimeInfo *EachCommonType(bool (*)(const ShortMimeInfo *, void *),
|
||||||
|
void *) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Build();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BObjectList<ShortMimeInfo> fMimeList;
|
||||||
|
BObjectList<ShortMimeInfo> fCommonMimeList;
|
||||||
|
mutable Benaphore fLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
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 _MIME_TYPES_H
|
||||||
|
#define _MIME_TYPES_H
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
#define B_FILE_MIMETYPE "application/octet-stream"
|
||||||
|
#define B_DIR_MIMETYPE "application/x-vnd.Be-directory"
|
||||||
|
#define B_VOLUME_MIMETYPE "application/x-vnd.Be-volume"
|
||||||
|
#define B_QUERY_MIMETYPE "application/x-vnd.Be-query"
|
||||||
|
#define B_QUERY_TEMPLATE_MIMETYPE "application/x-vnd.Be-queryTemplate"
|
||||||
|
#define B_LINK_MIMETYPE "application/x-vnd.Be-symlink"
|
||||||
|
#define B_ROOT_MIMETYPE "application/x-vnd.Be-root"
|
||||||
|
#define B_BOOKMARK_MIMETYPE "application/x-vnd.Be-bookmark"
|
||||||
|
#define B_PERSON_MIMETYPE "application/x-person"
|
||||||
|
|
||||||
|
#define B_PRINTER_MIMETYPE "application/x-vnd.Be.printer"
|
||||||
|
#define B_PRINTER_SPOOL_MIMETYPE "application/x-vnd.Be.printer-spool"
|
||||||
|
|
||||||
|
#define kPlainTextMimeType "text/plain"
|
||||||
|
|
||||||
|
#define kBitmapMimeType "image/x-vnd.Be-bitmap"
|
||||||
|
#define kLargeIconType "icon/large"
|
||||||
|
#define kMiniIconType "icon/mini"
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "MiniMenuField.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
MiniMenuField::MiniMenuField(BRect frame, const char *name, BPopUpMenu *menu,
|
||||||
|
uint32 resizeFlags, uint32 flags)
|
||||||
|
: BView(frame, name, resizeFlags, flags),
|
||||||
|
fMenu(menu)
|
||||||
|
{
|
||||||
|
SetFont(be_plain_font, B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
MiniMenuField::~MiniMenuField()
|
||||||
|
{
|
||||||
|
delete fMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MiniMenuField::AttachedToWindow()
|
||||||
|
{
|
||||||
|
if (Parent()) {
|
||||||
|
SetViewColor(Parent()->ViewColor());
|
||||||
|
SetLowColor(Parent()->ViewColor());
|
||||||
|
}
|
||||||
|
SetHighColor(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MiniMenuField::MakeFocus(bool on)
|
||||||
|
{
|
||||||
|
Invalidate();
|
||||||
|
BView::MakeFocus(on);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MiniMenuField::KeyDown(const char *bytes, int32 numBytes)
|
||||||
|
{
|
||||||
|
switch (bytes[0]) {
|
||||||
|
case B_SPACE:
|
||||||
|
case B_DOWN_ARROW:
|
||||||
|
case B_RIGHT_ARROW:
|
||||||
|
// invoke from keyboard
|
||||||
|
fMenu->Go(ConvertToScreen(BPoint(4, 4)), true, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BView::KeyDown(bytes, numBytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MiniMenuField::Draw(BRect)
|
||||||
|
{
|
||||||
|
BRect bounds(Bounds());
|
||||||
|
bounds.InsetBy(2, 2);
|
||||||
|
BRect rect(bounds);
|
||||||
|
rect.right--;
|
||||||
|
rect.bottom--;
|
||||||
|
|
||||||
|
rgb_color darkest = tint_color(kBlack, 0.6f);
|
||||||
|
rgb_color dark = tint_color(kBlack, 0.4f);
|
||||||
|
rgb_color medium = dark;
|
||||||
|
rgb_color light = tint_color(kBlack, 0.03f);
|
||||||
|
|
||||||
|
SetHighColor(medium);
|
||||||
|
|
||||||
|
// draw frame and shadow
|
||||||
|
BeginLineArray(10);
|
||||||
|
AddLine(rect.RightTop(), rect.RightBottom(), darkest);
|
||||||
|
AddLine(rect.RightBottom(), rect.LeftBottom(), darkest);
|
||||||
|
AddLine(rect.LeftBottom(), rect.LeftTop(), medium);
|
||||||
|
AddLine(rect.LeftTop(), rect.RightTop(), medium);
|
||||||
|
AddLine(bounds.LeftBottom() + BPoint(2, 0), bounds.RightBottom(), dark);
|
||||||
|
AddLine(bounds.RightTop() + BPoint(0, 1), bounds.RightBottom(), dark);
|
||||||
|
rect.InsetBy(1, 1);
|
||||||
|
AddLine(rect.RightTop(), rect.RightBottom(), medium);
|
||||||
|
AddLine(rect.RightBottom(), rect.LeftBottom(), medium);
|
||||||
|
AddLine(rect.LeftBottom(), rect.LeftTop(), light);
|
||||||
|
AddLine(rect.LeftTop(), rect.RightTop(), light);
|
||||||
|
|
||||||
|
EndLineArray();
|
||||||
|
|
||||||
|
// draw triangle
|
||||||
|
rect = BRect(5, 5, 15, 15);
|
||||||
|
const rgb_color outlineColor = kBlack;
|
||||||
|
const rgb_color middleColor = {150, 150, 150, 255};
|
||||||
|
|
||||||
|
BeginLineArray(5);
|
||||||
|
AddLine(BPoint(rect.left + 3, rect.top + 1),
|
||||||
|
BPoint(rect.left + 3, rect.top + 7), outlineColor);
|
||||||
|
AddLine(BPoint(rect.left + 3, rect.top + 1),
|
||||||
|
BPoint(rect.left + 6, rect.top + 4), outlineColor);
|
||||||
|
AddLine(BPoint(rect.left + 6, rect.top + 4),
|
||||||
|
BPoint(rect.left + 3, rect.top + 7), outlineColor);
|
||||||
|
|
||||||
|
AddLine(BPoint(rect.left + 4, rect.top + 3),
|
||||||
|
BPoint(rect.left + 4, rect.top + 5), middleColor);
|
||||||
|
AddLine(BPoint(rect.left + 5, rect.top + 4),
|
||||||
|
BPoint(rect.left + 5, rect.top + 4), middleColor);
|
||||||
|
EndLineArray();
|
||||||
|
|
||||||
|
// draw focus if focused, else erase focus
|
||||||
|
bounds = Bounds();
|
||||||
|
bool focused = IsFocus() && Window()->IsActive();
|
||||||
|
rgb_color markColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
|
||||||
|
rgb_color viewColor = ViewColor();
|
||||||
|
BeginLineArray(4);
|
||||||
|
AddLine(BPoint(bounds.left, bounds.top),
|
||||||
|
BPoint(bounds.right, bounds.top), focused ? markColor : viewColor);
|
||||||
|
AddLine(BPoint(bounds.right, bounds.top),
|
||||||
|
BPoint(bounds.right, bounds.bottom), focused ? markColor : viewColor);
|
||||||
|
AddLine(BPoint(bounds.right, bounds.bottom),
|
||||||
|
BPoint(bounds.left, bounds.bottom), focused ? markColor : viewColor);
|
||||||
|
AddLine(BPoint(bounds.left, bounds.bottom),
|
||||||
|
BPoint(bounds.left, bounds.top), focused ? markColor : viewColor);
|
||||||
|
EndLineArray();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MiniMenuField::MouseDown(BPoint)
|
||||||
|
{
|
||||||
|
fMenu->Go(ConvertToScreen(BPoint(4, 4)), true);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
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 __MINI_MENU_FIELD__
|
||||||
|
#define __MINI_MENU_FIELD__
|
||||||
|
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
class BPopUpMenu;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
|
||||||
|
class MiniMenuField : public BView {
|
||||||
|
public:
|
||||||
|
MiniMenuField(BRect frame, const char *name, BPopUpMenu *menu,
|
||||||
|
uint32 resizeFlags = B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||||
|
uint32 flags = B_WILL_DRAW | B_NAVIGABLE);
|
||||||
|
// ToDo:
|
||||||
|
// use BMenu instead of BPopUpMenu here
|
||||||
|
|
||||||
|
virtual ~MiniMenuField();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void Draw(BRect);
|
||||||
|
virtual void MouseDown(BPoint );
|
||||||
|
virtual void MakeFocus(bool);
|
||||||
|
virtual void KeyDown(const char *, int32);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BPopUpMenu *fMenu;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,473 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Dedicated to BModel
|
||||||
|
|
||||||
|
#ifndef _NU_MODEL_H
|
||||||
|
#define _NU_MODEL_H
|
||||||
|
|
||||||
|
#include <AppFileInfo.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
|
||||||
|
// using std::stat instead of just stat here because of what
|
||||||
|
// seems to be a gcc bug involving namespace and struct stat interaction
|
||||||
|
typedef struct std::stat StatStruct;
|
||||||
|
#else
|
||||||
|
// on mwcc std isn't turned on but there is no bug either.
|
||||||
|
// Also seems to be fixed in gcc 3.
|
||||||
|
typedef struct stat StatStruct;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kDoesNotSupportType,
|
||||||
|
kSuperhandlerModel,
|
||||||
|
kModelSupportsSupertype,
|
||||||
|
kModelSupportsType,
|
||||||
|
kModelSupportsFile
|
||||||
|
};
|
||||||
|
|
||||||
|
class Model {
|
||||||
|
public:
|
||||||
|
Model();
|
||||||
|
Model(const Model &);
|
||||||
|
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 *compareModel) const;
|
||||||
|
|
||||||
|
// node management
|
||||||
|
status_t OpenNode(bool writable = false);
|
||||||
|
// also used to switch from read-only to writable
|
||||||
|
void CloseNode();
|
||||||
|
bool IsNodeOpen() const;
|
||||||
|
bool IsNodeOpenForWriting() const;
|
||||||
|
|
||||||
|
status_t UpdateStatAndOpenNode(bool writable = false);
|
||||||
|
// like OpenNode, called on zombie poses to check if they turned
|
||||||
|
// real, starts by rereading the stat structure
|
||||||
|
|
||||||
|
// basic getters
|
||||||
|
const char *Name() const;
|
||||||
|
const entry_ref *EntryRef() const;
|
||||||
|
const node_ref *NodeRef() const;
|
||||||
|
const StatStruct *StatBuf() const;
|
||||||
|
|
||||||
|
BNode *Node() const;
|
||||||
|
// returns null if not Open
|
||||||
|
void GetPath(BPath *) const;
|
||||||
|
void GetEntry(BEntry *) const;
|
||||||
|
|
||||||
|
const char *MimeType() const;
|
||||||
|
const char *PreferredAppSignature() const;
|
||||||
|
// only not-null if not default for type and not self for app
|
||||||
|
void SetPreferredAppSignature(const char *);
|
||||||
|
|
||||||
|
void GetPreferredAppForBrokenSymLink(BString &result);
|
||||||
|
// special purpose call - if a symlink is unresolvable, it makes sense
|
||||||
|
// to be able to get at it's preferred handler which may be different
|
||||||
|
// from the Tracker. Used by the network neighborhood.
|
||||||
|
|
||||||
|
// type getters
|
||||||
|
bool IsFile() const;
|
||||||
|
bool IsDirectory() const;
|
||||||
|
bool IsQuery() const;
|
||||||
|
bool IsQueryTemplate() const;
|
||||||
|
bool IsContainer() const;
|
||||||
|
bool IsExecutable() const;
|
||||||
|
bool IsSymLink() const;
|
||||||
|
bool IsRoot() const;
|
||||||
|
bool IsVolume() const;
|
||||||
|
|
||||||
|
IconSource IconFrom() const;
|
||||||
|
void SetIconFrom(IconSource);
|
||||||
|
// where is this model getting it's icon from
|
||||||
|
|
||||||
|
void ResetIconFrom();
|
||||||
|
// called from the attribute changed calls to force a lookup of
|
||||||
|
// a new icon
|
||||||
|
|
||||||
|
// symlink handling calls, mainly used by the IconCache
|
||||||
|
const Model *ResolveIfLink() const;
|
||||||
|
Model *ResolveIfLink();
|
||||||
|
// works on anything
|
||||||
|
Model *LinkTo() const;
|
||||||
|
// fast, works only on symlinks
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Node monitor update call
|
||||||
|
void UpdateEntryRef(const node_ref *dirRef, const char *name);
|
||||||
|
bool AttrChanged(const char *);
|
||||||
|
// returns true if pose needs to update it's icon, etc.
|
||||||
|
// pass null to force full update
|
||||||
|
bool StatChanged();
|
||||||
|
// returns true if pose needs to update it's icon
|
||||||
|
|
||||||
|
status_t WatchVolumeAndMountPoint(uint32, BHandler *);
|
||||||
|
// correctly handles boot volume name watching
|
||||||
|
|
||||||
|
bool IsDropTarget(const Model *forDocument = 0,
|
||||||
|
bool traverse = false) const;
|
||||||
|
// if nonzero <forDocument> passed, mime info is used to
|
||||||
|
// resolve if document can be opened
|
||||||
|
// if zero, all executables, directories and volumes pass
|
||||||
|
// if traverse, dereference symlinks
|
||||||
|
bool IsDropTargetForList(const BObjectList<BString> *list) const;
|
||||||
|
// <list> contains mime types of all documents about to be handled
|
||||||
|
// by model
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
void PrintToStream(int32 level = 1, bool deep = false);
|
||||||
|
void TrackIconSource(icon_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool IsSuperHandler() const;
|
||||||
|
int32 SupportsMimeType(const char *type, const BObjectList<BString> *list,
|
||||||
|
bool exactReason = false) const;
|
||||||
|
// pass in one string in <type> or a bunch in <list>
|
||||||
|
// if <exactReason> false, returns as soon as it figures out that
|
||||||
|
// app supports a given type, if true, returns an exact reason
|
||||||
|
|
||||||
|
// get rid of this??
|
||||||
|
ssize_t WriteAttr(const char *attr, type_code type, off_t,
|
||||||
|
const void *buffer, size_t );
|
||||||
|
// cover call, creates a writable node and writes out attributes
|
||||||
|
// into it; work around for file nodes not being writeable
|
||||||
|
ssize_t WriteAttrKillForegin(const char *attr, const char *foreignAttr,
|
||||||
|
type_code type, off_t, const void *buffer, size_t);
|
||||||
|
|
||||||
|
bool Mimeset(bool force);
|
||||||
|
// returns true if mime type changed
|
||||||
|
private:
|
||||||
|
status_t OpenNodeCommon(bool writable);
|
||||||
|
void SetupBaseType();
|
||||||
|
void FinishSettingUpType();
|
||||||
|
void DeletePreferredAppVolumeNameLinkTo();
|
||||||
|
|
||||||
|
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,
|
||||||
|
kUnknownNode
|
||||||
|
};
|
||||||
|
|
||||||
|
entry_ref fEntryRef;
|
||||||
|
StatStruct fStatBuf;
|
||||||
|
BString fMimeType; // should use string that may be shared for common types
|
||||||
|
|
||||||
|
// bit of overloading hackery here to save on footprint
|
||||||
|
union {
|
||||||
|
char *fPreferredAppName; // used if we are neither a volume nor a symlink
|
||||||
|
char *fVolumeName; // used if we are a volume
|
||||||
|
Model *fLinkTo; // used if we are a symlink
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8 fBaseType;
|
||||||
|
uint8 fIconFrom;
|
||||||
|
bool fWritable;
|
||||||
|
BNode *fNode;
|
||||||
|
status_t fStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ModelNodeLazyOpener {
|
||||||
|
// a utility open state manager, usefull to allocate on stack
|
||||||
|
// and have close up model when done, etc.
|
||||||
|
public:
|
||||||
|
// consider failing when open does not succeed
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
// handy flavors of openers
|
||||||
|
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
|
||||||
|
// #define CHECK_OPEN_MODEL_LEAKS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CHECK_OPEN_MODEL_LEAKS
|
||||||
|
void DumpOpenModels(bool extensive);
|
||||||
|
void InitOpenModelDumping();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// inlines follow -----------------------------------
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
// the stat structure begins with a node_ref
|
||||||
|
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::IsFile() const
|
||||||
|
{
|
||||||
|
return fBaseType == kPlainNode
|
||||||
|
|| fBaseType == kQueryNode
|
||||||
|
|| fBaseType == kQueryTemplateNode
|
||||||
|
|| fBaseType == kExecutableNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Model::IsVolume() const
|
||||||
|
{
|
||||||
|
return fBaseType == kVolumeNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Model::IsDirectory() const
|
||||||
|
{
|
||||||
|
return fBaseType == kDirectoryNode
|
||||||
|
|| fBaseType == kVolumeNode
|
||||||
|
|| fBaseType == kRootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Model::IsQuery() const
|
||||||
|
{
|
||||||
|
return fBaseType == kQueryNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Model::IsQueryTemplate() const
|
||||||
|
{
|
||||||
|
return fBaseType == kQueryTemplateNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Model::IsContainer() const
|
||||||
|
{
|
||||||
|
// I guess as in should show container window -
|
||||||
|
// volumes show the volume window
|
||||||
|
return IsQuery() || IsDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Model::IsRoot() const
|
||||||
|
{
|
||||||
|
return fBaseType == kRootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Model::IsExecutable() const
|
||||||
|
{
|
||||||
|
return fBaseType == kExecutableNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Model::IsSymLink() const
|
||||||
|
{
|
||||||
|
return fBaseType == kLinkNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// MountMenu implements a context menu used for mounting/unmounting volumes
|
||||||
|
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <Mime.h>
|
||||||
|
#include <InterfaceDefs.h>
|
||||||
|
#include <VolumeRoster.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
#include <fs_info.h>
|
||||||
|
|
||||||
|
#include "AutoMounter.h"
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "MountMenu.h"
|
||||||
|
#include "IconMenuItem.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
#include "Bitmaps.h"
|
||||||
|
|
||||||
|
#if OPEN_TRACKER
|
||||||
|
#include "DeviceMap.h"
|
||||||
|
#else
|
||||||
|
#include <private/storage/DeviceMap.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SHOW_NETWORK_VOLUMES
|
||||||
|
|
||||||
|
MountMenu::MountMenu(const char *name)
|
||||||
|
: BMenu(name)
|
||||||
|
{
|
||||||
|
SetFont(be_plain_font);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if _INCLUDES_CLASS_DEVICE_MAP
|
||||||
|
struct AddOneAsMenuItemParams {
|
||||||
|
BMenu *mountMenu;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static Partition *
|
||||||
|
AddOnePartitionAsMenuItem(Partition *partition, void *castToParams)
|
||||||
|
{
|
||||||
|
if (partition->Hidden())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
AddOneAsMenuItemParams *params = (AddOneAsMenuItemParams *)castToParams;
|
||||||
|
BBitmap *icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1),
|
||||||
|
B_COLOR_8_BIT);
|
||||||
|
get_device_icon(partition->GetDevice()->Name(), icon->Bits(), B_MINI_ICON);
|
||||||
|
|
||||||
|
|
||||||
|
const char *name = partition->GetDevice()->DisplayName();
|
||||||
|
|
||||||
|
if (!partition->GetDevice()->IsFloppy() ||
|
||||||
|
partition->Mounted() == kMounted) {
|
||||||
|
if (*partition->VolumeName())
|
||||||
|
name = partition->VolumeName();
|
||||||
|
else if (*partition->Type())
|
||||||
|
name = partition->Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage *message = new BMessage;
|
||||||
|
|
||||||
|
if (partition->Mounted() == kMounted) {
|
||||||
|
message->what = kUnmountVolume;
|
||||||
|
message->AddInt32("device_id", partition->VolumeDeviceID());
|
||||||
|
} else {
|
||||||
|
message->what = kMountVolume;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Floppies have an ID of -1, because they don't have
|
||||||
|
// partition (and hence no parititon ID).
|
||||||
|
//
|
||||||
|
if (partition->GetDevice()->IsFloppy())
|
||||||
|
message->AddInt32("id", kFloppyID);
|
||||||
|
else
|
||||||
|
message->AddInt32("id", partition->UniqueID());
|
||||||
|
}
|
||||||
|
|
||||||
|
BMenuItem *item = new IconMenuItem(name, message, icon);
|
||||||
|
if (partition->Mounted() == kMounted)
|
||||||
|
item->SetMarked(true);
|
||||||
|
|
||||||
|
if (partition->Mounted() == kMounted) {
|
||||||
|
BVolume partVolume(partition->VolumeDeviceID());
|
||||||
|
|
||||||
|
BVolume bootVolume;
|
||||||
|
BVolumeRoster().GetBootVolume(&bootVolume);
|
||||||
|
if (partVolume == bootVolume)
|
||||||
|
item->SetEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
params->mountMenu->AddItem(item);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
MountMenu::AddDynamicItem(add_state)
|
||||||
|
{
|
||||||
|
#if _INCLUDES_CLASS_DEVICE_MAP
|
||||||
|
for (;;) {
|
||||||
|
BMenuItem *item = RemoveItem(0L);
|
||||||
|
if (item == NULL)
|
||||||
|
break;
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddOneAsMenuItemParams params;
|
||||||
|
params.mountMenu = this;
|
||||||
|
|
||||||
|
AutoMounter *autoMounter = dynamic_cast<TTracker *>(be_app)->
|
||||||
|
AutoMounterLoop();
|
||||||
|
|
||||||
|
autoMounter->CheckVolumesNow();
|
||||||
|
autoMounter->EachPartition(&AddOnePartitionAsMenuItem, ¶ms);
|
||||||
|
|
||||||
|
#ifdef SHOW_NETWORK_VOLUMES
|
||||||
|
|
||||||
|
// iterate the volume roster and look for volumes with the
|
||||||
|
// 'shared' attributes -- these same volumes will not be returned
|
||||||
|
// by the autoMounter because they do not show up in the /dev tree
|
||||||
|
BVolumeRoster volumeRoster;
|
||||||
|
BVolume volume;
|
||||||
|
bool needSeparator = false;
|
||||||
|
while (volumeRoster.GetNextVolume(&volume) == B_OK) {
|
||||||
|
if (volume.IsShared()) {
|
||||||
|
needSeparator = true;
|
||||||
|
BBitmap *icon = new BBitmap(BRect(0, 0, 15, 15), B_COLOR_8_BIT);
|
||||||
|
fs_info info;
|
||||||
|
if (fs_stat_dev(volume.Device(), &info) != B_OK) {
|
||||||
|
PRINT(("Cannot get mount menu item icon; bad device ID\n"));
|
||||||
|
delete icon;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Use the shared icon instead of the device icon
|
||||||
|
if (get_device_icon(info.device_name, icon->Bits(), B_MINI_ICON) != B_OK)
|
||||||
|
GetTrackerResources()->GetIconResource(kResShareIcon, B_MINI_ICON, icon);
|
||||||
|
|
||||||
|
BMessage *message = new BMessage(kUnmountVolume);
|
||||||
|
message->AddInt32("device_id", volume.Device());
|
||||||
|
char volumeName[B_FILE_NAME_LENGTH];
|
||||||
|
volume.GetName(volumeName);
|
||||||
|
|
||||||
|
BMenuItem *item = new IconMenuItem(volumeName, message, icon);
|
||||||
|
item->SetMarked(true);
|
||||||
|
AddItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AddSeparatorItem();
|
||||||
|
|
||||||
|
// add an option to rescan the scsii bus, etc.
|
||||||
|
BMenuItem *rescanItem = NULL;
|
||||||
|
if (modifiers() & B_SHIFT_KEY) {
|
||||||
|
rescanItem = new BMenuItem("Rescan Devices", new BMessage(kAutomounterRescan));
|
||||||
|
AddItem(rescanItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
BMenuItem *mountAll = new BMenuItem("Mount All", new BMessage(kMountAllNow));
|
||||||
|
AddItem(mountAll);
|
||||||
|
BMenuItem *mountSettings = new BMenuItem("Settings"B_UTF8_ELLIPSIS,
|
||||||
|
new BMessage(kRunAutomounterSettings));
|
||||||
|
AddItem(mountSettings);
|
||||||
|
|
||||||
|
SetTargetForItems(be_app);
|
||||||
|
|
||||||
|
if (rescanItem)
|
||||||
|
rescanItem->SetTarget(autoMounter);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
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 MOUNTMENU_H
|
||||||
|
#define MOUNTMENU_H
|
||||||
|
|
||||||
|
#include <Menu.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class MountMenu : public BMenu {
|
||||||
|
public:
|
||||||
|
|
||||||
|
MountMenu(const char *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual bool AddDynamicItem(add_state);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,851 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NavMenu is a hierarchical menu of volumes, folders, files and queries
|
||||||
|
// displays icons, uses the SlowMenu API for full interruptability
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
|
||||||
|
#include <StopWatch.h>
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <Query.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <Screen.h>
|
||||||
|
#include <VolumeRoster.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
|
||||||
|
#include "Attributes.h"
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "ContainerWindow.h"
|
||||||
|
#include "DesktopPoseView.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
#include "FSUtils.h"
|
||||||
|
#include "IconMenuItem.h"
|
||||||
|
#include "MimeTypes.h"
|
||||||
|
#include "NavMenu.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "FunctionObject.h"
|
||||||
|
#include "QueryPoseView.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
const int32 kMinMenuWidth = 150;
|
||||||
|
|
||||||
|
enum nav_flags {
|
||||||
|
kVolumesOnly = 1,
|
||||||
|
kShowParent = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SpringLoadedFolderCompareMessages(const BMessage *incoming, const BMessage *dragmessage)
|
||||||
|
{
|
||||||
|
if (!dragmessage || !incoming)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool retvalue=false;
|
||||||
|
for (int32 inIndex=0; incoming->HasRef("refs", inIndex); inIndex++) {
|
||||||
|
entry_ref inRef;
|
||||||
|
if (incoming->FindRef("refs", inIndex, &inRef) != B_OK) {
|
||||||
|
retvalue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inRefMatch = false;
|
||||||
|
for (int32 dragIndex=0; dragmessage->HasRef("refs", dragIndex); dragIndex++) {
|
||||||
|
entry_ref dragRef;
|
||||||
|
if (dragmessage->FindRef("refs", dragIndex, &dragRef) != B_OK) {
|
||||||
|
inRefMatch = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// if the incoming ref matches any ref in the drag ref
|
||||||
|
// then we can try the next incoming ref
|
||||||
|
if (inRef == dragRef) {
|
||||||
|
inRefMatch = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retvalue = inRefMatch;
|
||||||
|
if (!inRefMatch)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retvalue) {
|
||||||
|
// if all the refs match
|
||||||
|
// try and see if this is another instance of the same
|
||||||
|
// drag contents, but new drag
|
||||||
|
retvalue = false;
|
||||||
|
BPoint inPt, dPt;
|
||||||
|
if (incoming->FindPoint("click_pt", &inPt) == B_OK)
|
||||||
|
if (dragmessage->FindPoint("click_pt", &dPt) == B_OK)
|
||||||
|
retvalue = (inPt == dPt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SpringLoadedFolderSetMenuStates(const BMenu* menu, const BObjectList<BString> *typeslist)
|
||||||
|
{
|
||||||
|
if (!menu || !typeslist)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// if a types list exists
|
||||||
|
// iterate through the list and see if each item
|
||||||
|
// can support any item in the list
|
||||||
|
// set the enabled state of the item
|
||||||
|
int32 count = menu->CountItems();
|
||||||
|
for (int32 index = 0 ; index < count ; index++) {
|
||||||
|
ModelMenuItem *item = dynamic_cast<ModelMenuItem *>(menu->ItemAt(index));
|
||||||
|
if (!item)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const Model *model = item->TargetModel();
|
||||||
|
if (!model)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (model->IsSymLink()) {
|
||||||
|
// find out what the model is, resolve if symlink
|
||||||
|
BEntry entry(model->EntryRef(), true);
|
||||||
|
if (entry.InitCheck() == B_OK) {
|
||||||
|
if (entry.IsDirectory()) {
|
||||||
|
// folder? always keep enabled
|
||||||
|
item->SetEnabled(true);
|
||||||
|
} else {
|
||||||
|
// other, check its support
|
||||||
|
Model resolvedModel(&entry);
|
||||||
|
int32 supported = resolvedModel.SupportsMimeType(NULL, typeslist);
|
||||||
|
item->SetEnabled(supported != kDoesNotSupportType);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
// bad entry ref (bad symlink?), disable
|
||||||
|
item->SetEnabled(false);
|
||||||
|
} else if (model->IsDirectory() || model->IsRoot() || model->IsVolume())
|
||||||
|
// always enabled if a container
|
||||||
|
item->SetEnabled(true);
|
||||||
|
else if (model->IsFile() || model->IsExecutable()) {
|
||||||
|
int32 supported = model->SupportsMimeType(NULL, typeslist);
|
||||||
|
item->SetEnabled(supported != kDoesNotSupportType);
|
||||||
|
} else
|
||||||
|
item->SetEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SpringLoadedFolderAddUniqueTypeToList(entry_ref *ref, BObjectList<BString> *typeslist)
|
||||||
|
{
|
||||||
|
if (!ref || !typeslist)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// get the mime type for the current ref
|
||||||
|
BNodeInfo nodeinfo;
|
||||||
|
BNode node(ref);
|
||||||
|
if (node.InitCheck() != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nodeinfo.SetTo(&node);
|
||||||
|
|
||||||
|
char mimestr[B_MIME_TYPE_LENGTH];
|
||||||
|
// add it to the list
|
||||||
|
if (nodeinfo.GetType(mimestr) == B_OK && strlen(mimestr) > 0) {
|
||||||
|
// if this is a symlink, add symlink to the list (below)
|
||||||
|
// resolve the symlink, add the resolved type
|
||||||
|
// to the list
|
||||||
|
if (strcmp(B_LINK_MIMETYPE, mimestr) == 0) {
|
||||||
|
BEntry entry(ref, true);
|
||||||
|
if (entry.InitCheck() == B_OK) {
|
||||||
|
entry_ref resolvedRef;
|
||||||
|
if (entry.GetRef(&resolvedRef) == B_OK)
|
||||||
|
SpringLoadedFolderAddUniqueTypeToList(&resolvedRef, typeslist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// scan the current list, don't add dups
|
||||||
|
bool unique = true;
|
||||||
|
int32 count = typeslist->CountItems();
|
||||||
|
for (int32 index = 0 ; index < count ; index++) {
|
||||||
|
if (typeslist->ItemAt(index)->Compare(mimestr) == 0) {
|
||||||
|
unique = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unique)
|
||||||
|
typeslist->AddItem(new BString(mimestr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SpringLoadedFolderCacheDragData(const BMessage *incoming, BMessage **message, BObjectList<BString> **typeslist)
|
||||||
|
{
|
||||||
|
if (!incoming)
|
||||||
|
return;
|
||||||
|
|
||||||
|
delete *message;
|
||||||
|
delete *typeslist;
|
||||||
|
|
||||||
|
BMessage *localMessage = new BMessage(*incoming);
|
||||||
|
BObjectList<BString> *localTypesList = new BObjectList<BString>(10, true);
|
||||||
|
|
||||||
|
for (int32 index=0; incoming->HasRef("refs", index); index++) {
|
||||||
|
entry_ref ref;
|
||||||
|
if (incoming->FindRef("refs", index, &ref) != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SpringLoadedFolderAddUniqueTypeToList(&ref, localTypesList);
|
||||||
|
}
|
||||||
|
|
||||||
|
*message = localMessage;
|
||||||
|
*typeslist = localTypesList;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
BNavMenu::BNavMenu(const char *title, uint32 message, const BHandler *target,
|
||||||
|
BWindow *parentWindow, const BObjectList<BString> *list)
|
||||||
|
: BSlowMenu(title),
|
||||||
|
fMessage(message),
|
||||||
|
fMessenger(target, target->Looper()),
|
||||||
|
fParentWindow(parentWindow),
|
||||||
|
fFlags(0),
|
||||||
|
fItemList(0),
|
||||||
|
fContainer(0),
|
||||||
|
fTypesList(list)
|
||||||
|
{
|
||||||
|
InitIconPreloader();
|
||||||
|
|
||||||
|
SetFont(be_plain_font);
|
||||||
|
|
||||||
|
// add the parent window to the invocation message so that it
|
||||||
|
// can be closed if option modifier held down during invocation
|
||||||
|
BContainerWindow *originatingWindow = dynamic_cast<BContainerWindow *>(fParentWindow);
|
||||||
|
if (originatingWindow)
|
||||||
|
fMessage.AddData("nodeRefsToClose", B_RAW_TYPE,
|
||||||
|
originatingWindow->TargetModel()->NodeRef(), sizeof (node_ref));
|
||||||
|
|
||||||
|
// too long to have triggers
|
||||||
|
SetTriggersEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BNavMenu::BNavMenu(const char *title, uint32 message, const BMessenger &messenger,
|
||||||
|
BWindow *parentWindow, const BObjectList<BString> *list)
|
||||||
|
: BSlowMenu(title),
|
||||||
|
fMessage(message),
|
||||||
|
fMessenger(messenger),
|
||||||
|
fParentWindow(parentWindow),
|
||||||
|
fFlags(0),
|
||||||
|
fItemList(0),
|
||||||
|
fContainer(0),
|
||||||
|
fTypesList(list)
|
||||||
|
{
|
||||||
|
InitIconPreloader();
|
||||||
|
|
||||||
|
SetFont(be_plain_font);
|
||||||
|
|
||||||
|
// add the parent window to the invocation message so that it
|
||||||
|
// can be closed if option modifier held down during invocation
|
||||||
|
BContainerWindow *originatingWindow = dynamic_cast<BContainerWindow *>(fParentWindow);
|
||||||
|
if (originatingWindow)
|
||||||
|
fMessage.AddData("nodeRefsToClose", B_RAW_TYPE,
|
||||||
|
originatingWindow->TargetModel()->NodeRef(), sizeof (node_ref));
|
||||||
|
|
||||||
|
// too long to have triggers
|
||||||
|
SetTriggersEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BNavMenu::~BNavMenu()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::AttachedToWindow()
|
||||||
|
{
|
||||||
|
BSlowMenu::AttachedToWindow();
|
||||||
|
|
||||||
|
SpringLoadedFolderSetMenuStates(this, fTypesList);
|
||||||
|
// if dragging (fTypesList != NULL)
|
||||||
|
// set the menu items enabled state
|
||||||
|
// relative to the ability to handle an item in the
|
||||||
|
// drag message
|
||||||
|
ResetTargets();
|
||||||
|
// allow an opportunity to reset the target for each of the items
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::DetachedFromWindow()
|
||||||
|
{
|
||||||
|
// does this need to set this to null?
|
||||||
|
// the parent, handling dnd should set this
|
||||||
|
// appropriately
|
||||||
|
//
|
||||||
|
// if this changes, BeMenu and RecentsMenu
|
||||||
|
// in Deskbar should also change
|
||||||
|
fTypesList = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::ResetTargets()
|
||||||
|
{
|
||||||
|
SetTargetForItems(Target());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::ForceRebuild()
|
||||||
|
{
|
||||||
|
ClearMenuBuildingState();
|
||||||
|
fMenuBuilt = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BNavMenu::NeedsToRebuild() const
|
||||||
|
{
|
||||||
|
return !fMenuBuilt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::SetNavDir(const entry_ref *ref)
|
||||||
|
{
|
||||||
|
ForceRebuild();
|
||||||
|
// reset the slow menu building mechanism so we can add more stuff
|
||||||
|
|
||||||
|
fNavDir = *ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::ClearMenuBuildingState()
|
||||||
|
{
|
||||||
|
delete fContainer;
|
||||||
|
fContainer = NULL;
|
||||||
|
|
||||||
|
// item list is non-owning, need to delete the items because
|
||||||
|
// they didn't get added to the menu
|
||||||
|
if (fItemList) {
|
||||||
|
int32 count = fItemList->CountItems();
|
||||||
|
for (int32 index = count - 1; index >= 0; index--)
|
||||||
|
delete RemoveItem(index);
|
||||||
|
delete fItemList;
|
||||||
|
fItemList = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BNavMenu::StartBuildingItemList()
|
||||||
|
{
|
||||||
|
BEntry entry;
|
||||||
|
|
||||||
|
if (fNavDir.device < 0 || entry.SetTo(&fNavDir) != B_OK
|
||||||
|
|| !entry.Exists())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
fItemList = new BObjectList<BMenuItem>(50);
|
||||||
|
|
||||||
|
fIteratingDesktop = false;
|
||||||
|
|
||||||
|
BDirectory parent;
|
||||||
|
status_t status = entry.GetParent(&parent);
|
||||||
|
|
||||||
|
// if ref is the root item then build list of volume root dirs
|
||||||
|
fFlags = uint8((fFlags & ~kVolumesOnly) | (status == B_ENTRY_NOT_FOUND ? kVolumesOnly : 0));
|
||||||
|
if (fFlags & kVolumesOnly)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Model startModel(&entry, true);
|
||||||
|
if (startModel.InitCheck() != B_OK || !startModel.IsContainer())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (startModel.IsQuery())
|
||||||
|
fContainer = new QueryEntryListCollection(&startModel);
|
||||||
|
else if (FSIsDeskDir(&entry)) {
|
||||||
|
fIteratingDesktop = true;
|
||||||
|
fContainer = DesktopPoseView::InitDesktopDirentIterator(0, startModel.EntryRef());
|
||||||
|
AddRootItemsIfNeeded();
|
||||||
|
} else if (FSIsTrashDir(&entry)) {
|
||||||
|
// the trash window needs to display a union of all the
|
||||||
|
// trash folders from all the mounted volumes
|
||||||
|
BVolumeRoster volRoster;
|
||||||
|
volRoster.Rewind();
|
||||||
|
BVolume volume;
|
||||||
|
fContainer = new EntryIteratorList();
|
||||||
|
|
||||||
|
while (volRoster.GetNextVolume(&volume) == B_OK) {
|
||||||
|
if (!volume.IsPersistent())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BDirectory trashDir;
|
||||||
|
|
||||||
|
if (FSGetTrashDir(&trashDir, volume.Device()) == B_OK)
|
||||||
|
dynamic_cast<EntryIteratorList *>(fContainer)->
|
||||||
|
AddItem(new DirectoryEntryList(trashDir));
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
fContainer = new DirectoryEntryList(*dynamic_cast<BDirectory *>
|
||||||
|
(startModel.Node()));
|
||||||
|
|
||||||
|
if (fContainer == NULL || fContainer->InitCheck() != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
fContainer->Rewind();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::AddRootItemsIfNeeded()
|
||||||
|
{
|
||||||
|
BVolumeRoster roster;
|
||||||
|
roster.Rewind();
|
||||||
|
BVolume volume;
|
||||||
|
while (roster.GetNextVolume(&volume) == B_OK) {
|
||||||
|
|
||||||
|
BDirectory root;
|
||||||
|
BEntry entry;
|
||||||
|
if (!volume.IsPersistent()
|
||||||
|
|| volume.GetRootDirectory(&root) != B_OK
|
||||||
|
|| root.GetEntry(&entry) != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Model model(&entry);
|
||||||
|
AddOneItem(&model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BNavMenu::AddNextItem()
|
||||||
|
{
|
||||||
|
if (fFlags & kVolumesOnly) {
|
||||||
|
BuildVolumeMenu();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit nav menus to 500 items only
|
||||||
|
if (fItemList->CountItems() > 500)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
BEntry entry;
|
||||||
|
if (fContainer->GetNextEntry(&entry) != B_OK) {
|
||||||
|
// we're finished
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TrackerSettings().HideDotFiles()) {
|
||||||
|
char name[B_FILE_NAME_LENGTH];
|
||||||
|
if (entry.GetName(name) == B_OK && name[0] == '.')
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Model model(&entry, true);
|
||||||
|
if (model.InitCheck() != B_OK) {
|
||||||
|
// PRINT(("not showing hidden item %s, wouldn't open\n", model->Name()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryEntryListCollection *queryContainer
|
||||||
|
= dynamic_cast<QueryEntryListCollection*>(fContainer);
|
||||||
|
if (queryContainer && !queryContainer->ShowResultsFromTrash()
|
||||||
|
&& FSInTrashDir(model.EntryRef())) {
|
||||||
|
// query entry is in trash and shall not be shown
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t size = -1;
|
||||||
|
PoseInfo poseInfo;
|
||||||
|
|
||||||
|
if (model.Node())
|
||||||
|
size = model.Node()->ReadAttr(kAttrPoseInfo, B_RAW_TYPE, 0,
|
||||||
|
&poseInfo, sizeof(poseInfo));
|
||||||
|
|
||||||
|
model.CloseNode();
|
||||||
|
|
||||||
|
// item might be in invisible
|
||||||
|
// ToDo:
|
||||||
|
// use more of PoseView's filtering here
|
||||||
|
if ((size == sizeof(poseInfo)
|
||||||
|
&& !BPoseView::PoseVisible(&model, &poseInfo, false))
|
||||||
|
|| (fIteratingDesktop && !ShouldShowDesktopPose(fNavDir.device,
|
||||||
|
&model, &poseInfo))) {
|
||||||
|
// PRINT(("not showing hidden item %s\n", model.Name()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddOneItem(&model);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::AddOneItem(Model *model)
|
||||||
|
{
|
||||||
|
BMenuItem *item = NewModelItem(model, &fMessage, fMessenger, false,
|
||||||
|
dynamic_cast<BContainerWindow *>(fParentWindow),
|
||||||
|
fTypesList, &fTrackingHook);
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
fItemList->AddItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModelMenuItem *
|
||||||
|
BNavMenu::NewModelItem(Model *model, const BMessage *invokeMessage,
|
||||||
|
const BMessenger &target, bool suppressFolderHierarchy,
|
||||||
|
BContainerWindow *parentWindow, const BObjectList<BString> *typeslist,
|
||||||
|
TrackingHookData *hook)
|
||||||
|
{
|
||||||
|
if (model->InitCheck() != B_OK)
|
||||||
|
return 0;
|
||||||
|
entry_ref ref;
|
||||||
|
bool container = false;
|
||||||
|
if (model->IsSymLink()) {
|
||||||
|
|
||||||
|
Model *newResolvedModel = 0;
|
||||||
|
Model *result = model->LinkTo();
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
newResolvedModel = new Model(model->EntryRef(), true, true);
|
||||||
|
|
||||||
|
if (newResolvedModel->InitCheck() != B_OK) {
|
||||||
|
// broken link, still can show though, bail
|
||||||
|
delete newResolvedModel;
|
||||||
|
result = 0;
|
||||||
|
} else
|
||||||
|
result = newResolvedModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
BModelOpener opener(result);
|
||||||
|
// open the model, if it ain't open already
|
||||||
|
|
||||||
|
PoseInfo poseInfo;
|
||||||
|
ssize_t size = -1;
|
||||||
|
|
||||||
|
if (result->Node())
|
||||||
|
size = result->Node()->ReadAttr(kAttrPoseInfo, B_RAW_TYPE, 0,
|
||||||
|
&poseInfo, sizeof(poseInfo));
|
||||||
|
|
||||||
|
result->CloseNode();
|
||||||
|
|
||||||
|
if (size == sizeof(poseInfo) && !BPoseView::PoseVisible(result,
|
||||||
|
&poseInfo, false)) {
|
||||||
|
// link target sez it doesn't want to be visible,
|
||||||
|
// don't show the link
|
||||||
|
PRINT(("not showing hidden item %s\n", model->Name()));
|
||||||
|
delete newResolvedModel;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ref = *result->EntryRef();
|
||||||
|
container = result->IsContainer();
|
||||||
|
}
|
||||||
|
model->SetLinkTo(result);
|
||||||
|
} else {
|
||||||
|
ref = *model->EntryRef();
|
||||||
|
container = model->IsContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessage *message = new BMessage(*invokeMessage);
|
||||||
|
message->AddRef("refs", model->EntryRef());
|
||||||
|
|
||||||
|
// Truncate the name if necessary
|
||||||
|
BString truncatedString(model->Name());
|
||||||
|
be_plain_font->TruncateString(&truncatedString, B_TRUNCATE_END,
|
||||||
|
GetMaxMenuWidth());
|
||||||
|
|
||||||
|
ModelMenuItem *item = NULL;
|
||||||
|
if (!container || suppressFolderHierarchy) {
|
||||||
|
item = new ModelMenuItem(model, truncatedString.String(), message);
|
||||||
|
if (invokeMessage->what != B_REFS_RECEIVED)
|
||||||
|
item->SetEnabled(false);
|
||||||
|
// the above is broken for FavoritesMenu::AddNextItem, which uses a
|
||||||
|
// workaround - should fix this
|
||||||
|
} else {
|
||||||
|
BNavMenu *menu = new BNavMenu(truncatedString.String(),
|
||||||
|
invokeMessage->what, target, parentWindow, typeslist);
|
||||||
|
|
||||||
|
menu->SetNavDir(&ref);
|
||||||
|
if (hook)
|
||||||
|
menu->InitTrackingHook(hook->fTrackingHook, &(hook->fTarget),
|
||||||
|
hook->fDragMessage);
|
||||||
|
|
||||||
|
item = new ModelMenuItem(model, menu);
|
||||||
|
item->SetMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::BuildVolumeMenu()
|
||||||
|
{
|
||||||
|
BVolumeRoster roster;
|
||||||
|
BVolume volume;
|
||||||
|
|
||||||
|
roster.Rewind();
|
||||||
|
while (roster.GetNextVolume(&volume) == B_OK) {
|
||||||
|
|
||||||
|
if (!volume.IsPersistent())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BDirectory startDir;
|
||||||
|
if (volume.GetRootDirectory(&startDir) == B_OK) {
|
||||||
|
BEntry entry;
|
||||||
|
startDir.GetEntry(&entry);
|
||||||
|
|
||||||
|
Model *model = new Model(&entry);
|
||||||
|
if (model->InitCheck() != B_OK) {
|
||||||
|
delete model;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BNavMenu *menu = new BNavMenu(model->Name(), fMessage.what,
|
||||||
|
fMessenger, fParentWindow, fTypesList);
|
||||||
|
|
||||||
|
menu->SetNavDir(model->EntryRef());
|
||||||
|
|
||||||
|
ASSERT(menu->Name());
|
||||||
|
|
||||||
|
ModelMenuItem *item = new ModelMenuItem(model, menu);
|
||||||
|
BMessage *message = new BMessage(fMessage);
|
||||||
|
|
||||||
|
message->AddRef("refs", model->EntryRef());
|
||||||
|
|
||||||
|
item->SetMessage(message);
|
||||||
|
fItemList->AddItem(item);
|
||||||
|
ASSERT(item->Label());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
BNavMenu::CompareFolderNamesFirstOne(const BMenuItem *i1, const BMenuItem *i2)
|
||||||
|
{
|
||||||
|
const ModelMenuItem *item1 = dynamic_cast<const ModelMenuItem *>(i1);
|
||||||
|
const ModelMenuItem *item2 = dynamic_cast<const ModelMenuItem *>(i2);
|
||||||
|
|
||||||
|
if (item1 != NULL && item2 != NULL)
|
||||||
|
return item1->TargetModel()->CompareFolderNamesFirst(item2->TargetModel());
|
||||||
|
|
||||||
|
return strcasecmp(i1->Label(), i2->Label());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
BNavMenu::CompareOne(const BMenuItem *i1, const BMenuItem *i2)
|
||||||
|
{
|
||||||
|
return strcasecmp(i1->Label(), i2->Label());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::DoneBuildingItemList()
|
||||||
|
{
|
||||||
|
// add sorted items to menu
|
||||||
|
if (TrackerSettings().SortFolderNamesFirst())
|
||||||
|
fItemList->SortItems(CompareFolderNamesFirstOne);
|
||||||
|
else
|
||||||
|
fItemList->SortItems(CompareOne);
|
||||||
|
|
||||||
|
// if the parent link should be shown, it will be the first
|
||||||
|
// entry in the menu - but don't add the item if we're already
|
||||||
|
// at the file system's root
|
||||||
|
if (fFlags & kShowParent) {
|
||||||
|
BDirectory directory(&fNavDir);
|
||||||
|
BEntry entry(&fNavDir);
|
||||||
|
if (!directory.IsRootDirectory()
|
||||||
|
&& entry.GetParent(&entry) == B_OK) {
|
||||||
|
Model model(&entry, true);
|
||||||
|
BLooper *looper;
|
||||||
|
AddNavParentDir(&model,fMessage.what,fMessenger.Target(&looper));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 count = fItemList->CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++)
|
||||||
|
AddItem(fItemList->ItemAt(index));
|
||||||
|
fItemList->MakeEmpty();
|
||||||
|
|
||||||
|
if (!count) {
|
||||||
|
BMenuItem *item = new BMenuItem("Empty Folder", 0);
|
||||||
|
item->SetEnabled(false);
|
||||||
|
AddItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetTargetForItems(fMessenger);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BNavMenu::GetMaxMenuWidth(void)
|
||||||
|
{
|
||||||
|
int32 width = (int32)(BScreen().Frame().Width() / 4);
|
||||||
|
return (width < kMinMenuWidth) ? kMinMenuWidth : width;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::AddNavDir(const Model *model, uint32 what, BHandler *target,
|
||||||
|
bool populateSubmenu)
|
||||||
|
{
|
||||||
|
BMessage *message = new BMessage((uint32)what);
|
||||||
|
message->AddRef("refs", model->EntryRef());
|
||||||
|
ModelMenuItem *item = NULL;
|
||||||
|
|
||||||
|
if (populateSubmenu) {
|
||||||
|
BNavMenu *navMenu = new BNavMenu(model->Name(), what, target);
|
||||||
|
navMenu->SetNavDir(model->EntryRef());
|
||||||
|
navMenu->InitTrackingHook(fTrackingHook.fTrackingHook, &(fTrackingHook.fTarget),
|
||||||
|
fTrackingHook.fDragMessage);
|
||||||
|
item = new ModelMenuItem(model, navMenu);
|
||||||
|
item->SetMessage(message);
|
||||||
|
} else
|
||||||
|
item = new ModelMenuItem(model, model->Name(), message);
|
||||||
|
|
||||||
|
AddItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::AddNavParentDir(const char *name,const Model *model,uint32 what,BHandler *target)
|
||||||
|
{
|
||||||
|
BNavMenu *menu = new BNavMenu(name,what,target);
|
||||||
|
menu->SetNavDir(model->EntryRef());
|
||||||
|
menu->SetShowParent(true);
|
||||||
|
menu->InitTrackingHook(fTrackingHook.fTrackingHook, &(fTrackingHook.fTarget),
|
||||||
|
fTrackingHook.fDragMessage);
|
||||||
|
|
||||||
|
BMenuItem *item = new SpecialModelMenuItem(model,menu);
|
||||||
|
|
||||||
|
BMessage *message = new BMessage(what);
|
||||||
|
message->AddRef("refs",model->EntryRef());
|
||||||
|
item->SetMessage(message);
|
||||||
|
|
||||||
|
AddItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::AddNavParentDir(const Model *model, uint32 what, BHandler *target)
|
||||||
|
{
|
||||||
|
AddNavParentDir("parent folder",model,what,target);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::SetShowParent(bool show)
|
||||||
|
{
|
||||||
|
fFlags = uint8((fFlags & ~kShowParent) | (show ? kShowParent : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::SetTypesList(const BObjectList<BString> *list)
|
||||||
|
{
|
||||||
|
fTypesList = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const BObjectList<BString> *
|
||||||
|
BNavMenu::TypesList() const
|
||||||
|
{
|
||||||
|
return fTypesList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::SetTarget(const BMessenger &msngr)
|
||||||
|
{
|
||||||
|
fMessenger = msngr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMessenger
|
||||||
|
BNavMenu::Target()
|
||||||
|
{
|
||||||
|
return fMessenger;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TrackingHookData *
|
||||||
|
BNavMenu::InitTrackingHook(bool (*hook)(BMenu *, void *), const BMessenger *target,
|
||||||
|
const BMessage *dragMessage)
|
||||||
|
{
|
||||||
|
fTrackingHook.fTrackingHook = hook;
|
||||||
|
if (target)
|
||||||
|
fTrackingHook.fTarget = *target;
|
||||||
|
fTrackingHook.fDragMessage = dragMessage;
|
||||||
|
SetTrackingHookDeep(this, hook, &fTrackingHook);
|
||||||
|
return &fTrackingHook;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavMenu::SetTrackingHookDeep(BMenu *menu, bool (*func)(BMenu *, void *), void *state)
|
||||||
|
{
|
||||||
|
menu->SetTrackingHook(func, state);
|
||||||
|
int32 count = menu->CountItems();
|
||||||
|
for (int32 index = 0 ; index < count; index++) {
|
||||||
|
BMenuItem *item = menu->ItemAt(index);
|
||||||
|
if (!item)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BMenu *submenu = item->Submenu();
|
||||||
|
if (submenu)
|
||||||
|
SetTrackingHookDeep(submenu, func, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,393 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#include "Bitmaps.h"
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "ContainerWindow.h"
|
||||||
|
#include "FSUtils.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "Navigator.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
#include <Window.h>
|
||||||
|
#include <Picture.h>
|
||||||
|
#include <TextControl.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
static const int32 kMaxHistory = 32;
|
||||||
|
|
||||||
|
static const rgb_color kBgColor = {220, 220, 220, 255};
|
||||||
|
static const rgb_color kShineColor = {255, 255, 255, 255};
|
||||||
|
static const rgb_color kHalfDarkColor = {200, 200, 200, 255};
|
||||||
|
static const rgb_color kDarkColor = {166, 166, 166, 255};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// BPictureButton() will crash when giving zero pointers,
|
||||||
|
// although we really want and have to set up the
|
||||||
|
// pictures when we can, e.g. on a AttachedToWindow.
|
||||||
|
static BPicture sPicture;
|
||||||
|
|
||||||
|
BNavigatorButton::BNavigatorButton(BRect rect, const char *name, BMessage *message,
|
||||||
|
int32 resIDon, int32 resIDoff, int32 resIDdisabled)
|
||||||
|
: BPictureButton(rect, name, &sPicture, &sPicture, message),
|
||||||
|
fResIDOn(resIDon),
|
||||||
|
fResIDOff(resIDoff),
|
||||||
|
fResIDDisabled(resIDdisabled)
|
||||||
|
{
|
||||||
|
// Clear to background color to
|
||||||
|
// avoid ugly border on click
|
||||||
|
SetViewColor(kBgColor);
|
||||||
|
SetHighColor(kBgColor);
|
||||||
|
SetLowColor(kBgColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
BNavigatorButton::~BNavigatorButton()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigatorButton::AttachedToWindow()
|
||||||
|
{
|
||||||
|
BBitmap *bmpOn = 0;
|
||||||
|
GetTrackerResources()->GetBitmapResource(B_MESSAGE_TYPE, fResIDOn, &bmpOn);
|
||||||
|
SetPicture(bmpOn, true, true);
|
||||||
|
delete bmpOn;
|
||||||
|
|
||||||
|
BBitmap *bmpOff = 0;
|
||||||
|
GetTrackerResources()->GetBitmapResource(B_MESSAGE_TYPE, fResIDOff, &bmpOff);
|
||||||
|
SetPicture(bmpOff, true, false);
|
||||||
|
delete bmpOff;
|
||||||
|
|
||||||
|
BBitmap *bmpDisabled = 0;
|
||||||
|
GetTrackerResources()->GetBitmapResource(B_MESSAGE_TYPE, fResIDDisabled, &bmpDisabled);
|
||||||
|
SetPicture(bmpDisabled, false, false);
|
||||||
|
SetPicture(bmpDisabled, false, true);
|
||||||
|
delete bmpDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigatorButton::SetPicture(BBitmap *bitmap, bool enabled, bool on)
|
||||||
|
{
|
||||||
|
if (bitmap) {
|
||||||
|
BPicture picture;
|
||||||
|
BView view(bitmap->Bounds(), "", 0, 0);
|
||||||
|
AddChild(&view);
|
||||||
|
view.BeginPicture(&picture);
|
||||||
|
view.SetHighColor(kBgColor);
|
||||||
|
view.FillRect(view.Bounds());
|
||||||
|
view.SetDrawingMode(B_OP_OVER);
|
||||||
|
view.DrawBitmap(bitmap, BPoint(0, 0));
|
||||||
|
view.EndPicture();
|
||||||
|
RemoveChild(&view);
|
||||||
|
if (enabled)
|
||||||
|
if (on)
|
||||||
|
SetEnabledOn(&picture);
|
||||||
|
else
|
||||||
|
SetEnabledOff(&picture);
|
||||||
|
else
|
||||||
|
if (on)
|
||||||
|
SetDisabledOn(&picture);
|
||||||
|
else
|
||||||
|
SetDisabledOff(&picture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BNavigator::BNavigator(const Model *model, BRect rect, uint32 resizeMask)
|
||||||
|
: BView(rect, "Navigator", resizeMask, B_WILL_DRAW),
|
||||||
|
fBack(0),
|
||||||
|
fForw(0),
|
||||||
|
fUp(0),
|
||||||
|
fBackHistory(8, true),
|
||||||
|
fForwHistory(8, true)
|
||||||
|
{
|
||||||
|
// Get initial path
|
||||||
|
model->GetPath(&fPath);
|
||||||
|
|
||||||
|
SetViewColor(kBgColor);
|
||||||
|
|
||||||
|
float top = 2 + (be_plain_font->Size() - 8) / 2;
|
||||||
|
|
||||||
|
// Set up widgets
|
||||||
|
fBack = new BNavigatorButton(BRect(3, top, 21, top + 17), "Back",
|
||||||
|
new BMessage(kNavigatorCommandBackward), kResBackNavActiveSel,
|
||||||
|
kResBackNavActive, kResBackNavInactive);
|
||||||
|
fBack->SetEnabled(false);
|
||||||
|
AddChild(fBack);
|
||||||
|
|
||||||
|
fForw = new BNavigatorButton(BRect(35, top, 53, top + 17), "Forw",
|
||||||
|
new BMessage(kNavigatorCommandForward), kResForwNavActiveSel,
|
||||||
|
kResForwNavActive, kResForwNavInactive);
|
||||||
|
fForw->SetEnabled(false);
|
||||||
|
AddChild(fForw);
|
||||||
|
|
||||||
|
fUp = new BNavigatorButton(BRect(67, top, 84, top + 17), "Up",
|
||||||
|
new BMessage(kNavigatorCommandUp), kResUpNavActiveSel,
|
||||||
|
kResUpNavActive, kResUpNavInactive);
|
||||||
|
fUp->SetEnabled(false);
|
||||||
|
AddChild(fUp);
|
||||||
|
|
||||||
|
fLocation = new BTextControl(BRect(97, 2, rect.Width() - 2, 21),
|
||||||
|
"Location", "", "", new BMessage(kNavigatorCommandLocation),
|
||||||
|
B_FOLLOW_LEFT_RIGHT);
|
||||||
|
fLocation->SetDivider(0);
|
||||||
|
AddChild(fLocation);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BNavigator::~BNavigator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigator::AttachedToWindow()
|
||||||
|
{
|
||||||
|
// Inital setup of widget states
|
||||||
|
UpdateLocation(0, kActionSet);
|
||||||
|
|
||||||
|
// All messages should arrive here
|
||||||
|
fBack->SetTarget(this);
|
||||||
|
fForw->SetTarget(this);
|
||||||
|
fUp->SetTarget(this);
|
||||||
|
fLocation->SetTarget(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigator::Draw(BRect)
|
||||||
|
{
|
||||||
|
// Draws a beveled smooth border
|
||||||
|
BeginLineArray(4);
|
||||||
|
AddLine(Bounds().LeftTop(), Bounds().RightTop(), kShineColor);
|
||||||
|
AddLine(Bounds().LeftTop(), Bounds().LeftBottom() - BPoint(0, 1), kShineColor);
|
||||||
|
AddLine(Bounds().LeftBottom() - BPoint(-1, 1), Bounds().RightBottom() - BPoint(0, 1), kHalfDarkColor);
|
||||||
|
AddLine(Bounds().LeftBottom(), Bounds().RightBottom(), kDarkColor);
|
||||||
|
EndLineArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigator::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case kNavigatorCommandBackward:
|
||||||
|
GoBackward((modifiers() & B_OPTION_KEY) == B_OPTION_KEY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kNavigatorCommandForward:
|
||||||
|
GoForward((modifiers() & B_OPTION_KEY) == B_OPTION_KEY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kNavigatorCommandUp:
|
||||||
|
GoUp((modifiers() & B_OPTION_KEY) == B_OPTION_KEY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kNavigatorCommandLocation:
|
||||||
|
GoTo();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// Catch any dropped refs and try
|
||||||
|
// to switch to this new directory
|
||||||
|
entry_ref ref;
|
||||||
|
if (message->FindRef("refs", &ref) == B_OK) {
|
||||||
|
BMessage message(kSwitchDirectory);
|
||||||
|
BEntry entry(&ref, true);
|
||||||
|
if (!entry.IsDirectory()) {
|
||||||
|
entry.GetRef(&ref);
|
||||||
|
BPath path(&ref);
|
||||||
|
path.GetParent(&path);
|
||||||
|
get_ref_for_path(path.Path(), &ref);
|
||||||
|
}
|
||||||
|
message.AddRef("refs", &ref);
|
||||||
|
message.AddInt32("action", kActionSet);
|
||||||
|
Window()->PostMessage(&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigator::GoBackward(bool option)
|
||||||
|
{
|
||||||
|
int32 itemCount = fBackHistory.CountItems();
|
||||||
|
if (itemCount >= 2 && fBackHistory.ItemAt(itemCount - 2)) {
|
||||||
|
BEntry entry;
|
||||||
|
if (entry.SetTo(fBackHistory.ItemAt(itemCount - 2)->Path()) == B_OK)
|
||||||
|
SendNavigationMessage(kActionBackward, &entry, option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigator::GoForward(bool option)
|
||||||
|
{
|
||||||
|
if (fForwHistory.CountItems() >= 1) {
|
||||||
|
BEntry entry;
|
||||||
|
if (entry.SetTo(fForwHistory.LastItem()->Path()) == B_OK)
|
||||||
|
SendNavigationMessage(kActionForward, &entry, option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigator::GoUp(bool option)
|
||||||
|
{
|
||||||
|
BEntry entry;
|
||||||
|
if (entry.SetTo(fPath.Path()) == B_OK) {
|
||||||
|
BEntry parentEntry;
|
||||||
|
if (entry.GetParent(&parentEntry) == B_OK && !FSIsDeskDir(&parentEntry))
|
||||||
|
SendNavigationMessage(kActionUp, &parentEntry, option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigator::SendNavigationMessage(NavigationAction action, BEntry *entry, bool option)
|
||||||
|
{
|
||||||
|
entry_ref ref;
|
||||||
|
|
||||||
|
if (entry->GetRef(&ref) == B_OK) {
|
||||||
|
BMessage message;
|
||||||
|
message.AddRef("refs", &ref);
|
||||||
|
message.AddInt32("action", action);
|
||||||
|
|
||||||
|
// get the node of this folder for selecting it in the new location
|
||||||
|
const node_ref *nodeRef;
|
||||||
|
if (Window() && Window()->TargetModel())
|
||||||
|
nodeRef = Window()->TargetModel()->NodeRef();
|
||||||
|
else
|
||||||
|
nodeRef = NULL;
|
||||||
|
|
||||||
|
// if the option key was held down, open in new window (send message to be_app)
|
||||||
|
// otherwise send message to this window. TTracker (be_app) understands nodeRefToSlection,
|
||||||
|
// BContainerWindow doesn't, so we have to select the item manually
|
||||||
|
if (option) {
|
||||||
|
message.what = B_REFS_RECEIVED;
|
||||||
|
if (nodeRef)
|
||||||
|
message.AddData("nodeRefToSelect", B_RAW_TYPE, nodeRef, sizeof(node_ref));
|
||||||
|
be_app->PostMessage(&message);
|
||||||
|
} else {
|
||||||
|
message.what = kSwitchDirectory;
|
||||||
|
Window()->PostMessage(&message);
|
||||||
|
UnlockLooper();
|
||||||
|
// This is to prevent a dead-lock situation. SelectChildInParentSoon()
|
||||||
|
// eventually locks the TaskLoop::fLock. Later, when StandAloneTaskLoop::Run()
|
||||||
|
// runs, it also locks TaskLoop::fLock and subsequently locks this window's looper.
|
||||||
|
// Therefore we can't call SelectChildInParentSoon with our Looper locked,
|
||||||
|
// because we would get different orders of locking (thus the risk of dead-locking).
|
||||||
|
//
|
||||||
|
// Todo: Change the locking behaviour of StandAloneTaskLoop::Run() and sub-
|
||||||
|
// sequently called functions.
|
||||||
|
if (nodeRef)
|
||||||
|
dynamic_cast<TTracker *>(be_app)->SelectChildInParentSoon(&ref, nodeRef);
|
||||||
|
LockLooper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigator::GoTo()
|
||||||
|
{
|
||||||
|
BString pathname = fLocation->Text();
|
||||||
|
|
||||||
|
if (pathname.Compare("") == 0)
|
||||||
|
pathname = "/";
|
||||||
|
|
||||||
|
BEntry entry;
|
||||||
|
entry_ref ref;
|
||||||
|
|
||||||
|
if (entry.SetTo(pathname.String()) == B_OK
|
||||||
|
&& !FSIsDeskDir(&entry)
|
||||||
|
&& entry.GetRef(&ref) == B_OK) {
|
||||||
|
BMessage message(kSwitchDirectory);
|
||||||
|
message.AddRef("refs", &ref);
|
||||||
|
message.AddInt32("action", kActionLocation);
|
||||||
|
Window()->PostMessage(&message);
|
||||||
|
} else {
|
||||||
|
BPath path;
|
||||||
|
|
||||||
|
if (Window()
|
||||||
|
&& Window()->TargetModel()) {
|
||||||
|
Window()->TargetModel()->GetPath(&path);
|
||||||
|
fLocation->SetText(path.Path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BNavigator::UpdateLocation(const Model *newmodel, int32 action)
|
||||||
|
{
|
||||||
|
if (newmodel)
|
||||||
|
newmodel->GetPath(&fPath);
|
||||||
|
|
||||||
|
|
||||||
|
// Modify history according to commands
|
||||||
|
switch (action) {
|
||||||
|
case kActionBackward:
|
||||||
|
fForwHistory.AddItem(fBackHistory.RemoveItemAt(fBackHistory.CountItems()-1));
|
||||||
|
break;
|
||||||
|
case kActionForward:
|
||||||
|
fBackHistory.AddItem(fForwHistory.RemoveItemAt(fForwHistory.CountItems()-1));
|
||||||
|
break;
|
||||||
|
case kActionUpdatePath:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fForwHistory.MakeEmpty();
|
||||||
|
fBackHistory.AddItem(new BPath(fPath));
|
||||||
|
|
||||||
|
for (;fBackHistory.CountItems()>kMaxHistory;)
|
||||||
|
fBackHistory.RemoveItem(fBackHistory.FirstItem(), true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable Up button when there is any parent
|
||||||
|
BEntry entry;
|
||||||
|
if (entry.SetTo(fPath.Path()) == B_OK) {
|
||||||
|
BEntry parentEntry;
|
||||||
|
fUp->SetEnabled(entry.GetParent(&parentEntry) == B_OK && !FSIsDeskDir(&parentEntry));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable history buttons if history contains something
|
||||||
|
fForw->SetEnabled(fForwHistory.CountItems() > 0);
|
||||||
|
fBack->SetEnabled(fBackHistory.CountItems() > 1);
|
||||||
|
|
||||||
|
// Avoid loss of selection and cursor position
|
||||||
|
if (action != kActionLocation)
|
||||||
|
fLocation->SetText(fPath.Path());
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
BNavigator::CalcNavigatorHeight(void)
|
||||||
|
{
|
||||||
|
// Empiric formula from how much space the textview
|
||||||
|
// will take once it is attached (using be_plain_font):
|
||||||
|
return ceilf(11.0f + be_plain_font->Size()*(1.0f + 7.0f / 30.0f));
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
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 _NAVIGATOR_H_
|
||||||
|
#define _NAVIGATOR_H_
|
||||||
|
|
||||||
|
#include "Model.h"
|
||||||
|
|
||||||
|
#include <PictureButton.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
class BTextControl;
|
||||||
|
class BEntry;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
enum NavigationAction
|
||||||
|
{
|
||||||
|
kActionSet,
|
||||||
|
kActionForward,
|
||||||
|
kActionBackward,
|
||||||
|
kActionUp,
|
||||||
|
kActionLocation,
|
||||||
|
kActionUpdatePath,
|
||||||
|
|
||||||
|
kNavigatorCommandBackward = 'NVBW',
|
||||||
|
kNavigatorCommandForward = 'NVFW',
|
||||||
|
kNavigatorCommandUp = 'NVUP',
|
||||||
|
kNavigatorCommandLocation = 'NVLC'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Custom BPictureButton which takes
|
||||||
|
// bitmap resource IDs as arguments
|
||||||
|
class BNavigatorButton : public BPictureButton {
|
||||||
|
public:
|
||||||
|
BNavigatorButton(BRect rect, const char *name, BMessage *message, int32 resIDon,
|
||||||
|
int32 resIDoff, int32 resIDdisabled);
|
||||||
|
|
||||||
|
~BNavigatorButton();
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
|
void SetPicture(BBitmap *, bool enabled, bool on);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 fResIDOn;
|
||||||
|
int32 fResIDOff;
|
||||||
|
int32 fResIDDisabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BNavigator : public BView {
|
||||||
|
public:
|
||||||
|
BNavigator(const Model *model, BRect rect, uint32 resizeMask = B_FOLLOW_LEFT_RIGHT);
|
||||||
|
~BNavigator();
|
||||||
|
|
||||||
|
void UpdateLocation(const Model *newmodel, int32 action);
|
||||||
|
|
||||||
|
static float CalcNavigatorHeight(void);
|
||||||
|
|
||||||
|
BContainerWindow *Window() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void Draw(BRect rect);
|
||||||
|
virtual void MessageReceived(BMessage *msg);
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
|
||||||
|
void GoForward(bool option); // is option key held down?
|
||||||
|
void GoBackward(bool option);
|
||||||
|
void GoUp(bool option);
|
||||||
|
void SendNavigationMessage(NavigationAction, BEntry *, bool option);
|
||||||
|
|
||||||
|
void GoTo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
BPath fPath;
|
||||||
|
BNavigatorButton *fBack;
|
||||||
|
BNavigatorButton *fForw;
|
||||||
|
BNavigatorButton *fUp;
|
||||||
|
BTextControl *fLocation;
|
||||||
|
|
||||||
|
BObjectList<BPath> fBackHistory;
|
||||||
|
BObjectList<BPath> fForwHistory;
|
||||||
|
|
||||||
|
typedef BView _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline
|
||||||
|
BContainerWindow *
|
||||||
|
BNavigator::Window() const
|
||||||
|
{
|
||||||
|
return dynamic_cast<BContainerWindow *>(_inherited::Window());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NodePreloader manages caching up icons from apps and prefs folder for
|
||||||
|
// fast display
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <Node.h>
|
||||||
|
#include <NodeMonitor.h>
|
||||||
|
#include <Path.h>
|
||||||
|
|
||||||
|
#include "AutoLock.h"
|
||||||
|
#include "IconCache.h"
|
||||||
|
#include "NodePreloader.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
|
||||||
|
|
||||||
|
NodePreloader *
|
||||||
|
NodePreloader::InstallNodePreloader(const char *name, BLooper *host)
|
||||||
|
{
|
||||||
|
NodePreloader *result = new NodePreloader(name);
|
||||||
|
{
|
||||||
|
AutoLock<BLooper> lock(host);
|
||||||
|
if (!lock)
|
||||||
|
return NULL;
|
||||||
|
host->AddHandler(result);
|
||||||
|
}
|
||||||
|
result->Run();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NodePreloader::NodePreloader(const char *name)
|
||||||
|
: BHandler(name),
|
||||||
|
fModelList(20, true),
|
||||||
|
fQuitRequested(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NodePreloader::~NodePreloader()
|
||||||
|
{
|
||||||
|
// block deletion while we are locked
|
||||||
|
fQuitRequested = true;
|
||||||
|
fLock.Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NodePreloader::Run()
|
||||||
|
{
|
||||||
|
fLock.Lock();
|
||||||
|
Thread::Launch(NewMemberFunctionObject(&NodePreloader::Preload, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Model *
|
||||||
|
NodePreloader::FindModel(node_ref itemNode) const
|
||||||
|
{
|
||||||
|
for (int32 count = fModelList.CountItems() - 1; count >= 0; count--) {
|
||||||
|
Model *model = fModelList.ItemAt(count);
|
||||||
|
if (*model->NodeRef() == itemNode)
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NodePreloader::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
// respond to node monitor notifications
|
||||||
|
|
||||||
|
node_ref itemNode;
|
||||||
|
switch (message->what) {
|
||||||
|
case B_NODE_MONITOR:
|
||||||
|
switch (message->FindInt32("opcode")) {
|
||||||
|
case B_ENTRY_REMOVED:
|
||||||
|
{
|
||||||
|
AutoLock<Benaphore> locker(fLock);
|
||||||
|
message->FindInt32("device", &itemNode.device);
|
||||||
|
message->FindInt64("node", &itemNode.node);
|
||||||
|
Model *model = FindModel(itemNode);
|
||||||
|
if (!model)
|
||||||
|
break;
|
||||||
|
// PRINT(("preloader removing file %s\n", model->Name()));
|
||||||
|
IconCache::sIconCache->Removing(model);
|
||||||
|
fModelList.RemoveItem(model);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_ATTR_CHANGED:
|
||||||
|
case B_STAT_CHANGED:
|
||||||
|
{
|
||||||
|
AutoLock<Benaphore> locker(fLock);
|
||||||
|
message->FindInt32("device", &itemNode.device);
|
||||||
|
message->FindInt64("node", &itemNode.node);
|
||||||
|
|
||||||
|
const char *attrName;
|
||||||
|
message->FindString("attr", &attrName);
|
||||||
|
Model *model = FindModel(itemNode);
|
||||||
|
if (!model)
|
||||||
|
break;
|
||||||
|
BModelOpener opener(model);
|
||||||
|
IconCache::sIconCache->IconChanged(model->ResolveIfLink());
|
||||||
|
// PRINT(("preloader updating file %s\n", model->Name()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_inherited::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NodePreloader::PreloadOne(const char *dirPath)
|
||||||
|
{
|
||||||
|
// PRINT(("preloading directory %s\n", dirPath));
|
||||||
|
BDirectory dir(dirPath);
|
||||||
|
if (!dir.InitCheck() == B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node_ref nodeRef;
|
||||||
|
dir.GetNodeRef(&nodeRef);
|
||||||
|
|
||||||
|
// have to node monitor the whole directory
|
||||||
|
TTracker::WatchNode(&nodeRef, B_WATCH_DIRECTORY, this);
|
||||||
|
|
||||||
|
dir.Rewind();
|
||||||
|
for (;;) {
|
||||||
|
entry_ref ref;
|
||||||
|
if (dir.GetNextRef(&ref) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BEntry entry(&ref);
|
||||||
|
if (!entry.IsFile())
|
||||||
|
// only interrested in files
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Model *model = new Model(&ref, true);
|
||||||
|
if (model->InitCheck() == B_OK && model->IconFrom() == kUnknownSource) {
|
||||||
|
TTracker::WatchNode(model->NodeRef(), B_WATCH_STAT
|
||||||
|
| B_WATCH_ATTR, this);
|
||||||
|
IconCache::sIconCache->Preload(model, kNormalIcon, B_MINI_ICON, true);
|
||||||
|
fModelList.AddItem(model);
|
||||||
|
model->CloseNode();
|
||||||
|
} else
|
||||||
|
delete model;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
NodePreloader::Preload()
|
||||||
|
{
|
||||||
|
for (int32 count = 100; count >= 0; count--) {
|
||||||
|
// wait for a little bit before going ahead to reduce disk access contention
|
||||||
|
snooze(100000);
|
||||||
|
if (fQuitRequested) {
|
||||||
|
fLock.Unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BMessenger messenger(kTrackerSignature);
|
||||||
|
if (!messenger.IsValid()) {
|
||||||
|
// put out some message here!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(fLock.IsLocked());
|
||||||
|
BPath path;
|
||||||
|
if (find_directory(B_BEOS_APPS_DIRECTORY, &path) == B_OK)
|
||||||
|
PreloadOne(path.Path());
|
||||||
|
if (find_directory(B_BEOS_PREFERENCES_DIRECTORY, &path) == B_OK)
|
||||||
|
PreloadOne(path.Path());
|
||||||
|
|
||||||
|
fLock.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Copyright 1997, 1998, Be Incorporated, All Rights Reserved.
|
||||||
|
//
|
||||||
|
// NodePreloader manages caching up icons from apps and prefs folder for
|
||||||
|
// fast display of the app/prefs nav menus
|
||||||
|
//
|
||||||
|
// Icons end up in the node cache as permanent entries -- to be able
|
||||||
|
// to do this, each entry has to be node monitored to avoid inode
|
||||||
|
// aliasing after a deletion, etc.
|
||||||
|
//
|
||||||
|
// The node preloader knows which icons to preload
|
||||||
|
|
||||||
|
#ifndef __NODE_CACHE_PRELOADER__
|
||||||
|
#define __NODE_CACHE_PRELOADER__
|
||||||
|
|
||||||
|
#include <Handler.h>
|
||||||
|
|
||||||
|
#include "ObjectList.h"
|
||||||
|
#include "Model.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class NodePreloader : public BHandler {
|
||||||
|
public:
|
||||||
|
static NodePreloader *InstallNodePreloader(const char *name, BLooper *host);
|
||||||
|
virtual ~NodePreloader();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NodePreloader(const char *name);
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
void Run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void PreloadOne(const char *dirPath);
|
||||||
|
virtual void Preload();
|
||||||
|
// for now just preload apps and prefs
|
||||||
|
Model *FindModel(node_ref) const;
|
||||||
|
|
||||||
|
|
||||||
|
BObjectList<Model> fModelList;
|
||||||
|
Benaphore fLock;
|
||||||
|
volatile bool fQuitRequested;
|
||||||
|
|
||||||
|
typedef BHandler _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,697 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include "NodeWalker.h"
|
||||||
|
|
||||||
|
namespace BTrackerPrivate {
|
||||||
|
|
||||||
|
TWalker::~TWalker()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// all the following calls are pure viruals, should not get called
|
||||||
|
status_t
|
||||||
|
TWalker::GetNextEntry(BEntry *, bool )
|
||||||
|
{
|
||||||
|
TRESPASS();
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TWalker::GetNextRef(entry_ref *)
|
||||||
|
{
|
||||||
|
TRESPASS();
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
TWalker::GetNextDirents(struct dirent *, size_t, int32)
|
||||||
|
{
|
||||||
|
TRESPASS();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TWalker::Rewind()
|
||||||
|
{
|
||||||
|
TRESPASS();
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
TWalker::CountEntries()
|
||||||
|
{
|
||||||
|
TRESPASS();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNodeWalker::TNodeWalker(bool includeTopDirectory)
|
||||||
|
: fDirs(20),
|
||||||
|
fTopIndex(-1),
|
||||||
|
fTopDir(0),
|
||||||
|
fIncludeTopDir(includeTopDirectory),
|
||||||
|
fOriginalIncludeTopDir(includeTopDirectory),
|
||||||
|
fJustFile(0),
|
||||||
|
fOriginalJustFile(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNodeWalker::TNodeWalker(const char *path, bool includeTopDirectory)
|
||||||
|
: fDirs(20),
|
||||||
|
fTopIndex(-1),
|
||||||
|
fTopDir(0),
|
||||||
|
fIncludeTopDir(includeTopDirectory),
|
||||||
|
fOriginalIncludeTopDir(includeTopDirectory),
|
||||||
|
fJustFile(0),
|
||||||
|
fOriginalDirCopy(path),
|
||||||
|
fOriginalJustFile(0)
|
||||||
|
{
|
||||||
|
if (fOriginalDirCopy.InitCheck() != B_OK) {
|
||||||
|
// not a directory, set up walking a single file
|
||||||
|
fJustFile = new BEntry(path);
|
||||||
|
if (fJustFile->InitCheck() != B_OK) {
|
||||||
|
delete fJustFile;
|
||||||
|
fJustFile = NULL;
|
||||||
|
}
|
||||||
|
fOriginalJustFile = fJustFile;
|
||||||
|
} else {
|
||||||
|
fTopDir = new BDirectory(fOriginalDirCopy);
|
||||||
|
fTopIndex++;
|
||||||
|
fDirs.AddItem(fTopDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNodeWalker::TNodeWalker(const entry_ref *ref, bool includeTopDirectory)
|
||||||
|
: fDirs(20),
|
||||||
|
fTopIndex(-1),
|
||||||
|
fTopDir(0),
|
||||||
|
fIncludeTopDir(includeTopDirectory),
|
||||||
|
fOriginalIncludeTopDir(includeTopDirectory),
|
||||||
|
fJustFile(0),
|
||||||
|
fOriginalDirCopy(ref),
|
||||||
|
fOriginalJustFile(0)
|
||||||
|
{
|
||||||
|
if (fOriginalDirCopy.InitCheck() != B_OK) {
|
||||||
|
// not a directory, set up walking a single file
|
||||||
|
fJustFile = new BEntry(ref);
|
||||||
|
if (fJustFile->InitCheck() != B_OK) {
|
||||||
|
delete fJustFile;
|
||||||
|
fJustFile = NULL;
|
||||||
|
}
|
||||||
|
fOriginalJustFile = fJustFile;
|
||||||
|
} else {
|
||||||
|
fTopDir = new BDirectory(fOriginalDirCopy);
|
||||||
|
fTopIndex++;
|
||||||
|
fDirs.AddItem(fTopDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNodeWalker::TNodeWalker(const BDirectory *dir, bool includeTopDirectory)
|
||||||
|
: fDirs(20),
|
||||||
|
fTopIndex(-1),
|
||||||
|
fTopDir(0),
|
||||||
|
fIncludeTopDir(includeTopDirectory),
|
||||||
|
fOriginalIncludeTopDir(includeTopDirectory),
|
||||||
|
fJustFile(0),
|
||||||
|
fOriginalDirCopy(*dir),
|
||||||
|
fOriginalJustFile(0)
|
||||||
|
{
|
||||||
|
fTopDir = new BDirectory(*dir);
|
||||||
|
fTopIndex++;
|
||||||
|
fDirs.AddItem(fTopDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNodeWalker::TNodeWalker()
|
||||||
|
: fDirs(20),
|
||||||
|
fTopIndex(-1),
|
||||||
|
fTopDir(0),
|
||||||
|
fIncludeTopDir(false),
|
||||||
|
fOriginalIncludeTopDir(false),
|
||||||
|
fJustFile(0),
|
||||||
|
fOriginalJustFile(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TNodeWalker::TNodeWalker(const char *path)
|
||||||
|
: fDirs(20),
|
||||||
|
fTopIndex(-1),
|
||||||
|
fTopDir(0),
|
||||||
|
fIncludeTopDir(false),
|
||||||
|
fOriginalIncludeTopDir(false),
|
||||||
|
fJustFile(0),
|
||||||
|
fOriginalDirCopy(path),
|
||||||
|
fOriginalJustFile(0)
|
||||||
|
{
|
||||||
|
if (fOriginalDirCopy.InitCheck() != B_OK) {
|
||||||
|
// not a directory, set up walking a single file
|
||||||
|
fJustFile = new BEntry(path);
|
||||||
|
if (fJustFile->InitCheck() != B_OK) {
|
||||||
|
delete fJustFile;
|
||||||
|
fJustFile = NULL;
|
||||||
|
}
|
||||||
|
fOriginalJustFile = fJustFile;
|
||||||
|
} else {
|
||||||
|
fTopDir = new BDirectory(fOriginalDirCopy);
|
||||||
|
fTopIndex++;
|
||||||
|
fDirs.AddItem(fTopDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TNodeWalker::TNodeWalker(const entry_ref *ref)
|
||||||
|
: fDirs(20),
|
||||||
|
fTopIndex(-1),
|
||||||
|
fTopDir(0),
|
||||||
|
fIncludeTopDir(false),
|
||||||
|
fOriginalIncludeTopDir(false),
|
||||||
|
fJustFile(0),
|
||||||
|
fOriginalDirCopy(ref),
|
||||||
|
fOriginalJustFile(0)
|
||||||
|
{
|
||||||
|
if (fOriginalDirCopy.InitCheck() != B_OK) {
|
||||||
|
// not a directory, set up walking a single file
|
||||||
|
fJustFile = new BEntry(ref);
|
||||||
|
if (fJustFile->InitCheck() != B_OK) {
|
||||||
|
delete fJustFile;
|
||||||
|
fJustFile = NULL;
|
||||||
|
}
|
||||||
|
fOriginalJustFile = fJustFile;
|
||||||
|
} else {
|
||||||
|
fTopDir = new BDirectory(fOriginalDirCopy);
|
||||||
|
fTopIndex++;
|
||||||
|
fDirs.AddItem(fTopDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TNodeWalker::TNodeWalker(const BDirectory *dir)
|
||||||
|
: fDirs(20),
|
||||||
|
fTopIndex(-1),
|
||||||
|
fTopDir(0),
|
||||||
|
fIncludeTopDir(false),
|
||||||
|
fOriginalIncludeTopDir(false),
|
||||||
|
fJustFile(0),
|
||||||
|
fOriginalDirCopy(*dir),
|
||||||
|
fOriginalJustFile(0)
|
||||||
|
{
|
||||||
|
fTopDir = new BDirectory(*dir);
|
||||||
|
fTopIndex++;
|
||||||
|
fDirs.AddItem(fTopDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
TNodeWalker::~TNodeWalker()
|
||||||
|
{
|
||||||
|
delete fOriginalJustFile;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
BDirectory *directory = fDirs.RemoveItemAt(fTopIndex--);
|
||||||
|
if (directory == NULL)
|
||||||
|
break;
|
||||||
|
delete directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TNodeWalker::PopDirCommon()
|
||||||
|
{
|
||||||
|
ASSERT(fTopIndex >= 0);
|
||||||
|
|
||||||
|
// done with the old dir, pop it
|
||||||
|
fDirs.RemoveItemAt(fTopIndex);
|
||||||
|
fTopIndex--;
|
||||||
|
delete fTopDir;
|
||||||
|
fTopDir = NULL;
|
||||||
|
|
||||||
|
if (fTopIndex == -1)
|
||||||
|
// done
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
// point to the new top dir
|
||||||
|
fTopDir = fDirs.ItemAt(fTopIndex);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TNodeWalker::PushDirCommon(const entry_ref *ref)
|
||||||
|
{
|
||||||
|
fTopDir = new BDirectory(ref);
|
||||||
|
// OK to ignore error here. Will
|
||||||
|
// catch at next call to GetNextEntry
|
||||||
|
fTopIndex++;
|
||||||
|
fDirs.AddItem(fTopDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TNodeWalker::GetNextEntry(BEntry *entry, bool traverse)
|
||||||
|
{
|
||||||
|
if (fJustFile) {
|
||||||
|
*entry = *fJustFile;
|
||||||
|
fJustFile = 0;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fTopDir)
|
||||||
|
// done
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
// If requested to include the top directory, return that first.
|
||||||
|
if (fIncludeTopDir) {
|
||||||
|
fIncludeTopDir = false;
|
||||||
|
return fTopDir->GetEntry(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next entry.
|
||||||
|
status_t err = fTopDir->GetNextEntry(entry, traverse);
|
||||||
|
|
||||||
|
if (err != B_OK) {
|
||||||
|
err = PopDirCommon();
|
||||||
|
if (err != B_OK)
|
||||||
|
return err;
|
||||||
|
return GetNextEntry(entry, traverse);
|
||||||
|
}
|
||||||
|
// See if this entry is a directory. If it is then push it onto the
|
||||||
|
// stack
|
||||||
|
entry_ref ref;
|
||||||
|
err = entry->GetRef(&ref);
|
||||||
|
|
||||||
|
if (err == B_OK && fTopDir->Contains(ref.name, B_DIRECTORY_NODE))
|
||||||
|
PushDirCommon(&ref);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TNodeWalker::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
if (fJustFile) {
|
||||||
|
fJustFile->GetRef(ref);
|
||||||
|
fJustFile = 0;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fTopDir)
|
||||||
|
// done
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
// If requested to include the top directory, return that first.
|
||||||
|
if (fIncludeTopDir) {
|
||||||
|
fIncludeTopDir = false;
|
||||||
|
BEntry entry;
|
||||||
|
status_t err = fTopDir->GetEntry(&entry);
|
||||||
|
if (err == B_OK)
|
||||||
|
err = entry.GetRef(ref);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next entry.
|
||||||
|
status_t err = fTopDir->GetNextRef(ref);
|
||||||
|
if (err != B_OK) {
|
||||||
|
err = PopDirCommon();
|
||||||
|
if (err != B_OK)
|
||||||
|
return err;
|
||||||
|
return GetNextRef(ref);
|
||||||
|
}
|
||||||
|
// See if this entry is a directory. If it is then push it onto the
|
||||||
|
// stack
|
||||||
|
|
||||||
|
if (fTopDir->Contains(ref->name, B_DIRECTORY_NODE))
|
||||||
|
PushDirCommon(ref);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32
|
||||||
|
build_dirent(const BEntry *source, struct dirent *ent,
|
||||||
|
size_t size, int32 count)
|
||||||
|
{
|
||||||
|
entry_ref ref;
|
||||||
|
source->GetRef(&ref);
|
||||||
|
|
||||||
|
size_t recordLength = strlen(ref.name) + sizeof(dirent);
|
||||||
|
if (recordLength > size || count <= 0)
|
||||||
|
// can't fit in buffer, bail
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// info about this node
|
||||||
|
ent->d_reclen = static_cast<ushort>(recordLength);
|
||||||
|
strcpy(ent->d_name, ref.name);
|
||||||
|
ent->d_dev = ref.device;
|
||||||
|
ent->d_ino = ref.directory;
|
||||||
|
|
||||||
|
// info about the parent
|
||||||
|
BEntry parent;
|
||||||
|
source->GetParent(&parent);
|
||||||
|
if (parent.InitCheck() == B_OK) {
|
||||||
|
entry_ref parentRef;
|
||||||
|
parent.GetRef(&parentRef);
|
||||||
|
ent->d_pdev = parentRef.device;
|
||||||
|
ent->d_pino = parentRef.directory;
|
||||||
|
} else {
|
||||||
|
ent->d_pdev = 0;
|
||||||
|
ent->d_pino = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
TNodeWalker::GetNextDirents(struct dirent *ent, size_t size, int32 count)
|
||||||
|
{
|
||||||
|
if (fJustFile) {
|
||||||
|
if (!count)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// simulate GetNextDirents by building a single dirent structure
|
||||||
|
int32 result = build_dirent(fJustFile, ent, size, count);
|
||||||
|
fJustFile = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fTopDir)
|
||||||
|
// done
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// If requested to include the top directory, return that first.
|
||||||
|
if (fIncludeTopDir) {
|
||||||
|
fIncludeTopDir = false;
|
||||||
|
BEntry entry;
|
||||||
|
if (fTopDir->GetEntry(&entry) < B_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return build_dirent(fJustFile, ent, size, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next entry.
|
||||||
|
int32 result = fTopDir->GetNextDirents(ent, size, count);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
status_t err = PopDirCommon();
|
||||||
|
if (err != B_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return GetNextDirents(ent, size, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// push any directories in the returned entries onto the stack
|
||||||
|
for (int32 i = 0; i < result; i++) {
|
||||||
|
if (fTopDir->Contains(ent->d_name, B_DIRECTORY_NODE)) {
|
||||||
|
entry_ref ref(ent->d_dev, ent->d_ino, ent->d_name);
|
||||||
|
PushDirCommon(&ref);
|
||||||
|
}
|
||||||
|
ent = (dirent *)((char *)ent + ent->d_reclen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TNodeWalker::Rewind()
|
||||||
|
{
|
||||||
|
if (fOriginalJustFile) {
|
||||||
|
// single file mode, rewind by pointing to the original file
|
||||||
|
fJustFile = fOriginalJustFile;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pop all the directories and point to the initial one
|
||||||
|
for (;;) {
|
||||||
|
BDirectory *directory = fDirs.RemoveItemAt(fTopIndex--);
|
||||||
|
if (!directory)
|
||||||
|
break;
|
||||||
|
delete directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
fTopDir = new BDirectory(fOriginalDirCopy);
|
||||||
|
fTopIndex = 0;
|
||||||
|
fIncludeTopDir = fOriginalIncludeTopDir;
|
||||||
|
fDirs.AddItem(fTopDir);
|
||||||
|
// rewind the directory
|
||||||
|
return fTopDir->Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
TNodeWalker::CountEntries()
|
||||||
|
{
|
||||||
|
// should not be calling this
|
||||||
|
TRESPASS();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TVolWalker::TVolWalker(bool knowsAttributes, bool writable, bool includeTopDirectory)
|
||||||
|
: TNodeWalker(includeTopDirectory),
|
||||||
|
fKnowsAttr(knowsAttributes),
|
||||||
|
fWritable(writable)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get things initialized. Find first volume, or find the first volume
|
||||||
|
that supports attributes.
|
||||||
|
*/
|
||||||
|
NextVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
TVolWalker::~TVolWalker()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TVolWalker::NextVolume()
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
|
||||||
|
// The stack of directoies should be empty.
|
||||||
|
ASSERT(fTopIndex == -1);
|
||||||
|
ASSERT(fTopDir == NULL);
|
||||||
|
|
||||||
|
do {
|
||||||
|
err = fVolRoster.GetNextVolume(&fVol);
|
||||||
|
if (err != B_OK)
|
||||||
|
break;
|
||||||
|
} while ((fKnowsAttr && !fVol.KnowsAttr()) || (fWritable && fVol.IsReadOnly()));
|
||||||
|
|
||||||
|
if (err == B_OK) {
|
||||||
|
// Get the root directory to get things started. There's always
|
||||||
|
// a root directory for a volume. So if there is an error then it
|
||||||
|
// means that something is really bad, like the system is out of
|
||||||
|
// memory. In that case don't worry about truying to skip to the
|
||||||
|
// next volume.
|
||||||
|
fTopDir = new BDirectory();
|
||||||
|
err = fVol.GetRootDirectory(fTopDir);
|
||||||
|
fIncludeTopDir = fOriginalIncludeTopDir;
|
||||||
|
fTopIndex = 0;
|
||||||
|
fDirs.AddItem(fTopDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TVolWalker::GetNextEntry(BEntry *entry, bool traverse)
|
||||||
|
{
|
||||||
|
if (!fTopDir)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
// Get the next entry.
|
||||||
|
status_t err = _inherited::GetNextEntry(entry, traverse);
|
||||||
|
|
||||||
|
while (err != B_OK) {
|
||||||
|
// We're done with the current volume. Go to the next one
|
||||||
|
err = NextVolume();
|
||||||
|
if (err != B_OK)
|
||||||
|
break;
|
||||||
|
err = GetNextEntry(entry, traverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TVolWalker::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
if (!fTopDir)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
// Get the next ref.
|
||||||
|
status_t err = _inherited::GetNextRef(ref);
|
||||||
|
|
||||||
|
while (err != B_OK) {
|
||||||
|
// We're done with the current volume. Go to the next one
|
||||||
|
err = NextVolume();
|
||||||
|
if (err != B_OK)
|
||||||
|
break;
|
||||||
|
err = GetNextRef(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
TVolWalker::GetNextDirents(struct dirent *ent, size_t size, int32 count)
|
||||||
|
{
|
||||||
|
if (!fTopDir)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
// Get the next dirent.
|
||||||
|
status_t err = _inherited::GetNextDirents(ent, size, count);
|
||||||
|
|
||||||
|
while (err != B_OK) {
|
||||||
|
// We're done with the current volume. Go to the next one
|
||||||
|
err = NextVolume();
|
||||||
|
if (err != B_OK)
|
||||||
|
break;
|
||||||
|
err = GetNextDirents(ent, size, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TVolWalker::Rewind()
|
||||||
|
{
|
||||||
|
fVolRoster.Rewind();
|
||||||
|
return NextVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
TQueryWalker::TQueryWalker(const char *predicate)
|
||||||
|
: TWalker(), fQuery(), fVolRoster(), fVol()
|
||||||
|
{
|
||||||
|
fPredicate = strdup(predicate);
|
||||||
|
NextVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
TQueryWalker::~TQueryWalker()
|
||||||
|
{
|
||||||
|
free((char*) fPredicate);
|
||||||
|
fPredicate = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TQueryWalker::GetNextEntry(BEntry *entry, bool traverse)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
|
||||||
|
do {
|
||||||
|
err = fQuery.GetNextEntry(entry, traverse);
|
||||||
|
if (err == B_ENTRY_NOT_FOUND) {
|
||||||
|
if (NextVolume() != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (err == B_ENTRY_NOT_FOUND);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TQueryWalker::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
err = fQuery.GetNextRef(ref);
|
||||||
|
if (err != B_ENTRY_NOT_FOUND)
|
||||||
|
break;
|
||||||
|
|
||||||
|
err = NextVolume();
|
||||||
|
if (err != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
TQueryWalker::GetNextDirents(struct dirent *ent, size_t size, int32 count)
|
||||||
|
{
|
||||||
|
int32 result;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
result = fQuery.GetNextDirents(ent, size, count);
|
||||||
|
if (result != 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (NextVolume() != B_OK)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TQueryWalker::NextVolume()
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
do {
|
||||||
|
err = fVolRoster.GetNextVolume(&fVol);
|
||||||
|
if (err)
|
||||||
|
break;
|
||||||
|
} while (!fVol.KnowsQuery());
|
||||||
|
|
||||||
|
|
||||||
|
if (err == B_OK) {
|
||||||
|
err = fQuery.Clear();
|
||||||
|
err = fQuery.SetVolume(&fVol);
|
||||||
|
err = fQuery.SetPredicate(fPredicate);
|
||||||
|
err = fQuery.Fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
TQueryWalker::CountEntries()
|
||||||
|
{
|
||||||
|
// should not be calling this
|
||||||
|
TRESPASS();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
TQueryWalker::Rewind()
|
||||||
|
{
|
||||||
|
fVolRoster.Rewind();
|
||||||
|
return NextVolume();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BTrackerPrivate
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !OPEN_TRACKER
|
||||||
|
|
||||||
|
#include <private/storage/walker.h>
|
||||||
|
|
||||||
|
#define WALKER_NS
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef WALKER_H
|
||||||
|
#define WALKER_H
|
||||||
|
|
||||||
|
#ifndef _BE_BUILD_H
|
||||||
|
#include <BeBuild.h>
|
||||||
|
#endif
|
||||||
|
#include <VolumeRoster.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <EntryList.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Query.h>
|
||||||
|
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
namespace BTrackerPrivate {
|
||||||
|
#define WALKER_NS BTrackerPrivate
|
||||||
|
|
||||||
|
|
||||||
|
class TWalker : public BEntryList {
|
||||||
|
// adds a virtual destructor that is severely missing in BEntryList
|
||||||
|
// BEntryList should never be used polymorphically because of that
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~TWalker();
|
||||||
|
|
||||||
|
virtual status_t GetNextEntry(BEntry *, bool traverse = false) = 0;
|
||||||
|
virtual status_t GetNextRef(entry_ref *) = 0;
|
||||||
|
virtual int32 GetNextDirents(struct dirent *, size_t,
|
||||||
|
int32 count = INT_MAX) = 0;
|
||||||
|
virtual status_t Rewind() = 0;
|
||||||
|
virtual int32 CountEntries() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TNodeWalker : public TWalker {
|
||||||
|
// TNodeWalker supports iterating a single volume, starting from a specified
|
||||||
|
// entry; if passed a non-directory entry it returns just that one entry
|
||||||
|
public:
|
||||||
|
TNodeWalker(bool includeTopDirectory);
|
||||||
|
TNodeWalker(const char *path, bool includeTopDirectory);
|
||||||
|
TNodeWalker(const entry_ref *ref, bool includeTopDirectory);
|
||||||
|
TNodeWalker(const BDirectory *dir, bool includeTopDirectory);
|
||||||
|
virtual ~TNodeWalker();
|
||||||
|
|
||||||
|
// Backwards compatibility with Tracker compiled for R5 (remove when this
|
||||||
|
// gets integrated into the official release).
|
||||||
|
TNodeWalker();
|
||||||
|
TNodeWalker(const char *path);
|
||||||
|
TNodeWalker(const entry_ref *ref);
|
||||||
|
TNodeWalker(const BDirectory *dir);
|
||||||
|
|
||||||
|
virtual status_t GetNextEntry(BEntry *, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *, size_t,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
virtual status_t Rewind();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
status_t PopDirCommon();
|
||||||
|
void PushDirCommon(const entry_ref *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual int32 CountEntries();
|
||||||
|
// don't know how to do that, have just a fake stub here
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BObjectList<BDirectory> fDirs;
|
||||||
|
int32 fTopIndex;
|
||||||
|
BDirectory *fTopDir;
|
||||||
|
bool fIncludeTopDir;
|
||||||
|
bool fOriginalIncludeTopDir;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BEntry *fJustFile;
|
||||||
|
BDirectory fOriginalDirCopy;
|
||||||
|
BEntry *fOriginalJustFile;
|
||||||
|
// keep around to support Rewind
|
||||||
|
};
|
||||||
|
|
||||||
|
class TVolWalker : public TNodeWalker {
|
||||||
|
// TNodeWalker supports iterating over all the mounted volumes;
|
||||||
|
// non-attribute and read-only volumes may optionaly be filtered out
|
||||||
|
public:
|
||||||
|
TVolWalker(bool knows_attr = true, bool writable = true,
|
||||||
|
bool includeTopDirectory = true);
|
||||||
|
virtual ~TVolWalker();
|
||||||
|
|
||||||
|
virtual status_t GetNextEntry(BEntry *, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *, size_t,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
virtual status_t Rewind();
|
||||||
|
|
||||||
|
virtual status_t NextVolume();
|
||||||
|
// skips to the next volume
|
||||||
|
// Note: it would be cool to return const BVolume *
|
||||||
|
// that way a subclass could implement a volume filter -
|
||||||
|
// it would just override, call inherited for as long as there
|
||||||
|
// are volumes and it does not like them
|
||||||
|
// we would have to give up the status_t then, which might be
|
||||||
|
// ok
|
||||||
|
|
||||||
|
private:
|
||||||
|
BVolumeRoster fVolRoster;
|
||||||
|
BVolume fVol;
|
||||||
|
bool fKnowsAttr;
|
||||||
|
bool fWritable;
|
||||||
|
|
||||||
|
typedef TNodeWalker _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TQueryWalker : public TWalker {
|
||||||
|
public:
|
||||||
|
TQueryWalker(const char *predicate);
|
||||||
|
virtual ~TQueryWalker();
|
||||||
|
|
||||||
|
// Does an in-fix walk of all entries
|
||||||
|
virtual status_t GetNextEntry(BEntry *, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *, size_t,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
|
||||||
|
virtual status_t NextVolume();
|
||||||
|
// skips to the next volume
|
||||||
|
virtual status_t Rewind();
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual int32 CountEntries();
|
||||||
|
// can't count
|
||||||
|
|
||||||
|
BQuery fQuery;
|
||||||
|
BVolumeRoster fVolRoster;
|
||||||
|
BVolume fVol;
|
||||||
|
bigtime_t fTime;
|
||||||
|
const char *fPredicate;
|
||||||
|
|
||||||
|
typedef TQueryWalker _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BTrackerPrivate
|
||||||
|
|
||||||
|
using namespace BTrackerPrivate;
|
||||||
|
|
||||||
|
#endif // WALKER_H
|
||||||
|
|
||||||
|
#endif // B_BEOS_VERSION_DANO
|
||||||
@@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Hash table with open addresssing
|
||||||
|
|
||||||
|
#ifndef __OPEN_HASH_TABLE__
|
||||||
|
#define __OPEN_HASH_TABLE__
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <new.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
template <class Element>
|
||||||
|
class ElementVector {
|
||||||
|
// element vector for OpenHashTable needs to implement this
|
||||||
|
// interface
|
||||||
|
public:
|
||||||
|
Element &At(int32 index);
|
||||||
|
Element *Add();
|
||||||
|
int32 IndexOf(const Element &) const;
|
||||||
|
void Remove(int32 index);
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenHashElement {
|
||||||
|
public:
|
||||||
|
uint32 Hash() const;
|
||||||
|
bool operator==(const OpenHashElement &) const;
|
||||||
|
void Adopt(OpenHashElement &);
|
||||||
|
// low overhead copy, original element is in undefined state
|
||||||
|
// after call (calls Adopt on BString members, etc.)
|
||||||
|
int32 fNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32 kPrimes [] = {
|
||||||
|
509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139,
|
||||||
|
524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, 67108859,
|
||||||
|
134217689, 268435399, 536870909, 1073741789, 2147483647, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Element, class ElementVec = ElementVector<Element> >
|
||||||
|
class OpenHashTable {
|
||||||
|
public:
|
||||||
|
OpenHashTable(int32 minSize, ElementVec *elementVector = 0);
|
||||||
|
// it is up to the subclass of OpenHashTable to supply
|
||||||
|
// elementVector
|
||||||
|
~OpenHashTable();
|
||||||
|
|
||||||
|
void SetElementVector(ElementVec *elementVector);
|
||||||
|
|
||||||
|
Element *FindFirst(uint32 elementHash) const;
|
||||||
|
Element &Add(uint32 elementHash);
|
||||||
|
|
||||||
|
void Remove(Element *);
|
||||||
|
|
||||||
|
// when calling Add, any outstanding element pointer may become
|
||||||
|
// invalid; to deal with this, get the element index and restore
|
||||||
|
// it after the add
|
||||||
|
int32 ElementIndex(const Element *) const;
|
||||||
|
Element *ElementAt(int32 index) const;
|
||||||
|
|
||||||
|
int32 VectorSize() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static int32 OptimalSize(int32 minSize);
|
||||||
|
|
||||||
|
int32 fArraySize;
|
||||||
|
int32 *fHashArray;
|
||||||
|
ElementVec *fElementVector;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Element>
|
||||||
|
class OpenHashElementArray : public ElementVector<Element> {
|
||||||
|
// this is a straightforward implementation of an element vector
|
||||||
|
// deleting is handled by linking deleted elements into a free list
|
||||||
|
// the vector never shrinks
|
||||||
|
public:
|
||||||
|
OpenHashElementArray(int32 initialSize);
|
||||||
|
~OpenHashElementArray();
|
||||||
|
|
||||||
|
Element &At(int32 index);
|
||||||
|
const Element &At(int32 index) const;
|
||||||
|
int32 Add(const Element &);
|
||||||
|
int32 Add();
|
||||||
|
void Remove(int32 index);
|
||||||
|
int32 IndexOf(const Element &) const;
|
||||||
|
int32 Size() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Element *fData;
|
||||||
|
int32 fSize;
|
||||||
|
int32 fNextFree;
|
||||||
|
int32 fNextDeleted;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//--- inline implementation --------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
OpenHashTable<Element, ElementVec>::OpenHashTable(int32 minSize,ElementVec *elementVector)
|
||||||
|
:
|
||||||
|
fArraySize(OptimalSize(minSize)),
|
||||||
|
fElementVector(elementVector)
|
||||||
|
{
|
||||||
|
fHashArray = new int32[fArraySize];
|
||||||
|
for (int32 index = 0; index < fArraySize; index++)
|
||||||
|
fHashArray[index] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
OpenHashTable<Element, ElementVec>::~OpenHashTable()
|
||||||
|
{
|
||||||
|
delete fHashArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
int32
|
||||||
|
OpenHashTable<Element, ElementVec>::OptimalSize(int32 minSize)
|
||||||
|
{
|
||||||
|
for (int32 index = 0; ; index++)
|
||||||
|
if (!kPrimes[index] || kPrimes[index] >= (uint32)minSize)
|
||||||
|
return (int32)kPrimes[index];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
Element *
|
||||||
|
OpenHashTable<Element, ElementVec>::FindFirst(uint32 hash) const
|
||||||
|
{
|
||||||
|
ASSERT(fElementVector);
|
||||||
|
hash %= fArraySize;
|
||||||
|
if (fHashArray[hash] < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return &fElementVector->At(fHashArray[hash]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
int32
|
||||||
|
OpenHashTable<Element, ElementVec>::ElementIndex(const Element *element) const
|
||||||
|
{
|
||||||
|
return fElementVector->IndexOf(*element);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
Element *
|
||||||
|
OpenHashTable<Element, ElementVec>::ElementAt(int32 index) const
|
||||||
|
{
|
||||||
|
return &fElementVector->At(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
int32
|
||||||
|
OpenHashTable<Element, ElementVec>::VectorSize() const
|
||||||
|
{
|
||||||
|
return fElementVector->Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
Element &
|
||||||
|
OpenHashTable<Element, ElementVec>::Add(uint32 hash)
|
||||||
|
{
|
||||||
|
ASSERT(fElementVector);
|
||||||
|
hash %= fArraySize;
|
||||||
|
Element &result = *fElementVector->Add();
|
||||||
|
result.fNext = fHashArray[hash];
|
||||||
|
fHashArray[hash] = fElementVector->IndexOf(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
void
|
||||||
|
OpenHashTable<Element, ElementVec>::Remove(Element *element)
|
||||||
|
{
|
||||||
|
uint32 hash = element->Hash() % fArraySize;
|
||||||
|
int32 next = fHashArray[hash];
|
||||||
|
ASSERT(next >= 0);
|
||||||
|
|
||||||
|
if (&fElementVector->At(next) == element) {
|
||||||
|
fHashArray[hash] = element->fNext;
|
||||||
|
fElementVector->Remove(next);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32 index = next; index >= 0; ) {
|
||||||
|
// look for an existing match in table
|
||||||
|
int32 next = fElementVector->At(index).fNext;
|
||||||
|
if (next < 0) {
|
||||||
|
TRESPASS();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (&fElementVector->At(next) == element) {
|
||||||
|
fElementVector->At(index).fNext = element->fNext;
|
||||||
|
fElementVector->Remove(next);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
index = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element, class ElementVec>
|
||||||
|
void
|
||||||
|
OpenHashTable<Element, ElementVec>::SetElementVector(ElementVec *elementVector)
|
||||||
|
{
|
||||||
|
fElementVector = elementVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element>
|
||||||
|
OpenHashElementArray<Element>::OpenHashElementArray(int32 initialSize)
|
||||||
|
:
|
||||||
|
fSize(initialSize),
|
||||||
|
fNextFree(0),
|
||||||
|
fNextDeleted(-1)
|
||||||
|
{
|
||||||
|
fData = (Element *)calloc((size_t)initialSize , sizeof(Element));
|
||||||
|
if (!fData)
|
||||||
|
throw bad_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element>
|
||||||
|
OpenHashElementArray<Element>::~OpenHashElementArray()
|
||||||
|
{
|
||||||
|
free(fData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element>
|
||||||
|
Element &
|
||||||
|
OpenHashElementArray<Element>::At(int32 index)
|
||||||
|
{
|
||||||
|
ASSERT(index < fSize);
|
||||||
|
return fData[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element>
|
||||||
|
const Element &
|
||||||
|
OpenHashElementArray<Element>::At(int32 index) const
|
||||||
|
{
|
||||||
|
ASSERT(index < fSize);
|
||||||
|
return fData[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element>
|
||||||
|
int32
|
||||||
|
OpenHashElementArray<Element>::IndexOf(const Element &element) const
|
||||||
|
{
|
||||||
|
int32 result = &element - fData;
|
||||||
|
if (result < 0 || result > fSize)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element>
|
||||||
|
int32
|
||||||
|
OpenHashElementArray<Element>::Size() const
|
||||||
|
{
|
||||||
|
return fSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element>
|
||||||
|
int32
|
||||||
|
OpenHashElementArray<Element>::Add(const Element &newElement)
|
||||||
|
{
|
||||||
|
int32 index = Add();
|
||||||
|
At(index).Adopt(newElement);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
const int32 kGrowChunk = 10;
|
||||||
|
#else
|
||||||
|
const int32 kGrowChunk = 1024;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element>
|
||||||
|
int32
|
||||||
|
OpenHashElementArray<Element>::Add()
|
||||||
|
{
|
||||||
|
int32 index = fNextFree;
|
||||||
|
if (fNextDeleted >= 0) {
|
||||||
|
index = fNextDeleted;
|
||||||
|
fNextDeleted = At(index).fNext;
|
||||||
|
} else if (fNextFree >= fSize - 1) {
|
||||||
|
int32 newSize = fSize + kGrowChunk;
|
||||||
|
Element *newData = (Element *)calloc((size_t)newSize , sizeof(Element));
|
||||||
|
if (!newData)
|
||||||
|
throw bad_alloc();
|
||||||
|
memcpy(newData, fData, fSize * sizeof(Element));
|
||||||
|
free(fData);
|
||||||
|
fData = newData;
|
||||||
|
fSize = newSize;
|
||||||
|
index = fNextFree;
|
||||||
|
fNextFree++;
|
||||||
|
} else
|
||||||
|
fNextFree++;
|
||||||
|
|
||||||
|
new (&At(index)) Element;
|
||||||
|
// call placement new to initialize the element properly
|
||||||
|
ASSERT(At(index).fNext == -1);
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Element>
|
||||||
|
void
|
||||||
|
OpenHashElementArray<Element>::Remove(int32 index)
|
||||||
|
{
|
||||||
|
// delete by chaining empty elements in a single linked
|
||||||
|
// list, reusing the next field
|
||||||
|
ASSERT(index < fSize);
|
||||||
|
At(index).~Element();
|
||||||
|
// call the destructor explicitly to destroy the element
|
||||||
|
// properly
|
||||||
|
At(index).fNext = fNextDeleted;
|
||||||
|
fNextDeleted = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,325 @@
|
|||||||
|
/*
|
||||||
|
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 _OPEN_WITH_WINDOW_H
|
||||||
|
#define _OPEN_WITH_WINDOW_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include "ContainerWindow.h"
|
||||||
|
#include "EntryIterator.h"
|
||||||
|
#include "NodeWalker.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
#include "Query.h"
|
||||||
|
#include "SlowMenu.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class OpenWithPoseView;
|
||||||
|
|
||||||
|
// OpenWithContainerWindow supports the Open With feature
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kUnknownRelation = -1,
|
||||||
|
kNoRelation = 0,
|
||||||
|
kSuperhandler,
|
||||||
|
kSupportsSupertype,
|
||||||
|
kSupportsType,
|
||||||
|
kPreferredForType,
|
||||||
|
kPreferredForFile
|
||||||
|
};
|
||||||
|
|
||||||
|
class SearchForSignatureEntryList : public EntryListBase {
|
||||||
|
// pass in a predicate; a query will search for matches
|
||||||
|
// matches will be returned in iteration
|
||||||
|
public:
|
||||||
|
SearchForSignatureEntryList(bool canAddAllApps);
|
||||||
|
virtual ~SearchForSignatureEntryList();
|
||||||
|
|
||||||
|
void PushUniqueSignature(const char *);
|
||||||
|
// add one signature to search for
|
||||||
|
|
||||||
|
// entry list iterators
|
||||||
|
virtual status_t GetNextEntry(BEntry *entry, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *ref);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
|
||||||
|
virtual status_t Rewind();
|
||||||
|
virtual int32 CountEntries();
|
||||||
|
|
||||||
|
bool GetPreferredApp(entry_ref *ref) const;
|
||||||
|
// gets the preferred app for all the files it was asked to
|
||||||
|
// find supporting apps for, returns false if no preferred app
|
||||||
|
// found or if more than one found
|
||||||
|
void TrySettingPreferredApp(const entry_ref *);
|
||||||
|
void TrySettingPreferredAppForFile(const entry_ref *);
|
||||||
|
|
||||||
|
int32 Relation(const BMessage *entriesToOpen, const Model *) const;
|
||||||
|
// returns the reason why an application is shown in Open With window
|
||||||
|
void RelationDescription(const BMessage *entriesToOpen, const Model *,
|
||||||
|
BString *) const;
|
||||||
|
// returns a string describing why application handles files to open
|
||||||
|
|
||||||
|
static int32 Relation(const BMessage *entriesToOpen,
|
||||||
|
const Model *, const entry_ref *preferredApp,
|
||||||
|
const entry_ref *preferredAppForFile);
|
||||||
|
// returns the reason why an application is shown in Open With window
|
||||||
|
// static version, needs the preferred app for preformance
|
||||||
|
static void RelationDescription(const BMessage *entriesToOpen,
|
||||||
|
const Model *, BString *, const entry_ref *preferredApp,
|
||||||
|
const entry_ref *preferredAppForFile);
|
||||||
|
// returns a string describing why application handles files to open
|
||||||
|
|
||||||
|
bool CanOpenWithFilter(const Model *appModel, const BMessage *entriesToOpen,
|
||||||
|
const entry_ref *preferredApp);
|
||||||
|
|
||||||
|
void NonGenericFileFound();
|
||||||
|
bool GenericFilesOnly() const;
|
||||||
|
|
||||||
|
bool ShowAllApplications() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int32 Relation(const Model *node, const Model *app);
|
||||||
|
// returns the reason why an application is shown in Open With window
|
||||||
|
|
||||||
|
CachedEntryIteratorList *fIteratorList;
|
||||||
|
BObjectList<BString> fSignatures;
|
||||||
|
|
||||||
|
entry_ref fPreferredRef;
|
||||||
|
int32 fPreferredAppCount;
|
||||||
|
entry_ref fPreferredRefForFile;
|
||||||
|
int32 fPreferredAppForFileCount;
|
||||||
|
bool fGenericFilesOnly;
|
||||||
|
bool fCanAddAllApps;
|
||||||
|
bool fFoundOneNonSuperHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenWithContainerWindow : public BContainerWindow {
|
||||||
|
public:
|
||||||
|
OpenWithContainerWindow(BMessage *entriesToOpen,
|
||||||
|
LockingList<BWindow> *windowList,
|
||||||
|
window_look look = B_DOCUMENT_WINDOW_LOOK,
|
||||||
|
window_feel feel = B_NORMAL_WINDOW_FEEL,
|
||||||
|
uint32 flags = 0,
|
||||||
|
uint32 workspace = B_CURRENT_WORKSPACE);
|
||||||
|
// <entriesToOpen> eventually get opened by the selected app
|
||||||
|
|
||||||
|
~OpenWithContainerWindow();
|
||||||
|
|
||||||
|
virtual void Init(const BMessage *message);
|
||||||
|
|
||||||
|
const BMessage *EntryList() const;
|
||||||
|
// return the list of the entries we are supposed to open
|
||||||
|
|
||||||
|
void SetCanSetAppAsDefault(bool);
|
||||||
|
void SetCanOpen(bool);
|
||||||
|
|
||||||
|
OpenWithPoseView *PoseView() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual BPoseView *NewPoseView(Model *model, BRect rect, uint32 viewMode);
|
||||||
|
|
||||||
|
virtual bool ShouldAddMenus() const
|
||||||
|
{ return false; }
|
||||||
|
virtual void ShowContextMenu(BPoint, const entry_ref *, BView *)
|
||||||
|
{ }
|
||||||
|
virtual void AddShortcuts();
|
||||||
|
virtual void NewAttributeMenu(BMenu *);
|
||||||
|
|
||||||
|
virtual void RestoreState();
|
||||||
|
virtual void RestoreState(const BMessage &);
|
||||||
|
virtual void RestoreWindowState(AttributeStreamNode *);
|
||||||
|
virtual void RestoreWindowState(const BMessage &);
|
||||||
|
virtual bool NeedsDefaultStateSetup();
|
||||||
|
virtual void SaveState(bool hide = true);
|
||||||
|
virtual void SaveState(BMessage &) const;
|
||||||
|
virtual void SetUpDefaultState();
|
||||||
|
|
||||||
|
virtual bool IsShowing(const node_ref *) const;
|
||||||
|
virtual bool IsShowing(const entry_ref *) const;
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage *);
|
||||||
|
|
||||||
|
void OpenWithSelection();
|
||||||
|
// open entries with the selected app
|
||||||
|
void MakeDefaultAndOpen();
|
||||||
|
// open entries with the selected app and make it the default handler
|
||||||
|
|
||||||
|
private:
|
||||||
|
static filter_result KeyDownFilter(BMessage *, BHandler **, BMessageFilter *);
|
||||||
|
|
||||||
|
BMessage *fEntriesToOpen;
|
||||||
|
BButton *fLaunchButton;
|
||||||
|
BButton *fLaunchAndMakeDefaultButton;
|
||||||
|
|
||||||
|
typedef BContainerWindow _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenWithPoseView : public BPoseView {
|
||||||
|
public:
|
||||||
|
OpenWithPoseView(BRect, uint32 resizeMask = B_FOLLOW_ALL);
|
||||||
|
|
||||||
|
virtual void OpenSelection(BPose *, int32 *);
|
||||||
|
// open entries with the selected app
|
||||||
|
|
||||||
|
int32 OpenWithRelation(const Model *) const;
|
||||||
|
// returns the reason why an application is shown in Open With window
|
||||||
|
void OpenWithRelationDescription(const Model *, BString *) const;
|
||||||
|
// returns a string describing why application handles files to open
|
||||||
|
|
||||||
|
OpenWithContainerWindow *ContainerWindow() const;
|
||||||
|
|
||||||
|
virtual bool AddPosesThreadValid(const entry_ref *) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// don't do any volume watching and memtamime watching in open with panels for now
|
||||||
|
virtual void InitialStartWatching() {}
|
||||||
|
virtual void FinalStopWatching() {}
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
EntryListBase *InitDirentIterator(const entry_ref *ref);
|
||||||
|
|
||||||
|
virtual void SetUpDefaultColumnsIfNeeded();
|
||||||
|
// show launch window specific columns
|
||||||
|
|
||||||
|
// empty overrides for functions that depend on having an fModel
|
||||||
|
virtual void SaveState(AttributeStreamNode *);
|
||||||
|
virtual void RestoreState(AttributeStreamNode *);
|
||||||
|
virtual void SaveState(BMessage &) const;
|
||||||
|
virtual void RestoreState(const BMessage &);
|
||||||
|
virtual void SavePoseLocations(BRect * = NULL);
|
||||||
|
virtual void MoveSelectionToTrash(bool selectNext = true);
|
||||||
|
virtual void MoveSelectionTo(BPoint, BPoint, BContainerWindow*);
|
||||||
|
virtual void MoveSelectionInto(Model* destFolder, BContainerWindow *srcWindow,
|
||||||
|
bool forceCopy, bool create_link = false);
|
||||||
|
virtual bool HandleMessageDropped(BMessage *);
|
||||||
|
virtual bool CanHandleDragSelection(const Model *, const BMessage *, bool);
|
||||||
|
|
||||||
|
virtual bool Represents(const node_ref *) const;
|
||||||
|
virtual bool Represents(const entry_ref *) const;
|
||||||
|
|
||||||
|
virtual void CreatePoses(Model **models, PoseInfo *poseInfoArray, int32 count,
|
||||||
|
BPose **resultingPoses, bool insertionSort = true, int32 *lastPoseIndexPtr = NULL,
|
||||||
|
BRect *boundsPtr = NULL, bool forceDraw = false);
|
||||||
|
// override to add selecting the default handling app for selection
|
||||||
|
|
||||||
|
virtual bool ShouldShowPose(const Model *, const PoseInfo *);
|
||||||
|
|
||||||
|
virtual void Pulse();
|
||||||
|
|
||||||
|
virtual void KeyDown(const char *bytes, int32 count);
|
||||||
|
|
||||||
|
private:
|
||||||
|
entry_ref fPreferredRef;
|
||||||
|
bool fHaveCommonPreferredApp;
|
||||||
|
|
||||||
|
SearchForSignatureEntryList *fIterator;
|
||||||
|
// private copy of the iterator pointer
|
||||||
|
|
||||||
|
typedef BPoseView _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RelationCachingModelProxy {
|
||||||
|
public:
|
||||||
|
RelationCachingModelProxy(Model *);
|
||||||
|
~RelationCachingModelProxy();
|
||||||
|
|
||||||
|
int32 Relation(SearchForSignatureEntryList *, BMessage *entries) const;
|
||||||
|
|
||||||
|
Model *fModel;
|
||||||
|
mutable int32 relation;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenWithMenu : public BSlowMenu {
|
||||||
|
public:
|
||||||
|
OpenWithMenu(const char *, const BMessage *entriesToOpen,
|
||||||
|
BWindow *parentWindow, BHandler *);
|
||||||
|
OpenWithMenu(const char *, const BMessage *entriesToOpen,
|
||||||
|
BWindow *parentWindow, const BMessenger &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool StartBuildingItemList();
|
||||||
|
virtual bool AddNextItem();
|
||||||
|
virtual void DoneBuildingItemList();
|
||||||
|
virtual void ClearMenuBuildingState();
|
||||||
|
|
||||||
|
BMessage fEntriesToOpen;
|
||||||
|
BHandler *target;
|
||||||
|
BMessenger fMessenger;
|
||||||
|
|
||||||
|
// menu building state
|
||||||
|
SearchForSignatureEntryList *fIterator;
|
||||||
|
entry_ref fPreferredRef;
|
||||||
|
BObjectList<RelationCachingModelProxy> *fSupportingAppList;
|
||||||
|
bool fHaveCommonPreferredApp;
|
||||||
|
BWindow *fParentWindow;
|
||||||
|
|
||||||
|
typedef BSlowMenu _inherited;
|
||||||
|
|
||||||
|
friend int SortByRelationAndName(const RelationCachingModelProxy *,
|
||||||
|
const RelationCachingModelProxy *, void *);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConditionalAllAppsIterator : public EntryListBase {
|
||||||
|
// used for optionally showing the list of all apps. Do nothing
|
||||||
|
// until asked to iterate and only if supposed to do so
|
||||||
|
public:
|
||||||
|
ConditionalAllAppsIterator(SearchForSignatureEntryList *parent);
|
||||||
|
~ConditionalAllAppsIterator();
|
||||||
|
|
||||||
|
virtual status_t GetNextEntry(BEntry *entry, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *ref);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
|
||||||
|
virtual status_t Rewind();
|
||||||
|
virtual int32 CountEntries();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool Iterate() const;
|
||||||
|
void Instantiate();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SearchForSignatureEntryList *fParent;
|
||||||
|
WALKER_NS::TWalker *fWalker;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// defines the status area drawn in the bottom left corner of a Tracker window
|
||||||
|
|
||||||
|
#include <Button.h>
|
||||||
|
#include <Screen.h>
|
||||||
|
|
||||||
|
#include "OverrideAlert.h"
|
||||||
|
|
||||||
|
OverrideAlert::OverrideAlert(const char *title, const char *text,
|
||||||
|
const char *button1, uint32 modifiers1,
|
||||||
|
const char *button2, uint32 modifiers2,
|
||||||
|
const char *button3, uint32 modifiers3,
|
||||||
|
button_width width, alert_type type)
|
||||||
|
: BAlert(title, text, button1, button2, button3, width, type),
|
||||||
|
fCurModifiers(0)
|
||||||
|
{
|
||||||
|
fButtonModifiers[0] = modifiers1;
|
||||||
|
fButtonModifiers[1] = modifiers2;
|
||||||
|
fButtonModifiers[2] = modifiers3;
|
||||||
|
UpdateButtons(modifiers(), true);
|
||||||
|
|
||||||
|
BPoint where = OverPosition(Frame().Width(), Frame().Height());
|
||||||
|
MoveTo(where.x, where.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
OverrideAlert::OverrideAlert(const char *title, const char *text,
|
||||||
|
const char *button1, uint32 modifiers1,
|
||||||
|
const char *button2, uint32 modifiers2,
|
||||||
|
const char *button3, uint32 modifiers3,
|
||||||
|
button_width width, button_spacing spacing, alert_type type)
|
||||||
|
: BAlert(title, text, button1, button2, button3, width, spacing, type),
|
||||||
|
fCurModifiers(0)
|
||||||
|
{
|
||||||
|
fButtonModifiers[0] = modifiers1;
|
||||||
|
fButtonModifiers[1] = modifiers2;
|
||||||
|
fButtonModifiers[2] = modifiers3;
|
||||||
|
UpdateButtons(modifiers(), true);
|
||||||
|
|
||||||
|
BPoint where = OverPosition(Frame().Width(), Frame().Height());
|
||||||
|
MoveTo(where.x, where.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
OverrideAlert::~OverrideAlert()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OverrideAlert::DispatchMessage(BMessage *message, BHandler *handler)
|
||||||
|
{
|
||||||
|
if (message->what == B_KEY_DOWN || message->what == B_KEY_UP
|
||||||
|
|| message->what == B_UNMAPPED_KEY_DOWN
|
||||||
|
|| message->what == B_UNMAPPED_KEY_UP) {
|
||||||
|
uint32 modifiers;
|
||||||
|
if (message->FindInt32("modifiers", (int32 *)&modifiers) == B_OK)
|
||||||
|
UpdateButtons(modifiers);
|
||||||
|
}
|
||||||
|
BAlert::DispatchMessage(message, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
BPoint
|
||||||
|
OverrideAlert::OverPosition(float width, float height)
|
||||||
|
{
|
||||||
|
// This positions the alert window like a normal alert, put
|
||||||
|
// places it on top of the calling window if possible.
|
||||||
|
|
||||||
|
BWindow *window = dynamic_cast<BWindow *>(BLooper::LooperForThread(find_thread(NULL)));
|
||||||
|
BRect screenFrame;
|
||||||
|
BRect desirableRect;
|
||||||
|
screenFrame = BScreen(window).Frame();
|
||||||
|
|
||||||
|
if (window) {
|
||||||
|
// If we found a window associated with this calling thread,
|
||||||
|
// place alert over that window so that the first button is
|
||||||
|
// on top of it. This allows name editing confirmations to
|
||||||
|
// work with focus follows mouse -- when the alert goes away,
|
||||||
|
// the underlying window will still have focus.
|
||||||
|
|
||||||
|
desirableRect = window->Frame();
|
||||||
|
float midX = (desirableRect.left + desirableRect.right) / 2.0f;
|
||||||
|
float midY = (desirableRect.top * 3.0f + desirableRect.bottom) / 4.0f;
|
||||||
|
|
||||||
|
desirableRect.left = midX - ceilf(width / 2.0f);
|
||||||
|
desirableRect.right = desirableRect.left+width;
|
||||||
|
desirableRect.top = midY - ceilf(height / 3.0f);
|
||||||
|
desirableRect.bottom = desirableRect.top + height;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Otherwise, just place alert in center of screen.
|
||||||
|
|
||||||
|
desirableRect = screenFrame;
|
||||||
|
float midX = (desirableRect.left + desirableRect.right) / 2.0f;
|
||||||
|
float midY = (desirableRect.top * 3.0f + desirableRect.bottom) / 4.0f;
|
||||||
|
|
||||||
|
desirableRect.left = midX - ceilf(width / 2.0f);
|
||||||
|
desirableRect.right = desirableRect.left + width;
|
||||||
|
desirableRect.top = midY - ceilf(height / 3.0f);
|
||||||
|
desirableRect.bottom = desirableRect.top + height;
|
||||||
|
}
|
||||||
|
|
||||||
|
return desirableRect.LeftTop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OverrideAlert::UpdateButtons(uint32 modifiers, bool force)
|
||||||
|
{
|
||||||
|
if (modifiers == fCurModifiers && !force)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fCurModifiers = modifiers;
|
||||||
|
for (int32 i = 0; i < 3; i++) {
|
||||||
|
BButton *button = ButtonAt(i);
|
||||||
|
if (button)
|
||||||
|
button->SetEnabled(((fButtonModifiers[i] & fCurModifiers) == fButtonModifiers[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
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 _OVERRIDE_ALERT_H
|
||||||
|
#define _OVERRIDE_ALERT_H
|
||||||
|
|
||||||
|
// This is a special BAlert for which you can specify modifier
|
||||||
|
// keys that must be down for various buttons to be enabled. It
|
||||||
|
// is used when confirming changes in the BeOS directory to force
|
||||||
|
// the user to hold shift when confirming.
|
||||||
|
|
||||||
|
// The alert also positions itself slightly differently than a
|
||||||
|
// normal BAlert, attempting to be on top of the calling window.
|
||||||
|
// This allows it to work when confirming rename operations with
|
||||||
|
// Focus Follows Mouse turned on.
|
||||||
|
|
||||||
|
#include <Alert.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class OverrideAlert : public BAlert {
|
||||||
|
public:
|
||||||
|
OverrideAlert(const char *title, const char *text,
|
||||||
|
const char *button1, uint32 modifiers1,
|
||||||
|
const char *button2, uint32 modifiers2,
|
||||||
|
const char *button3, uint32 modifiers3,
|
||||||
|
button_width width = B_WIDTH_AS_USUAL,
|
||||||
|
alert_type type = B_INFO_ALERT);
|
||||||
|
OverrideAlert(const char *title, const char *text,
|
||||||
|
const char *button1, uint32 modifiers1,
|
||||||
|
const char *button2, uint32 modifiers2,
|
||||||
|
const char *button3, uint32 modifiers3,
|
||||||
|
button_width width, button_spacing spacing,
|
||||||
|
alert_type type = B_INFO_ALERT);
|
||||||
|
virtual ~OverrideAlert();
|
||||||
|
|
||||||
|
virtual void DispatchMessage(BMessage *, BHandler *);
|
||||||
|
|
||||||
|
static BPoint OverPosition(float width, float height);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void UpdateButtons(uint32 modifiers, bool force = false);
|
||||||
|
|
||||||
|
uint32 fCurModifiers;
|
||||||
|
uint32 fButtonModifiers[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PendingNodeMonitorCache.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
|
||||||
|
const bigtime_t kDelayedNodeMonitorLifetime = 10000000;
|
||||||
|
// after this much the pending node monitor gets discarded as
|
||||||
|
// too old
|
||||||
|
|
||||||
|
PendingNodeMonitorEntry::PendingNodeMonitorEntry(const node_ref *node,
|
||||||
|
const BMessage *nodeMonitor)
|
||||||
|
: fExpiresAfter(system_time() + kDelayedNodeMonitorLifetime),
|
||||||
|
fNodeMonitor(*nodeMonitor),
|
||||||
|
fNode(*node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const BMessage *
|
||||||
|
PendingNodeMonitorEntry::NodeMonitor() const
|
||||||
|
{
|
||||||
|
return &fNodeMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PendingNodeMonitorEntry::Match(const node_ref *node) const
|
||||||
|
{
|
||||||
|
return fNode == *node;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PendingNodeMonitorEntry::TooOld(bigtime_t now) const
|
||||||
|
{
|
||||||
|
return now > fExpiresAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PendingNodeMonitorCache::PendingNodeMonitorCache()
|
||||||
|
: fList(10, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PendingNodeMonitorCache::~PendingNodeMonitorCache()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PendingNodeMonitorCache::Add(const BMessage *message)
|
||||||
|
{
|
||||||
|
#if xDEBUG
|
||||||
|
PRINT(("adding pending node monitor\n"));
|
||||||
|
message->PrintToStream();
|
||||||
|
#endif
|
||||||
|
node_ref node;
|
||||||
|
if (message->FindInt32("device", &node.device) != B_OK
|
||||||
|
|| message->FindInt64("node", (int64 *)&node.node) != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fList.AddItem(new PendingNodeMonitorEntry(&node, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PendingNodeMonitorCache::RemoveEntries(const node_ref *nodeRef)
|
||||||
|
{
|
||||||
|
int32 count = fList.CountItems();
|
||||||
|
for (int32 index = count - 1; index >= 0; index--)
|
||||||
|
if (fList.ItemAt(index)->Match(nodeRef))
|
||||||
|
delete fList.RemoveItemAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PendingNodeMonitorCache::RemoveOldEntries()
|
||||||
|
{
|
||||||
|
bigtime_t now = system_time();
|
||||||
|
int32 count = fList.CountItems();
|
||||||
|
for (int32 index = count - 1; index >= 0; index--)
|
||||||
|
if (fList.ItemAt(index)->TooOld(now)) {
|
||||||
|
PRINT(("removing old entry from pending node monitor cache\n"));
|
||||||
|
delete fList.RemoveItemAt(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PendingNodeMonitorCache::PoseCreatedOrMoved(BPoseView *poseView, const BPose *pose)
|
||||||
|
{
|
||||||
|
bigtime_t now = system_time();
|
||||||
|
int32 count = fList.CountItems();
|
||||||
|
for (int32 index = 0; index < count;) {
|
||||||
|
PendingNodeMonitorEntry *item = fList.ItemAt(index);
|
||||||
|
if (item->TooOld(now)) {
|
||||||
|
PRINT(("removing old entry from pending node monitor cache\n"));
|
||||||
|
delete fList.RemoveItemAt(index);
|
||||||
|
count--;
|
||||||
|
} else if (item->Match(pose->TargetModel()->NodeRef())) {
|
||||||
|
#if DEBUG
|
||||||
|
PRINT(("reapplying node monitor for model:\n"));
|
||||||
|
pose->TargetModel()->PrintToStream();
|
||||||
|
item->NodeMonitor()->PrintToStream();
|
||||||
|
bool result =
|
||||||
|
#endif
|
||||||
|
poseView->FSNotification(item->NodeMonitor());
|
||||||
|
ASSERT(result);
|
||||||
|
delete fList.RemoveItemAt(index);
|
||||||
|
count--;
|
||||||
|
} else
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// PendingNodeMonitorCache is used to store node monitors that
|
||||||
|
// cannot be delivered yet because the corresponding model has not yet been
|
||||||
|
// added to a PoseView
|
||||||
|
//
|
||||||
|
// The respective node montior messages are stored in a list and applied
|
||||||
|
// later, when their target shows up. They get nuked when they become too
|
||||||
|
// old.
|
||||||
|
|
||||||
|
#ifndef __PENDING_NODEMONITOR_CACHE_H__
|
||||||
|
#define __PENDING_NODEMONITOR_CACHE_H__
|
||||||
|
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Node.h>
|
||||||
|
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BPoseView;
|
||||||
|
class BPose;
|
||||||
|
|
||||||
|
class PendingNodeMonitorEntry {
|
||||||
|
public:
|
||||||
|
PendingNodeMonitorEntry(const node_ref *node, const BMessage *);
|
||||||
|
const BMessage *NodeMonitor() const;
|
||||||
|
bool Match(const node_ref *) const;
|
||||||
|
bool TooOld(bigtime_t now) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bigtime_t fExpiresAfter;
|
||||||
|
BMessage fNodeMonitor;
|
||||||
|
node_ref fNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PendingNodeMonitorCache {
|
||||||
|
public:
|
||||||
|
PendingNodeMonitorCache();
|
||||||
|
~PendingNodeMonitorCache();
|
||||||
|
|
||||||
|
void Add(const BMessage *);
|
||||||
|
void RemoveEntries(const node_ref *);
|
||||||
|
void RemoveOldEntries();
|
||||||
|
|
||||||
|
void PoseCreatedOrMoved(BPoseView *, const BPose *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BObjectList<PendingNodeMonitorEntry> fList;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,912 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
#include <fs_info.h>
|
||||||
|
|
||||||
|
#include "Attributes.h"
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "FSClipboard.h"
|
||||||
|
#include "IconCache.h"
|
||||||
|
#include "Pose.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
CalcFreeSpace(dev_t device)
|
||||||
|
{
|
||||||
|
BVolume volume(device);
|
||||||
|
fs_info info;
|
||||||
|
if (volume.InitCheck() == B_OK && fs_stat_dev(device,&info) == B_OK) {
|
||||||
|
// Philosophy here:
|
||||||
|
// Bars go on all drives with read/write capabilities
|
||||||
|
// Exceptions: Not on CDDA, but on NTFS/Ext2
|
||||||
|
// Also note that some volumes may return 0 when
|
||||||
|
// BVolume::Capacity() is called (believe-me... That *DOES*
|
||||||
|
// happen) so we also check for that.
|
||||||
|
off_t capacity = volume.Capacity();
|
||||||
|
if (((!volume.IsReadOnly() && strcmp(info.fsh_name,"cdda"))
|
||||||
|
|| !strcmp(info.fsh_name,"ntfs")
|
||||||
|
|| !strcmp(info.fsh_name,"ext2"))
|
||||||
|
&& (capacity > 0)) {
|
||||||
|
int32 percent = static_cast<int32>(volume.FreeBytes() / (capacity / 100));
|
||||||
|
|
||||||
|
// warn below 20 MB of free space (if this is less than 10% of free space)
|
||||||
|
if (volume.FreeBytes() < 20 * 1024 * 1024 && percent < 10)
|
||||||
|
return -2 - percent;
|
||||||
|
|
||||||
|
return percent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SymLink handling:
|
||||||
|
// symlink pose uses the resolved model to retrieve the icon, if not broken
|
||||||
|
// everything else, like the attributes, etc. is retrieved directly from the
|
||||||
|
// symlink itself
|
||||||
|
|
||||||
|
BPose::BPose(Model *model, BPoseView *view, bool selected)
|
||||||
|
: fModel(model),
|
||||||
|
fWidgetList(4, true),
|
||||||
|
fPercent(-1),
|
||||||
|
fIsSelected(selected),
|
||||||
|
fDelayedEdit(true),
|
||||||
|
fHasLocation(false),
|
||||||
|
fNeedsSaveLocation(false),
|
||||||
|
fListModeInited(false),
|
||||||
|
fWasAutoPlaced(false),
|
||||||
|
fBrokenSymLink(false),
|
||||||
|
fBackgroundClean(false)
|
||||||
|
{
|
||||||
|
CreateWidgets(view);
|
||||||
|
|
||||||
|
if (model->IsVolume() && TrackerSettings().ShowVolumeSpaceBar()) {
|
||||||
|
dev_t device = model->NodeRef()->device;
|
||||||
|
fPercent = CalcFreeSpace(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fClipboardMode = FSClipboardFindNodeMode(model,true)) != 0
|
||||||
|
&& !view->HasPosesInClipboard()) {
|
||||||
|
view->SetHasPosesInClipboard(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BPose::~BPose()
|
||||||
|
{
|
||||||
|
delete fModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::CreateWidgets(BPoseView *poseView)
|
||||||
|
{
|
||||||
|
for (int32 index = 0; ; index++) {
|
||||||
|
BColumn *column = poseView->ColumnAt(index);
|
||||||
|
if (!column)
|
||||||
|
break;
|
||||||
|
fWidgetList.AddItem(new BTextWidget(fModel, column, poseView));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BTextWidget *
|
||||||
|
BPose::AddWidget(BPoseView *poseView, BColumn *column)
|
||||||
|
{
|
||||||
|
BModelOpener opener(fModel);
|
||||||
|
if (fModel->InitCheck() != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
BTextWidget *widget = new BTextWidget(fModel, column, poseView);
|
||||||
|
fWidgetList.AddItem(widget);
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BTextWidget *
|
||||||
|
BPose::AddWidget(BPoseView *poseView, BColumn *column, ModelNodeLazyOpener &opener)
|
||||||
|
{
|
||||||
|
opener.OpenNode();
|
||||||
|
if (fModel->InitCheck() != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
BTextWidget *widget = new BTextWidget(fModel, column, poseView);
|
||||||
|
fWidgetList.AddItem(widget);
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::RemoveWidget(BPoseView *, BColumn *column)
|
||||||
|
{
|
||||||
|
int32 index;
|
||||||
|
BTextWidget *widget = WidgetFor(column->AttrHash(), &index);
|
||||||
|
if (widget)
|
||||||
|
delete fWidgetList.RemoveItemAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::Commit(bool saveChanges, BPoint loc, BPoseView *poseView, int32 poseIndex)
|
||||||
|
{
|
||||||
|
int32 count = fWidgetList.CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++) {
|
||||||
|
BTextWidget *widget = fWidgetList.ItemAt(index);
|
||||||
|
if (widget->IsActive()) {
|
||||||
|
widget->StopEdit(saveChanges, loc, poseView, this, poseIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
OneMouseUp(BTextWidget *widget, BPose *pose, BPoseView *poseView, BColumn *column,
|
||||||
|
BPoint poseLoc, BPoint where)
|
||||||
|
{
|
||||||
|
BRect rect;
|
||||||
|
if (poseView->ViewMode() == kListMode)
|
||||||
|
rect = widget->CalcClickRect(poseLoc, column, poseView);
|
||||||
|
else
|
||||||
|
rect = widget->CalcClickRect(pose->Location(), 0, poseView);
|
||||||
|
|
||||||
|
if (rect.Contains(where)) {
|
||||||
|
widget->MouseUp(rect, poseView, pose, where, pose->DelayedEdit());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::MouseUp(BPoint poseLoc, BPoseView *poseView, BPoint where, int32)
|
||||||
|
{
|
||||||
|
WhileEachTextWidget(this, poseView, OneMouseUp, poseLoc, where);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
OneCheckAndUpdate(BTextWidget *widget, BPose *, BPoseView *poseView,
|
||||||
|
BColumn *column, BPoint poseLoc)
|
||||||
|
{
|
||||||
|
widget->CheckAndUpdate(poseLoc, column, poseView);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::UpdateAllWidgets(int32, BPoint poseLoc, BPoseView *poseView)
|
||||||
|
{
|
||||||
|
if (poseView->ViewMode() != kListMode)
|
||||||
|
poseLoc = fLocation;
|
||||||
|
|
||||||
|
ASSERT(fModel->IsNodeOpen());
|
||||||
|
EachTextWidget(this, poseView, OneCheckAndUpdate, poseLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::UpdateWidgetAndModel(Model *resolvedModel, const char *attrName,
|
||||||
|
uint32 attrType, int32, BPoint poseLoc, BPoseView *poseView)
|
||||||
|
{
|
||||||
|
if (poseView->ViewMode() != kListMode)
|
||||||
|
poseLoc = fLocation;
|
||||||
|
|
||||||
|
ASSERT(!resolvedModel || resolvedModel->IsNodeOpen());
|
||||||
|
|
||||||
|
if (attrName) {
|
||||||
|
// pick up new attributes and find out if icon needs updating
|
||||||
|
if (resolvedModel->AttrChanged(attrName))
|
||||||
|
UpdateIcon(poseLoc, poseView);
|
||||||
|
|
||||||
|
// ToDo: the following code is wrong, because this sort of hashing
|
||||||
|
// may overlap and we get aliasing
|
||||||
|
uint32 attrHash = AttrHashString(attrName, attrType);
|
||||||
|
BTextWidget *widget = WidgetFor(attrHash);
|
||||||
|
if (widget) {
|
||||||
|
BColumn *column = poseView->ColumnFor(attrHash);
|
||||||
|
if (column)
|
||||||
|
widget->CheckAndUpdate(poseLoc, column, poseView);
|
||||||
|
} else if (attrType == 0) {
|
||||||
|
// attribute got likely removed, so let's search the
|
||||||
|
// column for the matching attribute name
|
||||||
|
int32 count = fWidgetList.CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
BTextWidget *widget = fWidgetList.ItemAt(i);
|
||||||
|
BColumn *column = poseView->ColumnFor(widget->AttrHash());
|
||||||
|
if (column != NULL && !strcmp(column->AttrName(), attrName)) {
|
||||||
|
widget->CheckAndUpdate(poseLoc, column, poseView);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no attr name means check all widgets for stat info changes
|
||||||
|
|
||||||
|
// pick up stat changes
|
||||||
|
if (resolvedModel && resolvedModel->StatChanged()) {
|
||||||
|
if (resolvedModel->InitCheck() != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdateIcon(poseLoc, poseView);
|
||||||
|
}
|
||||||
|
|
||||||
|
// distribute stat changes
|
||||||
|
for (int32 index = 0; ; index++) {
|
||||||
|
BColumn *column = poseView->ColumnAt(index);
|
||||||
|
if (!column)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (column->StatField()) {
|
||||||
|
BTextWidget *widget = WidgetFor(column->AttrHash());
|
||||||
|
if (widget)
|
||||||
|
widget->CheckAndUpdate(poseLoc, column, poseView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPose::UpdateVolumeSpaceBar(bool enabled)
|
||||||
|
{
|
||||||
|
if (!enabled) {
|
||||||
|
if (fPercent == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
fPercent = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_t device = TargetModel()->NodeRef()->device;
|
||||||
|
int32 percent = CalcFreeSpace(device);
|
||||||
|
|
||||||
|
if (fPercent != percent) {
|
||||||
|
if (percent > 100)
|
||||||
|
fPercent = 100;
|
||||||
|
else
|
||||||
|
fPercent = percent;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::UpdateIcon(BPoint poseLoc, BPoseView *poseView)
|
||||||
|
{
|
||||||
|
IconCache::sIconCache->IconChanged(ResolvedModel());
|
||||||
|
|
||||||
|
BRect rect;
|
||||||
|
if (poseView->ViewMode() == kListMode) {
|
||||||
|
rect = CalcRect(poseLoc, poseView);
|
||||||
|
rect.left += kListOffset;
|
||||||
|
rect.right = rect.left + B_MINI_ICON;
|
||||||
|
rect.top = rect.bottom - B_MINI_ICON;
|
||||||
|
} else if (poseView->ViewMode() == kIconMode) {
|
||||||
|
rect.left = fLocation.x;
|
||||||
|
rect.top = fLocation.y;
|
||||||
|
rect.right = rect.left + B_LARGE_ICON;
|
||||||
|
rect.bottom = rect.top + B_LARGE_ICON;
|
||||||
|
} else {
|
||||||
|
rect.left = fLocation.x;
|
||||||
|
rect.top = fLocation.y;
|
||||||
|
rect.right = rect.left + B_MINI_ICON;
|
||||||
|
rect.bottom = rect.top + B_MINI_ICON;
|
||||||
|
}
|
||||||
|
|
||||||
|
poseView->Invalidate(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::UpdateBrokenSymLink(BPoint poseLoc, BPoseView *poseView)
|
||||||
|
{
|
||||||
|
ASSERT(TargetModel()->IsSymLink());
|
||||||
|
ASSERT(!TargetModel()->LinkTo());
|
||||||
|
UpdateIcon(poseLoc, poseView);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::UpdateWasBrokenSymlink(BPoint poseLoc, BPoseView *poseView)
|
||||||
|
{
|
||||||
|
if (!fModel->IsSymLink())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fModel->LinkTo())
|
||||||
|
return;
|
||||||
|
|
||||||
|
poseView->CreateSymlinkPoseTarget(fModel);
|
||||||
|
if (!fModel->LinkTo())
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdateIcon(poseLoc, poseView);
|
||||||
|
fModel->LinkTo()->CloseNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::EditFirstWidget(BPoint poseLoc, BPoseView *poseView)
|
||||||
|
{
|
||||||
|
// find first editable widget
|
||||||
|
BColumn *column;
|
||||||
|
for (int32 i = 0;(column = poseView->ColumnAt(i)) != NULL;i++) {
|
||||||
|
BTextWidget *widget = WidgetFor(column->AttrHash());
|
||||||
|
|
||||||
|
if (widget && widget->IsEditable()) {
|
||||||
|
BRect bounds;
|
||||||
|
// ToDo:
|
||||||
|
// fold the three StartEdit code sequences into a cover call
|
||||||
|
if (poseView->ViewMode() == kListMode)
|
||||||
|
bounds = widget->CalcRect(poseLoc, column, poseView);
|
||||||
|
else
|
||||||
|
bounds = widget->CalcRect(fLocation, NULL, poseView);
|
||||||
|
widget->StartEdit(bounds, poseView, this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::EditPreviousNextWidgetCommon(BPoseView *poseView, bool next)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
int32 delta = next ? 1 : -1;
|
||||||
|
for (int32 index = next ? 0 : poseView->CountColumns() - 1; ; index += delta) {
|
||||||
|
BColumn *column = poseView->ColumnAt(index);
|
||||||
|
if (!column)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BTextWidget *widget = WidgetFor(column->AttrHash());
|
||||||
|
if (widget && widget->IsActive()) {
|
||||||
|
poseView->CommitActivePose();
|
||||||
|
found = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found && column->Editable()) {
|
||||||
|
BRect bounds;
|
||||||
|
if (poseView->ViewMode() == kListMode) {
|
||||||
|
int32 poseIndex = poseView->IndexOfPose(this);
|
||||||
|
BPoint poseLoc(0, poseIndex * poseView->ListElemHeight());
|
||||||
|
bounds = widget->CalcRect(poseLoc, column, poseView);
|
||||||
|
} else
|
||||||
|
bounds = widget->CalcRect(fLocation, 0, poseView);
|
||||||
|
|
||||||
|
widget->StartEdit(bounds, poseView, this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::EditNextWidget(BPoseView *poseView)
|
||||||
|
{
|
||||||
|
EditPreviousNextWidgetCommon(poseView, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::EditPreviousWidget(BPoseView *poseView)
|
||||||
|
{
|
||||||
|
EditPreviousNextWidgetCommon(poseView, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPose::PointInPose(const BPoseView *poseView, BPoint where) const
|
||||||
|
{
|
||||||
|
ASSERT(poseView->ViewMode() != kListMode);
|
||||||
|
|
||||||
|
if (poseView->ViewMode() == kIconMode) {
|
||||||
|
// check icon rect, then actual icon pixel
|
||||||
|
BRect rect(fLocation, fLocation);
|
||||||
|
rect.right += B_LARGE_ICON - 1;
|
||||||
|
rect.bottom += B_LARGE_ICON - 1;
|
||||||
|
|
||||||
|
if (rect.Contains(where))
|
||||||
|
return TestLargeIconPixel(where - fLocation);
|
||||||
|
|
||||||
|
BTextWidget *widget = WidgetFor(poseView->FirstColumn()->AttrHash());
|
||||||
|
if (widget) {
|
||||||
|
float textWidth = ceilf(widget->TextWidth(poseView) + 1);
|
||||||
|
rect.left += (B_LARGE_ICON - textWidth) / 2;
|
||||||
|
rect.right = rect.left + textWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.top = fLocation.y + B_LARGE_ICON;
|
||||||
|
rect.bottom = rect.top + poseView->FontHeight();
|
||||||
|
|
||||||
|
return rect.Contains(where);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MINI_ICON_MODE rect calc
|
||||||
|
BRect rect(fLocation, fLocation);
|
||||||
|
rect.right += B_MINI_ICON + kMiniIconSeparator;
|
||||||
|
rect.bottom += poseView->IconPoseHeight();
|
||||||
|
BTextWidget *widget = WidgetFor(poseView->FirstColumn()->AttrHash());
|
||||||
|
if (widget)
|
||||||
|
rect.right += ceil(widget->TextWidth(poseView) + 1);
|
||||||
|
|
||||||
|
return rect.Contains(where);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPose::PointInPose(BPoint loc, const BPoseView *poseView, BPoint where,
|
||||||
|
BTextWidget **hitWidget) const
|
||||||
|
{
|
||||||
|
if (hitWidget)
|
||||||
|
*hitWidget = NULL;
|
||||||
|
|
||||||
|
// check intersection with icon
|
||||||
|
BRect rect;
|
||||||
|
rect.left = loc.x + kListOffset;
|
||||||
|
rect.right = rect.left + B_MINI_ICON;
|
||||||
|
rect.bottom = loc.y + poseView->ListElemHeight();
|
||||||
|
rect.top = rect.bottom - B_MINI_ICON;
|
||||||
|
if (rect.Contains(where))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (int32 index = 0; ; index++) {
|
||||||
|
BColumn *column = poseView->ColumnAt(index);
|
||||||
|
if (!column)
|
||||||
|
break;
|
||||||
|
BTextWidget *widget = WidgetFor(column->AttrHash());
|
||||||
|
if (widget && widget->CalcClickRect(loc, column, poseView).Contains(where)) {
|
||||||
|
if (hitWidget)
|
||||||
|
*hitWidget = widget;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::Draw(BRect rect, BPoseView *poseView, BView *drawView, bool fullDraw,
|
||||||
|
const BRegion *updateRgn, BPoint offset, bool selected, bool recalculateText)
|
||||||
|
{
|
||||||
|
if (fClipboardMode == kMoveSelectionTo) {
|
||||||
|
// If the background wasn't cleared and Draw() is not called after
|
||||||
|
// having edited a name or similar (with fullDraw)
|
||||||
|
if (!fBackgroundClean && !fullDraw) {
|
||||||
|
fBackgroundClean = true;
|
||||||
|
poseView->Invalidate(rect);
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
fBackgroundClean = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool directDraw = (drawView == poseView);
|
||||||
|
bool windowActive = poseView->Window()->IsActive();
|
||||||
|
bool showSelectionWhenInactive = poseView->fShowSelectionWhenInactive;
|
||||||
|
bool isDrawingSelectionRect = poseView->fIsDrawingSelectionRect;
|
||||||
|
|
||||||
|
ModelNodeLazyOpener modelOpener(fModel);
|
||||||
|
|
||||||
|
if (poseView->ViewMode() == kListMode) {
|
||||||
|
BRect iconRect(rect);
|
||||||
|
iconRect.OffsetBy(offset);
|
||||||
|
iconRect.left += kListOffset;
|
||||||
|
iconRect.right = iconRect.left + B_MINI_ICON;
|
||||||
|
iconRect.top = iconRect.bottom - B_MINI_ICON;
|
||||||
|
if (!updateRgn || updateRgn->Intersects(iconRect))
|
||||||
|
DrawIcon(iconRect.LeftTop(), drawView, B_MINI_ICON, directDraw,
|
||||||
|
!windowActive && !showSelectionWhenInactive);
|
||||||
|
|
||||||
|
// draw text
|
||||||
|
for (int32 index = 0; ; index++) {
|
||||||
|
BColumn *column = poseView->ColumnAt(index);
|
||||||
|
if (!column)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// if widget doesn't exist, create it
|
||||||
|
BTextWidget *widget = WidgetFor(column, poseView, modelOpener);
|
||||||
|
|
||||||
|
if (widget && widget->IsVisible()) {
|
||||||
|
BRect widgetRect(widget->ColumnRect(rect.LeftTop(), column,
|
||||||
|
poseView));
|
||||||
|
|
||||||
|
if (!updateRgn || updateRgn->Intersects(widgetRect)) {
|
||||||
|
BRect widgetTextRect(widget->CalcRect(rect.LeftTop(), column,
|
||||||
|
poseView));
|
||||||
|
|
||||||
|
if (recalculateText)
|
||||||
|
widget->RecalculateText(poseView);
|
||||||
|
|
||||||
|
widget->Draw(widgetRect, widgetTextRect, column->Width(),
|
||||||
|
poseView, drawView, selected, fClipboardMode, offset, directDraw);
|
||||||
|
|
||||||
|
if (index == 0 && selected) {
|
||||||
|
if (windowActive || isDrawingSelectionRect) {
|
||||||
|
widgetTextRect.OffsetBy(offset);
|
||||||
|
drawView->InvertRect(widgetTextRect);
|
||||||
|
} else if (!windowActive && showSelectionWhenInactive) {
|
||||||
|
widgetTextRect.OffsetBy(offset);
|
||||||
|
drawView->PushState();
|
||||||
|
drawView->SetDrawingMode(B_OP_BLEND);
|
||||||
|
drawView->SetHighColor(128, 128, 128, 255);
|
||||||
|
drawView->FillRect(widgetTextRect);
|
||||||
|
drawView->PopState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fullDraw)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// draw in icon mode
|
||||||
|
if (updateRgn && !updateRgn->Intersects(rect))
|
||||||
|
return;
|
||||||
|
|
||||||
|
BPoint iconOrigin(fLocation);
|
||||||
|
iconOrigin += offset;
|
||||||
|
|
||||||
|
DrawIcon(iconOrigin, drawView, poseView->ViewMode() == kIconMode ?
|
||||||
|
B_LARGE_ICON : B_MINI_ICON, directDraw,
|
||||||
|
!windowActive && !showSelectionWhenInactive && !poseView->IsDesktopWindow());
|
||||||
|
|
||||||
|
BColumn *column = poseView->FirstColumn();
|
||||||
|
if (!column)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BTextWidget *widget = WidgetFor(column, poseView, modelOpener);
|
||||||
|
if (!widget || !widget->IsVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
rect = widget->CalcRect(fLocation, 0, poseView);
|
||||||
|
|
||||||
|
bool selectDuringDraw = directDraw && selected
|
||||||
|
&& (poseView->IsDesktopWindow()
|
||||||
|
|| (windowActive && !poseView->EraseWidgetTextBackground()));
|
||||||
|
|
||||||
|
if (selectDuringDraw) {
|
||||||
|
// draw with dark background to select text
|
||||||
|
drawView->PushState();
|
||||||
|
drawView->SetLowColor(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
widget->Draw(rect, rect, rect.Width(), poseView, drawView,
|
||||||
|
selected, fClipboardMode, offset, directDraw);
|
||||||
|
|
||||||
|
if (selectDuringDraw)
|
||||||
|
drawView->PopState();
|
||||||
|
else if (selected && directDraw) {
|
||||||
|
if (windowActive || isDrawingSelectionRect) {
|
||||||
|
rect.OffsetBy(offset);
|
||||||
|
drawView->InvertRect(rect);
|
||||||
|
} else if (!windowActive && showSelectionWhenInactive) {
|
||||||
|
drawView->PushState();
|
||||||
|
drawView->SetDrawingMode(B_OP_BLEND);
|
||||||
|
drawView->SetHighColor(128, 128, 128, 255);
|
||||||
|
drawView->FillRect(rect);
|
||||||
|
drawView->PopState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::DeselectWithoutErasingBackground(BRect, BPoseView *poseView)
|
||||||
|
{
|
||||||
|
ASSERT(poseView->ViewMode() != kListMode);
|
||||||
|
ASSERT(!poseView->EraseWidgetTextBackground());
|
||||||
|
ASSERT(!IsSelected());
|
||||||
|
|
||||||
|
// draw icon directly
|
||||||
|
if (fPercent == -1)
|
||||||
|
DrawIcon(fLocation, poseView, poseView->ViewMode() == kIconMode ?
|
||||||
|
B_LARGE_ICON : B_MINI_ICON, true);
|
||||||
|
else
|
||||||
|
UpdateIcon(fLocation,poseView);
|
||||||
|
|
||||||
|
BColumn *column = poseView->FirstColumn();
|
||||||
|
if (!column)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BTextWidget *widget = WidgetFor(column->AttrHash());
|
||||||
|
if (!widget || !widget->IsVisible())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// just invalidate the background, don't draw anything
|
||||||
|
poseView->Invalidate(widget->CalcRect(fLocation, 0, poseView));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::MoveTo(BPoint point, BPoseView *poseView, bool inval)
|
||||||
|
{
|
||||||
|
point.x = floorf(point.x);
|
||||||
|
point.y = floorf(point.y);
|
||||||
|
|
||||||
|
BRect oldBounds;
|
||||||
|
|
||||||
|
ASSERT(poseView->ViewMode() != kListMode);
|
||||||
|
if (point == fLocation || poseView->ViewMode() == kListMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (inval)
|
||||||
|
oldBounds = CalcRect(poseView);
|
||||||
|
|
||||||
|
// might need to move a text view if we're active
|
||||||
|
if (poseView->ActivePose() == this) {
|
||||||
|
BView *border_view = poseView->FindView("BorderView");
|
||||||
|
if (border_view)
|
||||||
|
border_view->MoveBy(point.x - fLocation.x, point.y - fLocation.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
fLocation = point;
|
||||||
|
fHasLocation = true;
|
||||||
|
fNeedsSaveLocation = true;
|
||||||
|
|
||||||
|
if (inval) {
|
||||||
|
poseView->Invalidate(oldBounds);
|
||||||
|
poseView->Invalidate(CalcRect(poseView));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BTextWidget *
|
||||||
|
BPose::ActiveWidget() const
|
||||||
|
{
|
||||||
|
for (int32 i = fWidgetList.CountItems();i-- > 0;) {
|
||||||
|
BTextWidget *widget = fWidgetList.ItemAt(i);
|
||||||
|
if (widget->IsActive())
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BTextWidget *
|
||||||
|
BPose::WidgetFor(uint32 attr, int32 *index) const
|
||||||
|
{
|
||||||
|
int32 count = fWidgetList.CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
BTextWidget *widget = fWidgetList.ItemAt(i);
|
||||||
|
if (widget->AttrHash() == attr) {
|
||||||
|
if (index)
|
||||||
|
*index = i;
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BTextWidget *
|
||||||
|
BPose::WidgetFor(BColumn *column, BPoseView *poseView, ModelNodeLazyOpener &opener,
|
||||||
|
int32 *index)
|
||||||
|
{
|
||||||
|
BTextWidget *widget = WidgetFor(column->AttrHash(), index);
|
||||||
|
if (!widget)
|
||||||
|
widget = AddWidget(poseView, column, opener);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPose::TestLargeIconPixel(BPoint point) const
|
||||||
|
{
|
||||||
|
return IconCache::sIconCache->IconHitTest(point, ResolvedModel(),
|
||||||
|
kNormalIcon, B_LARGE_ICON);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::DrawIcon(BPoint where, BView *view, icon_size kind, bool direct, bool drawUnselected)
|
||||||
|
{
|
||||||
|
if (fClipboardMode == kMoveSelectionTo) {
|
||||||
|
view->SetDrawingMode(B_OP_ALPHA);
|
||||||
|
view->SetHighColor(0,0,0,64); // set the level of transparency
|
||||||
|
view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
|
||||||
|
} else if (direct)
|
||||||
|
view->SetDrawingMode(B_OP_OVER);
|
||||||
|
|
||||||
|
IconCache::sIconCache->Draw(ResolvedModel(), view, where,
|
||||||
|
fIsSelected && !drawUnselected ? kSelectedIcon : kNormalIcon, kind, true);
|
||||||
|
|
||||||
|
if (fPercent != -1)
|
||||||
|
DrawBar(where, view, kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::DrawBar(BPoint where,BView *view,icon_size kind)
|
||||||
|
{
|
||||||
|
view->PushState();
|
||||||
|
|
||||||
|
int32 size,barWidth,barHeight,yOffset;
|
||||||
|
if (kind == B_LARGE_ICON) {
|
||||||
|
size = B_LARGE_ICON - 1;
|
||||||
|
barWidth = 7;
|
||||||
|
yOffset = 2;
|
||||||
|
barHeight = size - 4 - 2*yOffset;
|
||||||
|
} else {
|
||||||
|
size = B_MINI_ICON;
|
||||||
|
barWidth = 4;
|
||||||
|
yOffset = 0;
|
||||||
|
barHeight = size - 4 - 2*yOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the black shadowed line
|
||||||
|
view->SetHighColor(32,32,32,92);
|
||||||
|
view->MovePenTo(BPoint(where.x + size,where.y + 1 + yOffset));
|
||||||
|
view->StrokeLine(BPoint(where.x + size,where.y + size - yOffset));
|
||||||
|
view->StrokeLine(BPoint(where.x + size - barWidth + 1,where.y + size - yOffset));
|
||||||
|
|
||||||
|
view->SetDrawingMode(B_OP_ALPHA);
|
||||||
|
|
||||||
|
// the gray frame
|
||||||
|
view->SetHighColor(76,76,76,192);
|
||||||
|
BRect rect( where.x + size - barWidth,where.y + yOffset,
|
||||||
|
where.x + size - 1,where.y + size - 1 - yOffset);
|
||||||
|
view->StrokeRect(rect);
|
||||||
|
|
||||||
|
// calculate bar height
|
||||||
|
int32 percent = fPercent > -1 ? fPercent : -2 - fPercent;
|
||||||
|
int32 barPos = int32(barHeight * percent / 100.0);
|
||||||
|
if (barPos < 0)
|
||||||
|
barPos = 0;
|
||||||
|
else if (barPos > barHeight)
|
||||||
|
barPos = barHeight;
|
||||||
|
|
||||||
|
// the free space bar
|
||||||
|
TrackerSettings settings;
|
||||||
|
view->SetHighColor(settings.FreeSpaceColor());
|
||||||
|
|
||||||
|
rect.InsetBy(1,1);
|
||||||
|
BRect bar(rect);
|
||||||
|
bar.bottom = bar.top + barPos - 1;
|
||||||
|
if (barPos > 0)
|
||||||
|
view->FillRect(bar);
|
||||||
|
|
||||||
|
// the used space bar
|
||||||
|
bar.top = bar.bottom + 1;
|
||||||
|
bar.bottom = rect.bottom;
|
||||||
|
view->SetHighColor(fPercent < -1 ? settings.WarningSpaceColor() : settings.UsedSpaceColor());
|
||||||
|
view->FillRect(bar);
|
||||||
|
|
||||||
|
view->PopState();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::DrawToggleSwitch(BRect, BPoseView *)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BRect
|
||||||
|
BPose::CalcRect(BPoint loc, const BPoseView *poseView, bool minimalRect)
|
||||||
|
{
|
||||||
|
ASSERT(poseView->ViewMode() == kListMode);
|
||||||
|
|
||||||
|
BColumn *column = poseView->LastColumn();
|
||||||
|
BRect rect;
|
||||||
|
rect.left = loc.x;
|
||||||
|
rect.top = loc.y;
|
||||||
|
rect.right = loc.x + column->Offset() + column->Width();
|
||||||
|
rect.bottom = rect.top + poseView->ListElemHeight();
|
||||||
|
|
||||||
|
if (minimalRect) {
|
||||||
|
BTextWidget *widget = WidgetFor(poseView->FirstColumn()->AttrHash());
|
||||||
|
if (widget)
|
||||||
|
rect.right = widget->CalcRect(loc, poseView->FirstColumn(), poseView).right;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BRect
|
||||||
|
BPose::CalcRect(const BPoseView *poseView)
|
||||||
|
{
|
||||||
|
|
||||||
|
ASSERT(poseView->ViewMode() != kListMode);
|
||||||
|
|
||||||
|
BRect rect;
|
||||||
|
if (poseView->ViewMode() == kIconMode) {
|
||||||
|
rect.left = fLocation.x;
|
||||||
|
rect.right = rect.left + B_LARGE_ICON;
|
||||||
|
|
||||||
|
BTextWidget *widget = WidgetFor(poseView->FirstColumn()->AttrHash());
|
||||||
|
if (widget) {
|
||||||
|
float textWidth = ceilf(widget->TextWidth(poseView) + 1);
|
||||||
|
if (textWidth > B_LARGE_ICON) {
|
||||||
|
rect.left += (B_LARGE_ICON - textWidth) / 2;
|
||||||
|
rect.right = rect.left + textWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.top = fLocation.y;
|
||||||
|
rect.bottom = rect.top + poseView->IconPoseHeight();
|
||||||
|
} else {
|
||||||
|
// MINI_ICON_MODE rect calc
|
||||||
|
rect.left = fLocation.x;
|
||||||
|
rect.top = fLocation.y;
|
||||||
|
rect.right = rect.left + B_MINI_ICON + kMiniIconSeparator;
|
||||||
|
rect.bottom = rect.top + poseView->IconPoseHeight();
|
||||||
|
BTextWidget *widget = WidgetFor(poseView->FirstColumn()->AttrHash());
|
||||||
|
if (widget)
|
||||||
|
rect.right += ceil(widget->TextWidth(poseView) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
|
||||||
|
void
|
||||||
|
BPose::PrintToStream()
|
||||||
|
{
|
||||||
|
TargetModel()->PrintToStream();
|
||||||
|
PRINT(("%sselected\n", IsSelected() ? "" : "not "));
|
||||||
|
switch (fClipboardMode) {
|
||||||
|
case kMoveSelectionTo:
|
||||||
|
PRINT(("clipboardMode: Cut\n"));
|
||||||
|
break;
|
||||||
|
case kCopySelectionTo:
|
||||||
|
PRINT(("clipboardMode: Copy\n"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PRINT(("clipboardMode: 0 - not in clipboard\n"));
|
||||||
|
}
|
||||||
|
PRINT(("location %s x:%f y:%f\n", HasLocation() ? "" : "unknown ",
|
||||||
|
HasLocation() ? Location().x : 0,
|
||||||
|
HasLocation() ? Location().y : 0));
|
||||||
|
PRINT(("%sautoplaced \n", WasAutoPlaced() ? "was " : "not "));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,334 @@
|
|||||||
|
/*
|
||||||
|
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 _POSE_H
|
||||||
|
#define _POSE_H
|
||||||
|
|
||||||
|
#include <Region.h>
|
||||||
|
|
||||||
|
#include "TextWidget.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BPoseView;
|
||||||
|
class BTextWidget;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
B_NAME_WIDGET,
|
||||||
|
B_ALL_WIDGETS
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BPose {
|
||||||
|
public:
|
||||||
|
BPose(Model *adopt, BPoseView *, bool selected = false);
|
||||||
|
virtual ~BPose();
|
||||||
|
|
||||||
|
BTextWidget *AddWidget(BPoseView *, BColumn *);
|
||||||
|
BTextWidget *AddWidget(BPoseView *, BColumn *, ModelNodeLazyOpener &opener);
|
||||||
|
void RemoveWidget(BPoseView *, BColumn *);
|
||||||
|
void SetLocation(BPoint);
|
||||||
|
void MoveTo(BPoint, BPoseView *, bool inval = true);
|
||||||
|
|
||||||
|
void Draw(BRect, BPoseView *, bool fullDraw = true, const BRegion * = 0,
|
||||||
|
bool recalculateText = false);
|
||||||
|
void Draw(BRect, BPoseView *, BView *drawView, bool fullDraw,
|
||||||
|
const BRegion *, BPoint offset, bool selected, bool recalculateText = false);
|
||||||
|
void DeselectWithoutErasingBackground(BRect rect, BPoseView *poseView);
|
||||||
|
// special purpose draw call for deselecting over a textured
|
||||||
|
// background
|
||||||
|
|
||||||
|
void DrawBar(BPoint where,BView *view,icon_size kind);
|
||||||
|
|
||||||
|
void DrawIcon(BPoint, BView *, icon_size, bool direct, bool drawUnselected = false);
|
||||||
|
void DrawToggleSwitch(BRect, BPoseView *);
|
||||||
|
void MouseUp(BPoint poseLoc, BPoseView *, BPoint where, int32 index);
|
||||||
|
Model* TargetModel() const;
|
||||||
|
Model* ResolvedModel() const;
|
||||||
|
void Select(bool selected);
|
||||||
|
bool IsSelected() const;
|
||||||
|
// Rename to IsHighlighted
|
||||||
|
|
||||||
|
BTextWidget *ActiveWidget() const;
|
||||||
|
BTextWidget *WidgetFor(uint32 hashAttr, int32 *index = 0) const;
|
||||||
|
BTextWidget *WidgetFor(BColumn *column, BPoseView *poseView, ModelNodeLazyOpener &opener,
|
||||||
|
int32 *index = NULL);
|
||||||
|
// adds the widget if needed
|
||||||
|
|
||||||
|
bool PointInPose(BPoint poseLoc, const BPoseView *, BPoint where,
|
||||||
|
BTextWidget ** = NULL) const;
|
||||||
|
bool PointInPose(const BPoseView *, BPoint where) const ;
|
||||||
|
BRect CalcRect(BPoint loc, const BPoseView *, bool minimal_rect = false);
|
||||||
|
BRect CalcRect(const BPoseView *);
|
||||||
|
void UpdateAllWidgets(int32 poseIndex, BPoint poseLoc, BPoseView *);
|
||||||
|
void UpdateWidgetAndModel(Model *resolvedModel, const char *attrName,
|
||||||
|
uint32 attrType, int32 poseIndex, BPoint poseLoc, BPoseView *view);
|
||||||
|
bool UpdateVolumeSpaceBar(bool enabled);
|
||||||
|
void UpdateIcon(BPoint poseLoc, BPoseView *);
|
||||||
|
|
||||||
|
//void UpdateFixedSymlink(BPoint poseLoc, BPoseView *);
|
||||||
|
void UpdateBrokenSymLink(BPoint poseLoc, BPoseView *);
|
||||||
|
void UpdateWasBrokenSymlink(BPoint poseLoc, BPoseView *poseView);
|
||||||
|
|
||||||
|
void Commit(bool saveChanges, BPoint loc, BPoseView *, int32 index);
|
||||||
|
void EditFirstWidget(BPoint poseLoc, BPoseView *);
|
||||||
|
void EditNextWidget(BPoseView *);
|
||||||
|
void EditPreviousWidget(BPoseView *);
|
||||||
|
|
||||||
|
BPoint Location() const;
|
||||||
|
bool DelayedEdit() const;
|
||||||
|
void SetDelayedEdit(bool delay);
|
||||||
|
bool ListModeInited() const;
|
||||||
|
bool HasLocation() const;
|
||||||
|
bool NeedsSaveLocation() const;
|
||||||
|
void SetSaveLocation();
|
||||||
|
bool WasAutoPlaced() const;
|
||||||
|
void SetAutoPlaced(bool);
|
||||||
|
|
||||||
|
uint32 ClipboardMode() const;
|
||||||
|
void SetClipboardMode(uint32 clipboardMode);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
void PrintToStream();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
void EditPreviousNextWidgetCommon(BPoseView *poseView, bool next);
|
||||||
|
void CreateWidgets(BPoseView *);
|
||||||
|
bool TestLargeIconPixel(BPoint) const;
|
||||||
|
|
||||||
|
Model *fModel;
|
||||||
|
BObjectList<BTextWidget> fWidgetList;
|
||||||
|
BPoint fLocation;
|
||||||
|
|
||||||
|
uint32 fClipboardMode;
|
||||||
|
int32 fPercent;
|
||||||
|
|
||||||
|
bool fIsSelected : 1;
|
||||||
|
bool fDelayedEdit : 1;
|
||||||
|
bool fHasLocation : 1;
|
||||||
|
bool fNeedsSaveLocation : 1;
|
||||||
|
bool fListModeInited : 1;
|
||||||
|
bool fWasAutoPlaced : 1;
|
||||||
|
bool fBrokenSymLink : 1;
|
||||||
|
bool fBackgroundClean : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class Param1>
|
||||||
|
void
|
||||||
|
EachTextWidget(BPose *pose, BPoseView *poseView,
|
||||||
|
void (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *, Param1), Param1 p1)
|
||||||
|
{
|
||||||
|
for (int32 index = 0; ;index++) {
|
||||||
|
BColumn *column = poseView->ColumnAt(index);
|
||||||
|
if (!column)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BTextWidget *widget = pose->WidgetFor(column->AttrHash());
|
||||||
|
if (widget)
|
||||||
|
(func)(widget, pose, poseView, column, p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Param1, class Param2>
|
||||||
|
void
|
||||||
|
EachTextWidget(BPose *pose, BPoseView *poseView,
|
||||||
|
void (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *,
|
||||||
|
Param1, Param2), Param1 p1, Param2 p2)
|
||||||
|
{
|
||||||
|
for (int32 index = 0; ;index++) {
|
||||||
|
BColumn *column = poseView->ColumnAt(index);
|
||||||
|
if (!column)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BTextWidget *widget = pose->WidgetFor(column->AttrHash());
|
||||||
|
if (widget)
|
||||||
|
(func)(widget, pose, poseView, column, p1, p2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Result, class Param1, class Param2>
|
||||||
|
Result
|
||||||
|
WhileEachTextWidget(BPose *pose, BPoseView *poseView,
|
||||||
|
Result (*func)(BTextWidget *, BPose *, BPoseView *, BColumn *,
|
||||||
|
Param1, Param2), Param1 p1, Param2 p2)
|
||||||
|
{
|
||||||
|
for (int32 index = 0; ;index++) {
|
||||||
|
BColumn *column = poseView->ColumnAt(index);
|
||||||
|
if (!column)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BTextWidget *widget = pose->WidgetFor(column->AttrHash());
|
||||||
|
if (widget) {
|
||||||
|
Result result = (func)(widget, pose, poseView, column, p1, p2);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Model *
|
||||||
|
BPose::TargetModel() const
|
||||||
|
{
|
||||||
|
return fModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Model *
|
||||||
|
BPose::ResolvedModel() const
|
||||||
|
{
|
||||||
|
return fModel->IsSymLink() ?
|
||||||
|
(fModel->LinkTo() ? fModel->LinkTo() : fModel) : fModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BPose::IsSelected() const
|
||||||
|
{
|
||||||
|
return fIsSelected;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
BPose::Select(bool on)
|
||||||
|
{
|
||||||
|
fIsSelected = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BPose::DelayedEdit() const
|
||||||
|
{
|
||||||
|
return fDelayedEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
BPose::SetDelayedEdit(bool on)
|
||||||
|
{
|
||||||
|
fDelayedEdit = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BPose::NeedsSaveLocation() const
|
||||||
|
{
|
||||||
|
return fNeedsSaveLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
BPose::SetSaveLocation()
|
||||||
|
{
|
||||||
|
fNeedsSaveLocation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BPose::ListModeInited() const
|
||||||
|
{
|
||||||
|
return fListModeInited;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BPose::WasAutoPlaced() const
|
||||||
|
{
|
||||||
|
return fWasAutoPlaced;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
BPose::SetAutoPlaced(bool on)
|
||||||
|
{
|
||||||
|
fWasAutoPlaced = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
BPose::HasLocation() const
|
||||||
|
{
|
||||||
|
return fHasLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline BPoint
|
||||||
|
BPose::Location() const
|
||||||
|
{
|
||||||
|
return fLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
BPose::SetLocation(BPoint point)
|
||||||
|
{
|
||||||
|
fLocation = BPoint(floorf(point.x), floorf(point.y));
|
||||||
|
fHasLocation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
BPose::Draw(BRect rect, BPoseView *view, bool fullDraw, const BRegion *updateRgn,
|
||||||
|
bool recalculateText)
|
||||||
|
{
|
||||||
|
Draw(rect, view, (BView *)view, fullDraw, updateRgn, BPoint(0, 0),
|
||||||
|
IsSelected(), recalculateText);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline uint32
|
||||||
|
BPose::ClipboardMode() const
|
||||||
|
{
|
||||||
|
return fClipboardMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
BPose::SetClipboardMode(uint32 clipboardMode)
|
||||||
|
{
|
||||||
|
fClipboardMode = clipboardMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Icon cache is used for drawing node icons; it caches icons
|
||||||
|
// and reuses them for successive draws
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
|
||||||
|
#include "PoseList.h"
|
||||||
|
#include "Pose.h"
|
||||||
|
|
||||||
|
|
||||||
|
BPose *
|
||||||
|
PoseList::FindPose(const node_ref *node, int32 *resultingIndex) const
|
||||||
|
{
|
||||||
|
int32 count = CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++) {
|
||||||
|
BPose *pose = ItemAt(index);
|
||||||
|
ASSERT(pose->TargetModel());
|
||||||
|
if (*pose->TargetModel()->NodeRef() == *node) {
|
||||||
|
if (resultingIndex)
|
||||||
|
*resultingIndex = index;
|
||||||
|
return pose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPose *
|
||||||
|
PoseList::FindPose(const entry_ref *entry, int32 *resultingIndex) const
|
||||||
|
{
|
||||||
|
int32 count = CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++) {
|
||||||
|
BPose *pose = ItemAt(index);
|
||||||
|
ASSERT(pose->TargetModel());
|
||||||
|
if (*pose->TargetModel()->EntryRef() == *entry) {
|
||||||
|
if (resultingIndex)
|
||||||
|
*resultingIndex = index;
|
||||||
|
return pose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPose *
|
||||||
|
PoseList::FindPose(const Model *model, int32 *resultingIndex) const
|
||||||
|
{
|
||||||
|
return FindPose(model->NodeRef(), resultingIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
BPose *
|
||||||
|
PoseList::DeepFindPose(const node_ref *node, int32 *resultingIndex) const
|
||||||
|
{
|
||||||
|
int32 count = CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++) {
|
||||||
|
BPose *pose = ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel();
|
||||||
|
if (*model->NodeRef() == *node) {
|
||||||
|
if (resultingIndex)
|
||||||
|
*resultingIndex = index;
|
||||||
|
return pose;
|
||||||
|
}
|
||||||
|
// if model is a symlink, try matching node with the target
|
||||||
|
// of the link
|
||||||
|
if (model->IsSymLink()) {
|
||||||
|
model = model->LinkTo();
|
||||||
|
if (model && *model->NodeRef() == *node) {
|
||||||
|
if (resultingIndex)
|
||||||
|
*resultingIndex = index;
|
||||||
|
return pose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPose *
|
||||||
|
PoseList::FindVolumePose(const dev_t device, int32 *resultingIndex) const
|
||||||
|
{
|
||||||
|
int32 count = CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++) {
|
||||||
|
BPose *pose = ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel();
|
||||||
|
ASSERT(model);
|
||||||
|
if (model->IsVolume() && model->NodeRef()->device == device) {
|
||||||
|
if (resultingIndex)
|
||||||
|
*resultingIndex = index;
|
||||||
|
return pose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// PoseList is a commonly used instance of BObjectList<BPose>
|
||||||
|
// Defines convenience find and iteration calls
|
||||||
|
|
||||||
|
#ifndef _POSE_LIST_H
|
||||||
|
#define _POSE_LIST_H
|
||||||
|
|
||||||
|
#include "ObjectList.h"
|
||||||
|
|
||||||
|
struct node_ref;
|
||||||
|
struct entry_ref;
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BPose;
|
||||||
|
class Model;
|
||||||
|
|
||||||
|
class PoseList : public BObjectList<BPose> {
|
||||||
|
public:
|
||||||
|
PoseList(int32 itemsPerBlock = 20, bool owning = false)
|
||||||
|
: BObjectList<BPose>(itemsPerBlock, owning)
|
||||||
|
{}
|
||||||
|
|
||||||
|
PoseList(const PoseList &list)
|
||||||
|
: BObjectList<BPose>(list)
|
||||||
|
{}
|
||||||
|
|
||||||
|
BPose *FindPose(const node_ref *node, int32 *index = NULL) const;
|
||||||
|
BPose *FindPose(const entry_ref *entry, int32 *index = NULL) const;
|
||||||
|
BPose *FindPose(const Model *model, int32 *index = NULL) const;
|
||||||
|
BPose *DeepFindPose(const node_ref *node, int32 *index = NULL) const;
|
||||||
|
// same as FindPose, node can be a target of the actual
|
||||||
|
// pose if the pose is a symlink
|
||||||
|
BPose *FindVolumePose(const dev_t device, int32 *index = NULL) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// iteration glue, add permutations as needed
|
||||||
|
|
||||||
|
template<class EachParam1>
|
||||||
|
void
|
||||||
|
EachPoseAndModel(PoseList *list, void (*eachFunction)(BPose *, Model *, EachParam1),
|
||||||
|
EachParam1 eachParam1)
|
||||||
|
{
|
||||||
|
for (int32 index = list->CountItems() - 1; index >= 0; index--) {
|
||||||
|
BPose *pose = list->ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel();
|
||||||
|
if (model)
|
||||||
|
(eachFunction)(pose, model, eachParam1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class EachParam1>
|
||||||
|
void
|
||||||
|
EachPoseAndModel(PoseList *list, void (*eachFunction)(BPose *, Model *, int32 ,
|
||||||
|
EachParam1), EachParam1 eachParam1)
|
||||||
|
{
|
||||||
|
for (int32 index = list->CountItems() - 1; index >= 0; index--) {
|
||||||
|
BPose *pose = list->ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel();
|
||||||
|
if (model)
|
||||||
|
(eachFunction)(pose, model, index, eachParam1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class EachParam1, class EachParam2>
|
||||||
|
void
|
||||||
|
EachPoseAndModel(PoseList *list, void (*eachFunction)(BPose *, Model *, EachParam1,
|
||||||
|
EachParam2), EachParam1 eachParam1, EachParam2 eachParam2)
|
||||||
|
{
|
||||||
|
for (int32 index = list->CountItems() - 1; index >= 0; index--) {
|
||||||
|
BPose *pose = list->ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel();
|
||||||
|
if (model)
|
||||||
|
(eachFunction)(pose, model, eachParam1, eachParam2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class EachParam1, class EachParam2>
|
||||||
|
void
|
||||||
|
EachPoseAndModel(PoseList *list, void (*eachFunction)(BPose *, Model *, int32,
|
||||||
|
EachParam1, EachParam2), EachParam1 eachParam1, EachParam2 eachParam2)
|
||||||
|
{
|
||||||
|
for (int32 index = list->CountItems() - 1; index >= 0; index--) {
|
||||||
|
BPose *pose = list->ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel();
|
||||||
|
if (model)
|
||||||
|
(eachFunction)(pose, model, index, eachParam1, eachParam2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class EachParam1>
|
||||||
|
void
|
||||||
|
EachPoseAndResolvedModel(PoseList *list, void (*eachFunction)(BPose *, Model *, EachParam1),
|
||||||
|
EachParam1 eachParam1)
|
||||||
|
{
|
||||||
|
for (int32 index = list->CountItems() - 1; index >= 0; index--) {
|
||||||
|
BPose *pose = list->ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel()->ResolveIfLink();
|
||||||
|
if (model)
|
||||||
|
(eachFunction)(pose, model, eachParam1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class EachParam1>
|
||||||
|
void
|
||||||
|
EachPoseAndResolvedModel(PoseList *list, void (*eachFunction)(BPose *, Model *, int32 ,
|
||||||
|
EachParam1), EachParam1 eachParam1)
|
||||||
|
{
|
||||||
|
for (int32 index = list->CountItems() - 1; index >= 0; index--) {
|
||||||
|
BPose *pose = list->ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel()->ResolveIfLink();
|
||||||
|
if (model)
|
||||||
|
(eachFunction)(pose, model, index, eachParam1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class EachParam1, class EachParam2>
|
||||||
|
void
|
||||||
|
EachPoseAndResolvedModel(PoseList *list, void (*eachFunction)(BPose *, Model *, EachParam1,
|
||||||
|
EachParam2), EachParam1 eachParam1, EachParam2 eachParam2)
|
||||||
|
{
|
||||||
|
for (int32 index = list->CountItems() - 1; index >= 0; index--) {
|
||||||
|
BPose *pose = list->ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel()->ResolveIfLink();
|
||||||
|
if (model)
|
||||||
|
(eachFunction)(pose, model, eachParam1, eachParam2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class EachParam1, class EachParam2>
|
||||||
|
void
|
||||||
|
EachPoseAndResolvedModel(PoseList *list, void (*eachFunction)(BPose *, Model *, int32,
|
||||||
|
EachParam1, EachParam2), EachParam1 eachParam1, EachParam2 eachParam2)
|
||||||
|
{
|
||||||
|
for (int32 index = list->CountItems() - 1; index >= 0; index--) {
|
||||||
|
BPose *pose = list->ItemAt(index);
|
||||||
|
Model *model = pose->TargetModel()->ResolveIfLink();
|
||||||
|
if (model)
|
||||||
|
(eachFunction)(pose, model, index, eachParam1, eachParam2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,764 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// PoseView scripting interface
|
||||||
|
|
||||||
|
#include <byteorder.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <PropertyInfo.h>
|
||||||
|
|
||||||
|
#include "Tracker.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
|
||||||
|
#define kPosesSuites "suite/vnd.Be-TrackerPoses"
|
||||||
|
|
||||||
|
#define kPropertyPath "Path"
|
||||||
|
|
||||||
|
#ifndef _SCRIPTING_ONLY
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
#define _SCRIPTING_ONLY(x) x
|
||||||
|
#else
|
||||||
|
#define _SCRIPTING_ONLY(x)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// notes on PoseView scripting interface:
|
||||||
|
// Indices and entry_refs are used to specify poses; In the case of indices
|
||||||
|
// and previous/next specifiers the current PoseView sort order is used.
|
||||||
|
// If PoseView is not in list view mode, the order in which poses are indexed
|
||||||
|
// is arbitrary.
|
||||||
|
// Both of these specifiers, but indices more so, are likely to be accurate only
|
||||||
|
// till a next change to the PoseView (a change may be adding, removing a pose, changing
|
||||||
|
// an attribute or stat resulting in a sort ordering change, changing the sort ordering
|
||||||
|
// rule. When getting a selected item, there is no guarantee that the item will still
|
||||||
|
// be selected after the operation. The client must be able to deal with these
|
||||||
|
// inaccuracies.
|
||||||
|
// Specifying an index/entry_ref that no longer exists will be handled well.
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
doo Tracker get Suites of Poses of Window test
|
||||||
|
doo Tracker get Path of Poses of Window test
|
||||||
|
doo Tracker count Entry of Poses of Window test
|
||||||
|
doo Tracker get Entry of Poses of Window test
|
||||||
|
doo Tracker get Entry 2 of Poses of Window test
|
||||||
|
doo Tracker count Selection of Poses of Window test
|
||||||
|
doo Tracker get Selection of Poses of Window test
|
||||||
|
doo Tracker delete Entry 'test/6L6' of Poses of Window test
|
||||||
|
doo Tracker execute Entry 'test/6L6' of Poses of Window test
|
||||||
|
doo Tracker execute Entry 2 of Poses of Window test
|
||||||
|
doo Tracker set Selection of Poses of Window test to [0,2]
|
||||||
|
doo Tracker set Selection of Poses of Window test to 'test/KT55'
|
||||||
|
doo Tracker create Selection of Poses of Window test to 'test/EL34'
|
||||||
|
doo Tracker delete Selection 'test/EL34' of Poses of Window test
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ToDo:
|
||||||
|
// access list view column state
|
||||||
|
// access poses
|
||||||
|
// - pose location
|
||||||
|
// - pose text widgets
|
||||||
|
|
||||||
|
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
|
||||||
|
const property_info kPosesPropertyList[] = {
|
||||||
|
{ kPropertyPath,
|
||||||
|
{ B_GET_PROPERTY },
|
||||||
|
{ B_DIRECT_SPECIFIER },
|
||||||
|
"get Path of ... # returns the path of a Tracker window, "
|
||||||
|
"error if no path associated",
|
||||||
|
0,
|
||||||
|
{ B_REF_TYPE },
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ kPropertyEntry,
|
||||||
|
{ B_COUNT_PROPERTIES },
|
||||||
|
{ B_DIRECT_SPECIFIER },
|
||||||
|
"count Entry of ... # count entries in a PoseView",
|
||||||
|
0,
|
||||||
|
{ B_INT32_TYPE },
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ kPropertyEntry,
|
||||||
|
{ B_DELETE_PROPERTY },
|
||||||
|
{ B_ENTRY_SPECIFIER, B_INDEX_SPECIFIER },
|
||||||
|
"delete Entry {path|index} # deletes specified entries in a PoseView",
|
||||||
|
0,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ kPropertyEntry,
|
||||||
|
{ B_GET_PROPERTY },
|
||||||
|
{ B_DIRECT_SPECIFIER, B_INDEX_SPECIFIER, kPreviousSpecifier, kNextSpecifier },
|
||||||
|
"get Entry [next|previous|index] # returns specified entries",
|
||||||
|
0,
|
||||||
|
{ B_REF_TYPE },
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ kPropertyEntry,
|
||||||
|
{ B_EXECUTE_PROPERTY },
|
||||||
|
{ B_ENTRY_SPECIFIER, B_INDEX_SPECIFIER },
|
||||||
|
"execute Entry {path|index} # opens specified entries",
|
||||||
|
0,
|
||||||
|
{ B_REF_TYPE },
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ kPropertySelection,
|
||||||
|
{ B_GET_PROPERTY },
|
||||||
|
{ B_DIRECT_SPECIFIER, kPreviousSpecifier, kNextSpecifier },
|
||||||
|
"get Selection [next|previous] # returns the selected entries",
|
||||||
|
0,
|
||||||
|
{ B_REF_TYPE },
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ kPropertySelection,
|
||||||
|
{ B_SET_PROPERTY },
|
||||||
|
{ B_DIRECT_SPECIFIER, kPreviousSpecifier, kNextSpecifier },
|
||||||
|
"set Selection of ... to {next|previous|entry} # selects specified entries",
|
||||||
|
0,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ kPropertySelection,
|
||||||
|
{ B_COUNT_PROPERTIES },
|
||||||
|
{ B_DIRECT_SPECIFIER },
|
||||||
|
"count Selection of ... # counts selected items",
|
||||||
|
0,
|
||||||
|
{ B_INT32_TYPE },
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ kPropertySelection,
|
||||||
|
{ B_CREATE_PROPERTY },
|
||||||
|
{ B_DIRECT_SPECIFIER },
|
||||||
|
"create selection of ... to {entry|index} "
|
||||||
|
"# adds specified items to a selection in a PoseView",
|
||||||
|
0,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ kPropertySelection,
|
||||||
|
{ B_DELETE_PROPERTY },
|
||||||
|
{ B_ENTRY_SPECIFIER, B_INDEX_SPECIFIER },
|
||||||
|
"delete selection {path|index} of ... "
|
||||||
|
"# removes specified items from a selection in a PoseView",
|
||||||
|
0,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{NULL,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
NULL, 0,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BPoseView::GetSupportedSuites(BMessage *_SCRIPTING_ONLY(data))
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
data->AddString("suites", kPosesSuites);
|
||||||
|
BPropertyInfo propertyInfo(const_cast<property_info *>(kPosesPropertyList));
|
||||||
|
data->AddFlat("messages", &propertyInfo);
|
||||||
|
|
||||||
|
return _inherited::GetSupportedSuites(data);
|
||||||
|
#else
|
||||||
|
return B_UNSUPPORTED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPoseView::HandleScriptingMessage(BMessage *_SCRIPTING_ONLY(message))
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
if (message->what != B_GET_PROPERTY
|
||||||
|
&& message->what != B_SET_PROPERTY
|
||||||
|
&& message->what != B_CREATE_PROPERTY
|
||||||
|
&& message->what != B_COUNT_PROPERTIES
|
||||||
|
&& message->what != B_DELETE_PROPERTY
|
||||||
|
&& message->what != B_EXECUTE_PROPERTY)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// dispatch scripting messages
|
||||||
|
BMessage reply(B_REPLY);
|
||||||
|
const char *property = 0;
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
int32 index = 0;
|
||||||
|
int32 form = 0;
|
||||||
|
BMessage specifier;
|
||||||
|
status_t result = message->GetCurrentSpecifier(&index, &specifier,
|
||||||
|
&form, &property);
|
||||||
|
|
||||||
|
if (result != B_OK || index == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ASSERT(property);
|
||||||
|
|
||||||
|
switch (message->what) {
|
||||||
|
case B_CREATE_PROPERTY:
|
||||||
|
handled = CreateProperty(message, &specifier, form, property, &reply);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_GET_PROPERTY:
|
||||||
|
handled = GetProperty(&specifier, form, property, &reply);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_SET_PROPERTY:
|
||||||
|
handled = SetProperty(message, &specifier, form, property, &reply);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_COUNT_PROPERTIES:
|
||||||
|
handled = CountProperty(&specifier, form, property, &reply);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_DELETE_PROPERTY:
|
||||||
|
handled = DeleteProperty(&specifier, form, property, &reply);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_EXECUTE_PROPERTY:
|
||||||
|
handled = ExecuteProperty(&specifier, form, property, &reply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled)
|
||||||
|
// done handling message, send a reply
|
||||||
|
message->SendReply(&reply);
|
||||||
|
return handled;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPoseView::ExecuteProperty(BMessage *_SCRIPTING_ONLY(specifier),
|
||||||
|
int32 _SCRIPTING_ONLY(form), const char *_SCRIPTING_ONLY(property),
|
||||||
|
BMessage *_SCRIPTING_ONLY(reply))
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
status_t error = B_OK;
|
||||||
|
bool handled = false;
|
||||||
|
if (strcmp(property, kPropertyEntry) == 0) {
|
||||||
|
BMessage launchMessage(B_REFS_RECEIVED);
|
||||||
|
|
||||||
|
if (form == (int32)B_ENTRY_SPECIFIER) {
|
||||||
|
// move all poses specified by entry_ref to Trash
|
||||||
|
entry_ref ref;
|
||||||
|
for (int32 index = 0; specifier->FindRef("refs", index, &ref)
|
||||||
|
== B_OK; index++)
|
||||||
|
launchMessage.AddRef("refs", &ref);
|
||||||
|
|
||||||
|
} else if (form == (int32)B_INDEX_SPECIFIER) {
|
||||||
|
// move all poses specified by index to Trash
|
||||||
|
int32 specifyingIndex;
|
||||||
|
for (int32 index = 0; specifier->FindInt32("index", index,
|
||||||
|
&specifyingIndex) == B_OK; index++) {
|
||||||
|
BPose *pose = PoseAtIndex(specifyingIndex);
|
||||||
|
|
||||||
|
if (!pose) {
|
||||||
|
error = B_ENTRY_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
launchMessage.AddRef("refs", pose->TargetModel()->EntryRef());
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (error == B_OK) {
|
||||||
|
// add a messenger to the launch message that will be used to
|
||||||
|
// dispatch scripting calls from apps to the PoseView
|
||||||
|
launchMessage.AddMessenger("TrackerViewToken", BMessenger(this, 0, 0));
|
||||||
|
if (fSelectionHandler)
|
||||||
|
fSelectionHandler->PostMessage(&launchMessage);
|
||||||
|
}
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != B_OK)
|
||||||
|
reply->AddInt32("error", error);
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPoseView::CreateProperty(BMessage *_SCRIPTING_ONLY(specifier), BMessage *,
|
||||||
|
int32 _SCRIPTING_ONLY(form), const char *_SCRIPTING_ONLY(property),
|
||||||
|
BMessage *_SCRIPTING_ONLY(reply))
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
status_t error = B_OK;
|
||||||
|
bool handled = false;
|
||||||
|
if (strcmp(property, kPropertySelection) == 0) {
|
||||||
|
// creating on a selection expands the current selection
|
||||||
|
|
||||||
|
if (form != B_DIRECT_SPECIFIER)
|
||||||
|
// only support direct specifier
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// items to add to a selection may be passed as refs or as indices
|
||||||
|
if (specifier->HasRef("data")) {
|
||||||
|
entry_ref ref;
|
||||||
|
// select poses specified by entries
|
||||||
|
for (int32 index = 0; specifier->FindRef("data", index, &ref)
|
||||||
|
== B_OK; index++) {
|
||||||
|
|
||||||
|
int32 poseIndex;
|
||||||
|
BPose *pose = FindPose(&ref, form, &poseIndex);
|
||||||
|
|
||||||
|
if (!pose) {
|
||||||
|
error = B_ENTRY_NOT_FOUND;
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddPoseToSelection(pose, poseIndex);
|
||||||
|
}
|
||||||
|
handled = true;
|
||||||
|
} else {
|
||||||
|
// select poses specified by indices
|
||||||
|
int32 specifyingIndex;
|
||||||
|
for (int32 index = 0; specifier->FindInt32("data", index,
|
||||||
|
&specifyingIndex) == B_OK; index++) {
|
||||||
|
|
||||||
|
BPose *pose = PoseAtIndex(specifyingIndex);
|
||||||
|
if (!pose) {
|
||||||
|
error = B_BAD_INDEX;
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddPoseToSelection(pose, specifyingIndex);
|
||||||
|
}
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != B_OK)
|
||||||
|
reply->AddInt32("error", error);
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPoseView::DeleteProperty(BMessage *_SCRIPTING_ONLY(specifier),
|
||||||
|
int32 _SCRIPTING_ONLY(form), const char *_SCRIPTING_ONLY(property),
|
||||||
|
BMessage *_SCRIPTING_ONLY(reply))
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
status_t error = B_OK;
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
if (strcmp(property, kPropertySelection) == 0) {
|
||||||
|
// deleting on a selection is handled as removing a part of the selection
|
||||||
|
// not to be confused with deleting a selected item
|
||||||
|
|
||||||
|
if (form == (int32)B_ENTRY_SPECIFIER) {
|
||||||
|
entry_ref ref;
|
||||||
|
// select poses specified by entries
|
||||||
|
for (int32 index = 0; specifier->FindRef("refs", index, &ref)
|
||||||
|
== B_OK; index++) {
|
||||||
|
|
||||||
|
int32 poseIndex;
|
||||||
|
BPose *pose = FindPose(&ref, form, &poseIndex);
|
||||||
|
|
||||||
|
if (!pose) {
|
||||||
|
error = B_ENTRY_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemovePoseFromSelection(pose);
|
||||||
|
}
|
||||||
|
handled = true;
|
||||||
|
|
||||||
|
} else if (form == B_INDEX_SPECIFIER) {
|
||||||
|
// move all poses specified by index to Trash
|
||||||
|
int32 specifyingIndex;
|
||||||
|
for (int32 index = 0; specifier->FindInt32("index", index,
|
||||||
|
&specifyingIndex) == B_OK; index++) {
|
||||||
|
BPose *pose = PoseAtIndex(specifyingIndex);
|
||||||
|
|
||||||
|
if (!pose) {
|
||||||
|
error = B_BAD_INDEX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemovePoseFromSelection(pose);
|
||||||
|
}
|
||||||
|
handled = true;
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else if (strcmp(property, kPropertyEntry) == 0) {
|
||||||
|
// deleting entries is handled by moving entries to trash
|
||||||
|
|
||||||
|
// build a list of entries, specified by the specifier
|
||||||
|
BObjectList<entry_ref> *entryList = new BObjectList<entry_ref>();
|
||||||
|
// list will be deleted for us by the trashing thread
|
||||||
|
|
||||||
|
if (form == (int32)B_ENTRY_SPECIFIER) {
|
||||||
|
// move all poses specified by entry_ref to Trash
|
||||||
|
entry_ref ref;
|
||||||
|
for (int32 index = 0; specifier->FindRef("refs", index, &ref)
|
||||||
|
== B_OK; index++)
|
||||||
|
entryList->AddItem(new entry_ref(ref));
|
||||||
|
|
||||||
|
} else if (form == (int32)B_INDEX_SPECIFIER) {
|
||||||
|
// move all poses specified by index to Trash
|
||||||
|
int32 specifyingIndex;
|
||||||
|
for (int32 index = 0; specifier->FindInt32("index", index, &specifyingIndex)
|
||||||
|
== B_OK; index++) {
|
||||||
|
BPose *pose = PoseAtIndex(specifyingIndex);
|
||||||
|
|
||||||
|
if (!pose) {
|
||||||
|
error = B_BAD_INDEX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
entryList->AddItem(new entry_ref(*pose->TargetModel()->EntryRef()));
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (error == B_OK) {
|
||||||
|
TrackerSettings settings;
|
||||||
|
if (!settings.DontMoveFilesToTrash()) {
|
||||||
|
// move the list we build into trash, don't make the trashing task
|
||||||
|
// select the next item
|
||||||
|
MoveListToTrash(entryList, false, false);
|
||||||
|
} else
|
||||||
|
Delete(entryList, false, settings.AskBeforeDeleteFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != B_OK)
|
||||||
|
reply->AddInt32("error", error);
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPoseView::CountProperty(BMessage *, int32, const char *_SCRIPTING_ONLY(property),
|
||||||
|
BMessage *_SCRIPTING_ONLY(reply))
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
bool handled = false;
|
||||||
|
// PRINT(("BPoseView::CountProperty, %s\n", property));
|
||||||
|
|
||||||
|
// just return the respecitve counts
|
||||||
|
if (strcmp(property, kPropertySelection) == 0) {
|
||||||
|
reply->AddInt32("result", fSelectionList->CountItems());
|
||||||
|
handled = true;
|
||||||
|
} else if (strcmp(property, kPropertyEntry) == 0) {
|
||||||
|
reply->AddInt32("result", fPoseList->CountItems());
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
return handled;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPoseView::GetProperty(BMessage *_SCRIPTING_ONLY(specifier),
|
||||||
|
int32 _SCRIPTING_ONLY(form), const char *_SCRIPTING_ONLY(property),
|
||||||
|
BMessage *_SCRIPTING_ONLY(reply))
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
// PRINT(("GetProperty %s\n", property));
|
||||||
|
bool handled = false;
|
||||||
|
status_t error = B_OK;
|
||||||
|
|
||||||
|
if (strcmp(property, kPropertyPath) == 0) {
|
||||||
|
if (form == B_DIRECT_SPECIFIER) {
|
||||||
|
handled = true;
|
||||||
|
if (!TargetModel())
|
||||||
|
error = B_NOT_A_DIRECTORY;
|
||||||
|
else
|
||||||
|
reply->AddRef("result", TargetModel()->EntryRef());
|
||||||
|
}
|
||||||
|
} else if (strcmp(property, kPropertySelection) == 0) {
|
||||||
|
int32 count = fSelectionList->CountItems();
|
||||||
|
switch (form) {
|
||||||
|
case B_DIRECT_SPECIFIER:
|
||||||
|
// return entries of all poses in selection
|
||||||
|
for (int32 index = 0; index < count; index++)
|
||||||
|
reply->AddRef("result", fSelectionList->ItemAt(index)->
|
||||||
|
TargetModel()->EntryRef());
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kPreviousSpecifier:
|
||||||
|
case kNextSpecifier:
|
||||||
|
{
|
||||||
|
// return entry and index of selected pose before or after
|
||||||
|
// specified pose
|
||||||
|
entry_ref ref;
|
||||||
|
if (specifier->FindRef("data", &ref) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int32 poseIndex;
|
||||||
|
BPose *pose = FindPose(&ref, &poseIndex);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (form == (int32)kPreviousSpecifier)
|
||||||
|
pose = PoseAtIndex(--poseIndex);
|
||||||
|
else if (form == (int32)kNextSpecifier)
|
||||||
|
pose = PoseAtIndex(++poseIndex);
|
||||||
|
|
||||||
|
if (!pose) {
|
||||||
|
error = B_ENTRY_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pose->IsSelected()) {
|
||||||
|
reply->AddRef("result", pose->TargetModel()->EntryRef());
|
||||||
|
reply->AddInt32("index", IndexOfPose(pose));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (strcmp(property, kPropertyEntry) == 0) {
|
||||||
|
int32 count = fPoseList->CountItems();
|
||||||
|
switch (form) {
|
||||||
|
case B_DIRECT_SPECIFIER:
|
||||||
|
// return all entries of all poses in PoseView
|
||||||
|
for (int32 index = 0; index < count; index++)
|
||||||
|
reply->AddRef("result", PoseAtIndex(index)->TargetModel()->EntryRef());
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
case B_INDEX_SPECIFIER:
|
||||||
|
{
|
||||||
|
// return entry at index
|
||||||
|
int32 index;
|
||||||
|
if (specifier->FindInt32("index", &index) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!PoseAtIndex(index)) {
|
||||||
|
error = B_BAD_INDEX;
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
reply->AddRef("result", PoseAtIndex(index)->TargetModel()->EntryRef());
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kPreviousSpecifier:
|
||||||
|
case kNextSpecifier:
|
||||||
|
{
|
||||||
|
// return entry and index of pose before or after specified pose
|
||||||
|
entry_ref ref;
|
||||||
|
if (specifier->FindRef("data", &ref) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int32 tmp;
|
||||||
|
BPose *pose = FindPose(&ref, form, &tmp);
|
||||||
|
|
||||||
|
if (!pose) {
|
||||||
|
error = B_ENTRY_NOT_FOUND;
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
reply->AddRef("result", pose->TargetModel()->EntryRef());
|
||||||
|
reply->AddInt32("index", IndexOfPose(pose));
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != B_OK)
|
||||||
|
reply->AddInt32("error", error);
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BPoseView::SetProperty(BMessage *_SCRIPTING_ONLY(message), BMessage *,
|
||||||
|
int32 _SCRIPTING_ONLY(form), const char *_SCRIPTING_ONLY(property),
|
||||||
|
BMessage *_SCRIPTING_ONLY(reply))
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
status_t error = B_OK;
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
if (strcmp(property, kPropertySelection) == 0) {
|
||||||
|
entry_ref ref;
|
||||||
|
|
||||||
|
switch (form) {
|
||||||
|
case B_DIRECT_SPECIFIER:
|
||||||
|
{
|
||||||
|
int32 selStart;
|
||||||
|
int32 selEnd;
|
||||||
|
if (message->FindInt32("data", 0, &selStart) == B_OK
|
||||||
|
&& message->FindInt32("data", 1, &selEnd) == B_OK) {
|
||||||
|
|
||||||
|
if (selStart < 0 || selStart >= fPoseList->CountItems()
|
||||||
|
|| selEnd < 0 || selEnd >= fPoseList->CountItems()) {
|
||||||
|
error = B_BAD_INDEX;
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectPoses(selStart, selEnd);
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fall thru
|
||||||
|
case kPreviousSpecifier:
|
||||||
|
case kNextSpecifier:
|
||||||
|
{
|
||||||
|
// PRINT(("SetProperty direct/previous/next %s\n", property));
|
||||||
|
// select/unselect poses specified by entries
|
||||||
|
bool clearSelection = true;
|
||||||
|
for (int32 index = 0; message->FindRef("data", index, &ref)
|
||||||
|
== B_OK; index++) {
|
||||||
|
|
||||||
|
int32 poseIndex;
|
||||||
|
BPose *pose = FindPose(&ref, form, &poseIndex);
|
||||||
|
|
||||||
|
if (!pose) {
|
||||||
|
error = B_ENTRY_NOT_FOUND;
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearSelection) {
|
||||||
|
// first selected item must call SelectPose so the selection
|
||||||
|
// gets cleared first
|
||||||
|
SelectPose(pose, poseIndex);
|
||||||
|
clearSelection = false;
|
||||||
|
} else
|
||||||
|
AddPoseToSelection(pose, poseIndex);
|
||||||
|
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != B_OK)
|
||||||
|
reply->AddInt32("error", error);
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
BHandler *
|
||||||
|
BPoseView::ResolveSpecifier(BMessage *_SCRIPTING_ONLY(message),
|
||||||
|
int32 _SCRIPTING_ONLY(index), BMessage *_SCRIPTING_ONLY(specifier),
|
||||||
|
int32 _SCRIPTING_ONLY(form), const char *_SCRIPTING_ONLY(property))
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
BPropertyInfo propertyInfo(const_cast<property_info *>(kPosesPropertyList));
|
||||||
|
|
||||||
|
int32 result = propertyInfo.FindMatch(message, index, specifier, form, property);
|
||||||
|
if (result < 0) {
|
||||||
|
// PRINT(("FindMatch result %d \n"));
|
||||||
|
return _inherited::ResolveSpecifier(message, index, specifier,
|
||||||
|
form, property);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
BPose *
|
||||||
|
BPoseView::FindPose(const entry_ref *_SCRIPTING_ONLY(ref),
|
||||||
|
int32 _SCRIPTING_ONLY(specifierForm), int32 *_SCRIPTING_ONLY(index)) const
|
||||||
|
{
|
||||||
|
#if _SUPPORTS_FEATURE_SCRIPTING
|
||||||
|
// flavor of FindPose, used by previous/next specifiers
|
||||||
|
|
||||||
|
BPose *pose = FindPose(ref, index);
|
||||||
|
|
||||||
|
if (specifierForm == (int32)kPreviousSpecifier)
|
||||||
|
return PoseAtIndex(--*index);
|
||||||
|
else if (specifierForm == (int32)kNextSpecifier)
|
||||||
|
return PoseAtIndex(++*index);
|
||||||
|
else
|
||||||
|
return pose;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
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 __PUBLIC_COMMANDS__
|
||||||
|
#define __PUBLIC_COMMANDS__
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
// commands that may be issued to the tracker by other apps using messengers
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
const uint32 kFindButton = 'Tfnd';
|
||||||
|
const uint32 kSaveButton = 'Tsav';
|
||||||
|
const uint32 kShowSplash = 'Spls';
|
||||||
|
|
||||||
|
const uint32 kStartWatchClipboardRefs = 'TCbw';
|
||||||
|
// StartWatching() clipboard changes. Changes will be sent to given BMessenger "target"
|
||||||
|
const uint32 kStopWatchClipboardRefs = 'TCfw';
|
||||||
|
// StopWatching() given BMessenger "target"
|
||||||
|
const uint32 kFSClipboardChanges = 'TCch';
|
||||||
|
// Used by FSClipboard functions which change refs in clipboard and are used outside Tracker (like BFilePanel called in another app)
|
||||||
|
// Contains movemodes named as in FSClipboard operations and in Clipboard (look into FSClipboard files)
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif /* __PUBLIC_COMMANDS__ */
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Menu.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <Query.h>
|
||||||
|
|
||||||
|
#include "Attributes.h"
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "QueryContainerWindow.h"
|
||||||
|
#include "QueryPoseView.h"
|
||||||
|
|
||||||
|
|
||||||
|
BQueryContainerWindow::BQueryContainerWindow(LockingList<BWindow> *windowList,
|
||||||
|
uint32 containerWindowFlags, window_look look,
|
||||||
|
window_feel feel, uint32 flags, uint32 workspace)
|
||||||
|
: BContainerWindow(windowList, containerWindowFlags, look, feel,
|
||||||
|
flags, workspace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BPoseView *
|
||||||
|
BQueryContainerWindow::NewPoseView(Model *model, BRect rect, uint32)
|
||||||
|
{
|
||||||
|
return new BQueryPoseView(model, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BQueryPoseView *
|
||||||
|
BQueryContainerWindow::PoseView() const
|
||||||
|
{
|
||||||
|
return static_cast<BQueryPoseView *>(fPoseView);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryContainerWindow::CreatePoseView(Model *model)
|
||||||
|
{
|
||||||
|
BRect rect(Bounds());
|
||||||
|
rect.right -= B_V_SCROLL_BAR_WIDTH;
|
||||||
|
rect.bottom -= B_H_SCROLL_BAR_HEIGHT;
|
||||||
|
fPoseView = NewPoseView(model, rect, kListMode);
|
||||||
|
|
||||||
|
AddChild(fPoseView);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryContainerWindow::AddWindowMenu(BMenu *menu)
|
||||||
|
{
|
||||||
|
BMenuItem *item;
|
||||||
|
|
||||||
|
item = new BMenuItem("Resize to Fit", new BMessage(kResizeToFit), 'Y');
|
||||||
|
item->SetTarget(this);
|
||||||
|
menu->AddItem(item);
|
||||||
|
|
||||||
|
item = new BMenuItem("Select"B_UTF8_ELLIPSIS, new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY);
|
||||||
|
item->SetTarget(PoseView());
|
||||||
|
menu->AddItem(item);
|
||||||
|
|
||||||
|
item = new BMenuItem("Select All", new BMessage(B_SELECT_ALL), 'A');
|
||||||
|
item->SetTarget(PoseView());
|
||||||
|
menu->AddItem(item);
|
||||||
|
|
||||||
|
item = new BMenuItem("Invert Selection", new BMessage(kInvertSelection), 'S');
|
||||||
|
item->SetTarget(PoseView());
|
||||||
|
menu->AddItem(item);
|
||||||
|
|
||||||
|
item = new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED), 'W');
|
||||||
|
item->SetTarget(this);
|
||||||
|
menu->AddItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryContainerWindow::AddWindowContextMenus(BMenu *menu)
|
||||||
|
{
|
||||||
|
BMenuItem *resizeItem = new BMenuItem("Resize to Fit",
|
||||||
|
new BMessage(kResizeToFit), 'Y');
|
||||||
|
menu->AddItem(resizeItem);
|
||||||
|
menu->AddItem(new BMenuItem("Select"B_UTF8_ELLIPSIS, new BMessage(kShowSelectionWindow), 'A', B_SHIFT_KEY));
|
||||||
|
menu->AddItem(new BMenuItem("Select All", new BMessage(B_SELECT_ALL), 'A'));
|
||||||
|
BMenuItem *closeItem = new BMenuItem("Close",
|
||||||
|
new BMessage(B_QUIT_REQUESTED), 'W');
|
||||||
|
menu->AddItem(closeItem);
|
||||||
|
// target items as needed
|
||||||
|
menu->SetTargetForItems(PoseView());
|
||||||
|
closeItem->SetTarget(this);
|
||||||
|
resizeItem->SetTarget(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryContainerWindow::SetUpDefaultState()
|
||||||
|
{
|
||||||
|
BNode defaultingNode;
|
||||||
|
|
||||||
|
WindowStateNodeOpener opener(this, true);
|
||||||
|
// this is our destination node, whatever it is for this window
|
||||||
|
if (!opener.StreamNode())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BString defaultStatePath(kQueryTemplates);
|
||||||
|
BString sanitizedType(PoseView()->SearchForType());
|
||||||
|
|
||||||
|
defaultStatePath += '/';
|
||||||
|
int32 length = sanitizedType.Length();
|
||||||
|
char *buf = sanitizedType.LockBuffer(length);
|
||||||
|
for (int32 index = length - 1; index >= 0; index--)
|
||||||
|
if (buf[index] == '/')
|
||||||
|
buf[index] = '_';
|
||||||
|
sanitizedType.UnlockBuffer(length);
|
||||||
|
|
||||||
|
defaultStatePath += sanitizedType;
|
||||||
|
|
||||||
|
PRINT(("looking for default query state at %s\n", defaultStatePath.String()));
|
||||||
|
|
||||||
|
if (!DefaultStateSourceNode(defaultStatePath.String(), &defaultingNode, false)) {
|
||||||
|
TRACE();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy over the attributes
|
||||||
|
|
||||||
|
// set up a filter of the attributes we want copied
|
||||||
|
const char *allowAttrs[] = {
|
||||||
|
kAttrWindowFrame,
|
||||||
|
kAttrViewState,
|
||||||
|
kAttrViewStateForeign,
|
||||||
|
kAttrColumns,
|
||||||
|
kAttrColumnsForeign,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
// do it
|
||||||
|
AttributeStreamMemoryNode memoryNode;
|
||||||
|
NamesToAcceptAttrFilter filter(allowAttrs);
|
||||||
|
AttributeStreamFileNode fileNode(&defaultingNode);
|
||||||
|
*opener.StreamNode() << memoryNode << filter << fileNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BQueryContainerWindow::ActiveOnDevice(dev_t device) const
|
||||||
|
{
|
||||||
|
return PoseView()->ActiveOnDevice(device);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
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 _QUERY_CONTAINER_WINDOW_H
|
||||||
|
#define _QUERY_CONTAINER_WINDOW_H
|
||||||
|
|
||||||
|
#include "ContainerWindow.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
// Container window specificaly used for displaying BQueryPoseViews
|
||||||
|
// Adds query window specific menus
|
||||||
|
|
||||||
|
|
||||||
|
#define kQueryTemplates "DefaultQueryTemplates"
|
||||||
|
|
||||||
|
class BQueryPoseView;
|
||||||
|
|
||||||
|
class BQueryContainerWindow : public BContainerWindow {
|
||||||
|
public:
|
||||||
|
BQueryContainerWindow(LockingList<BWindow> *windowList,
|
||||||
|
uint32 containerWindowFlags,
|
||||||
|
window_look look = B_DOCUMENT_WINDOW_LOOK,
|
||||||
|
window_feel feel = B_NORMAL_WINDOW_FEEL,
|
||||||
|
uint32 flags = B_WILL_ACCEPT_FIRST_CLICK | B_NO_WORKSPACE_ACTIVATION,
|
||||||
|
uint32 workspace = B_CURRENT_WORKSPACE);
|
||||||
|
|
||||||
|
BQueryPoseView *PoseView() const;
|
||||||
|
bool ActiveOnDevice(dev_t) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void CreatePoseView(Model *);
|
||||||
|
virtual BPoseView *NewPoseView(Model *model, BRect rect, uint32 viewMode);
|
||||||
|
virtual void AddWindowMenu(BMenu *menu);
|
||||||
|
virtual void AddWindowContextMenus(BMenu *menu);
|
||||||
|
|
||||||
|
virtual void SetUpDefaultState();
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef BContainerWindow _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,662 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Debug.h>
|
||||||
|
#include <NodeMonitor.h>
|
||||||
|
#include <Query.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
#include <VolumeRoster.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "Attributes.h"
|
||||||
|
#include "AttributeStream.h"
|
||||||
|
#include "AutoLock.h"
|
||||||
|
#include "Commands.h"
|
||||||
|
#include "FindPanel.h"
|
||||||
|
#include "FSUtils.h"
|
||||||
|
#include "MimeTypeList.h"
|
||||||
|
#include "MimeTypes.h"
|
||||||
|
#include "QueryPoseView.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
|
||||||
|
#include <fs_attr.h>
|
||||||
|
|
||||||
|
// Currently filtering out Trash doesn't node monitor too well - if you
|
||||||
|
// remove an item from the Trash, it doesn't show up in the query result
|
||||||
|
// To do this properly, we would have to node monitor everything BQuery
|
||||||
|
// returns and after a node monitor re-chech if it should be part of
|
||||||
|
// query results and add/remove appropriately. Right now only moving to
|
||||||
|
// Trash is supported
|
||||||
|
|
||||||
|
BQueryPoseView::BQueryPoseView(Model *model, BRect frame, uint32 resizeMask)
|
||||||
|
: BPoseView(model, frame, kListMode, resizeMask),
|
||||||
|
fShowResultsFromTrash(false),
|
||||||
|
fQueryList(NULL),
|
||||||
|
fQueryListContainer(NULL),
|
||||||
|
fCreateOldPoseList(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BQueryPoseView::~BQueryPoseView()
|
||||||
|
{
|
||||||
|
delete fQueryListContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case kFSClipboardChanges:
|
||||||
|
{
|
||||||
|
// poses have always to be updated for the query view
|
||||||
|
UpdatePosesClipboardModeFromClipboard(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
_inherited::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::EditQueries()
|
||||||
|
{
|
||||||
|
BMessage message(kEditQuery);
|
||||||
|
message.AddRef("refs", TargetModel()->EntryRef());
|
||||||
|
BMessenger(kTrackerSignature, -1, 0).SendMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::SetUpDefaultColumnsIfNeeded()
|
||||||
|
{
|
||||||
|
// in case there were errors getting some columns
|
||||||
|
if (fColumnList->CountItems() != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fColumnList->AddItem(new BColumn("Name", kColumnStart, 145, B_ALIGN_LEFT,
|
||||||
|
kAttrStatName, B_STRING_TYPE, true, true));
|
||||||
|
fColumnList->AddItem(new BColumn("Path", 200, 225, B_ALIGN_LEFT,
|
||||||
|
kAttrPath, B_STRING_TYPE, true, false));
|
||||||
|
fColumnList->AddItem(new BColumn("Size", 440, 80, B_ALIGN_RIGHT,
|
||||||
|
kAttrStatSize, B_OFF_T_TYPE, true, false));
|
||||||
|
fColumnList->AddItem(new BColumn("Modified", 535, 150, B_ALIGN_LEFT,
|
||||||
|
kAttrStatModified, B_TIME_TYPE, true, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::AttachedToWindow()
|
||||||
|
{
|
||||||
|
_inherited::AttachedToWindow();
|
||||||
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::RestoreState(AttributeStreamNode *node)
|
||||||
|
{
|
||||||
|
_inherited::RestoreState(node);
|
||||||
|
fViewState->SetViewMode(kListMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::RestoreState(const BMessage &message)
|
||||||
|
{
|
||||||
|
_inherited::RestoreState(message);
|
||||||
|
fViewState->SetViewMode(kListMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::SavePoseLocations(BRect *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::SetViewMode(uint32)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::OpenParent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::Refresh()
|
||||||
|
{
|
||||||
|
PRINT(("refreshing dynamic date query\n"));
|
||||||
|
|
||||||
|
// cause the old AddPosesTask to die
|
||||||
|
fAddPosesThreads.clear();
|
||||||
|
delete fQueryListContainer;
|
||||||
|
fQueryListContainer = NULL;
|
||||||
|
|
||||||
|
fCreateOldPoseList = true;
|
||||||
|
AddPoses(TargetModel());
|
||||||
|
TargetModel()->CloseNode();
|
||||||
|
|
||||||
|
ResetOrigin();
|
||||||
|
ResetPosePlacementHint();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BQueryPoseView::ShouldShowPose(const Model *model, const PoseInfo *poseInfo)
|
||||||
|
{
|
||||||
|
// add_poses, etc. filter
|
||||||
|
ASSERT(TargetModel());
|
||||||
|
|
||||||
|
if (!fShowResultsFromTrash
|
||||||
|
&& dynamic_cast<TTracker *>(be_app)->InTrashNode(model->EntryRef()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool result = _inherited::ShouldShowPose(model, poseInfo);
|
||||||
|
|
||||||
|
PoseList *oldPoseList = fQueryListContainer->OldPoseList();
|
||||||
|
if (result && oldPoseList) {
|
||||||
|
// pose will get added - remove it from the old pose list
|
||||||
|
// because it is supposed to be showing
|
||||||
|
BPose *pose = oldPoseList->FindPose(model);
|
||||||
|
if (pose)
|
||||||
|
oldPoseList->RemoveItem(pose);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BQueryPoseView::AddPosesCompleted()
|
||||||
|
{
|
||||||
|
ASSERT(Window()->IsLocked());
|
||||||
|
|
||||||
|
PoseList *oldPoseList = fQueryListContainer->OldPoseList();
|
||||||
|
if (oldPoseList) {
|
||||||
|
int32 count = oldPoseList->CountItems();
|
||||||
|
for (int32 index = count - 1; index >= 0; index--) {
|
||||||
|
BPose *pose = oldPoseList->ItemAt(index);
|
||||||
|
DeletePose(pose->TargetModel()->NodeRef());
|
||||||
|
}
|
||||||
|
fQueryListContainer->ClearOldPoseList();
|
||||||
|
}
|
||||||
|
|
||||||
|
_inherited::AddPosesCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// When using dynamic dates, such as "today", need to refresh the query
|
||||||
|
// window every now and then
|
||||||
|
|
||||||
|
EntryListBase *
|
||||||
|
BQueryPoseView::InitDirentIterator(const entry_ref *ref)
|
||||||
|
{
|
||||||
|
BEntry entry(ref);
|
||||||
|
if (entry.InitCheck() != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Model sourceModel(&entry, true);
|
||||||
|
if (sourceModel.InitCheck() != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ASSERT(sourceModel.IsQuery());
|
||||||
|
|
||||||
|
// old pose list is used for finding poses that no longer match a
|
||||||
|
// dynamic date query during a Refresh call
|
||||||
|
PoseList *oldPoseList = NULL;
|
||||||
|
if (fCreateOldPoseList) {
|
||||||
|
oldPoseList = new PoseList(10, false);
|
||||||
|
oldPoseList->AddList(fPoseList);
|
||||||
|
}
|
||||||
|
|
||||||
|
fQueryListContainer = new QueryEntryListCollection(&sourceModel, this, oldPoseList);
|
||||||
|
fCreateOldPoseList = false;
|
||||||
|
|
||||||
|
if (fQueryListContainer->InitCheck() != B_OK) {
|
||||||
|
delete fQueryListContainer;
|
||||||
|
fQueryListContainer = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fShowResultsFromTrash = fQueryListContainer->ShowResultsFromTrash();
|
||||||
|
|
||||||
|
TTracker::WatchNode(sourceModel.NodeRef(), B_WATCH_NAME | B_WATCH_STAT
|
||||||
|
| B_WATCH_ATTR, this);
|
||||||
|
|
||||||
|
fQueryList = fQueryListContainer->QueryList();
|
||||||
|
|
||||||
|
if (fQueryListContainer->DynamicDateQuery()) {
|
||||||
|
|
||||||
|
// calculate the time to trigger the query refresh - next midnight
|
||||||
|
time_t now = time(0);
|
||||||
|
|
||||||
|
time_t nextMidnight = now + 60 * 60 * 24; // move ahead by a day
|
||||||
|
tm timeData;
|
||||||
|
localtime_r(&nextMidnight, &timeData);
|
||||||
|
timeData.tm_sec = 0;
|
||||||
|
timeData.tm_min = 0;
|
||||||
|
timeData.tm_hour = 0;
|
||||||
|
nextMidnight = mktime(&timeData);
|
||||||
|
|
||||||
|
time_t nextHour = now + 60 * 60; // move ahead by a hour
|
||||||
|
localtime_r(&nextHour, &timeData);
|
||||||
|
timeData.tm_sec = 0;
|
||||||
|
timeData.tm_min = 0;
|
||||||
|
nextHour = mktime(&timeData);
|
||||||
|
|
||||||
|
PRINT(("%ld minutes, %ld seconds till next hour\n", (nextHour - now) / 60,
|
||||||
|
(nextHour - now) % 60));
|
||||||
|
|
||||||
|
time_t nextMinute = now + 60; // move ahead by a minute
|
||||||
|
localtime_r(&nextMinute, &timeData);
|
||||||
|
timeData.tm_sec = 0;
|
||||||
|
nextMinute = mktime(&timeData);
|
||||||
|
|
||||||
|
PRINT(("%ld seconds till next minute\n", nextMinute - now));
|
||||||
|
|
||||||
|
bigtime_t delta;
|
||||||
|
if (fQueryListContainer->DynamicDateRefreshEveryMinute())
|
||||||
|
delta = nextMinute - now;
|
||||||
|
else if (fQueryListContainer->DynamicDateRefreshEveryHour())
|
||||||
|
delta = nextHour - now;
|
||||||
|
else
|
||||||
|
delta = nextMidnight - now;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
int32 secondsTillMidnight = (nextMidnight - now);
|
||||||
|
int32 minutesTillMidnight = secondsTillMidnight/60;
|
||||||
|
secondsTillMidnight %= 60;
|
||||||
|
int32 hoursTillMidnight = minutesTillMidnight/60;
|
||||||
|
minutesTillMidnight %= 60;
|
||||||
|
|
||||||
|
PRINT(("%ld hours, %ld minutes, %ld seconds till midnight\n",
|
||||||
|
hoursTillMidnight, minutesTillMidnight, secondsTillMidnight));
|
||||||
|
|
||||||
|
int32 refreshInSeconds = delta % 60;
|
||||||
|
int32 refreshInMinutes = delta / 60;
|
||||||
|
int32 refreshInHours = refreshInMinutes / 60;
|
||||||
|
refreshInMinutes %= 60;
|
||||||
|
|
||||||
|
PRINT(("next refresh in %ld hours, %ld minutes, %ld seconds\n",
|
||||||
|
refreshInHours, refreshInMinutes, refreshInSeconds));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// bump up to microseconds
|
||||||
|
delta *= 1000000;
|
||||||
|
|
||||||
|
TTracker *tracker = dynamic_cast<TTracker *>(be_app);
|
||||||
|
ASSERT(tracker);
|
||||||
|
tracker->MainTaskLoop()->RunLater(
|
||||||
|
NewLockingMemberFunctionObject(&BQueryPoseView::Refresh, this), delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fQueryListContainer->Clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
BQueryPoseView::WatchNewNodeMask()
|
||||||
|
{
|
||||||
|
return B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
BQueryPoseView::SearchForType() const
|
||||||
|
{
|
||||||
|
if (!fSearchForMimeType.Length()) {
|
||||||
|
BModelOpener opener(TargetModel());
|
||||||
|
BString buffer;
|
||||||
|
attr_info attrInfo;
|
||||||
|
// read the type of files we are looking for
|
||||||
|
status_t status = TargetModel()->Node()->GetAttrInfo(kAttrQueryInitialMime, &attrInfo);
|
||||||
|
if (status == B_OK)
|
||||||
|
TargetModel()->Node()->ReadAttrString(kAttrQueryInitialMime, &buffer);
|
||||||
|
|
||||||
|
if (buffer.Length()) {
|
||||||
|
TTracker *tracker = dynamic_cast<TTracker *>(be_app);
|
||||||
|
if (tracker) {
|
||||||
|
const ShortMimeInfo *info = tracker->MimeTypes()->FindMimeType(buffer.String());
|
||||||
|
if (info)
|
||||||
|
fSearchForMimeType = info->InternalName();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!fSearchForMimeType.Length())
|
||||||
|
fSearchForMimeType = B_FILE_MIMETYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fSearchForMimeType.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BQueryPoseView::ActiveOnDevice(dev_t device) const
|
||||||
|
{
|
||||||
|
int32 count = fQueryList->CountItems();
|
||||||
|
for (int32 index = 0; index < count; index++)
|
||||||
|
if (fQueryList->ItemAt(index)->TargetDevice() == device)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
QueryEntryListCollection::QueryEntryListCollection(Model *model, BHandler *target,
|
||||||
|
PoseList *oldPoseList)
|
||||||
|
: fQueryListRep(new QueryListRep(new BObjectList<BQuery>(5, true)))
|
||||||
|
{
|
||||||
|
Rewind();
|
||||||
|
attr_info info;
|
||||||
|
BQuery query;
|
||||||
|
|
||||||
|
if (!model->Node()) {
|
||||||
|
fStatus = B_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the actual query string
|
||||||
|
fStatus = model->Node()->GetAttrInfo(kAttrQueryString, &info);
|
||||||
|
if (fStatus != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BString buffer;
|
||||||
|
if (model->Node()->ReadAttr(kAttrQueryString, B_STRING_TYPE, 0,
|
||||||
|
buffer.LockBuffer((int32)info.size), (size_t)info.size) != info.size) {
|
||||||
|
fStatus = B_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.UnlockBuffer();
|
||||||
|
|
||||||
|
// read the extra options
|
||||||
|
MoreOptionsStruct saveMoreOptions;
|
||||||
|
if (ReadAttr(model->Node(), kAttrQueryMoreOptions, kAttrQueryMoreOptionsForeign,
|
||||||
|
B_RAW_TYPE, 0, &saveMoreOptions, sizeof(MoreOptionsStruct),
|
||||||
|
&MoreOptionsStruct::EndianSwap) != kReadAttrFailed)
|
||||||
|
fQueryListRep->fShowResultsFromTrash = saveMoreOptions.searchTrash;
|
||||||
|
|
||||||
|
fStatus = query.SetPredicate(buffer.String());
|
||||||
|
|
||||||
|
fQueryListRep->fOldPoseList = oldPoseList;
|
||||||
|
fQueryListRep->fDynamicDateQuery = false;
|
||||||
|
|
||||||
|
fQueryListRep->fRefreshEveryHour = false;
|
||||||
|
fQueryListRep->fRefreshEveryMinute = false;
|
||||||
|
|
||||||
|
if (model->Node()->ReadAttr(kAttrDynamicDateQuery, B_BOOL_TYPE, 0,
|
||||||
|
&fQueryListRep->fDynamicDateQuery, sizeof(bool)) != sizeof(bool))
|
||||||
|
fQueryListRep->fDynamicDateQuery = false;
|
||||||
|
|
||||||
|
if (fQueryListRep->fDynamicDateQuery) {
|
||||||
|
// only refresh every minute on debug builds
|
||||||
|
fQueryListRep->fRefreshEveryMinute = buffer.IFindFirst("second") != -1
|
||||||
|
|| buffer.IFindFirst("minute") != -1;
|
||||||
|
fQueryListRep->fRefreshEveryHour = fQueryListRep->fRefreshEveryMinute
|
||||||
|
|| buffer.IFindFirst("hour") != -1;
|
||||||
|
|
||||||
|
#if !DEBUG
|
||||||
|
// don't refresh every minute unless we are running debug build
|
||||||
|
fQueryListRep->fRefreshEveryMinute = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fStatus != B_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool searchAllVolumes = true;
|
||||||
|
status_t result = B_OK;
|
||||||
|
|
||||||
|
// get volumes to perform query on
|
||||||
|
if (model->Node()->GetAttrInfo(kAttrQueryVolume, &info) == B_OK) {
|
||||||
|
char *buffer = NULL;
|
||||||
|
|
||||||
|
if ((buffer = (char *)malloc(info.size)) != NULL
|
||||||
|
&& model->Node()->ReadAttr(kAttrQueryVolume, B_MESSAGE_TYPE, 0, buffer,
|
||||||
|
(size_t)info.size) == info.size) {
|
||||||
|
|
||||||
|
BMessage message;
|
||||||
|
if (message.Unflatten(buffer) == B_OK) {
|
||||||
|
for (int32 index = 0; ;index++) {
|
||||||
|
ASSERT(index < 100);
|
||||||
|
BVolume volume;
|
||||||
|
// match a volume with the info embedded in the message
|
||||||
|
result = MatchArchivedVolume(&volume, &message, index);
|
||||||
|
if (result == B_OK) {
|
||||||
|
// start the query on this volume
|
||||||
|
result = FetchOneQuery(&query, target,
|
||||||
|
fQueryListRep->fQueryList, &volume);
|
||||||
|
if (result != B_OK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
searchAllVolumes = false;
|
||||||
|
} else if (result != B_DEV_BAD_DRIVE_NUM)
|
||||||
|
// if B_DEV_BAD_DRIVE_NUM, the volume just isn't mounted this
|
||||||
|
// time around, keep looking for more
|
||||||
|
// if other error, bail
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchAllVolumes) {
|
||||||
|
// no specific volumes embedded in query, search everything
|
||||||
|
BVolumeRoster roster;
|
||||||
|
BVolume volume;
|
||||||
|
|
||||||
|
roster.Rewind();
|
||||||
|
while (roster.GetNextVolume(&volume) == B_OK)
|
||||||
|
if (volume.IsPersistent() && volume.KnowsQuery()) {
|
||||||
|
result = FetchOneQuery(&query, target, fQueryListRep->fQueryList, &volume);
|
||||||
|
if (result != B_OK)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fStatus = B_OK;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
QueryEntryListCollection::FetchOneQuery(const BQuery *copyThis,
|
||||||
|
BHandler *target, BObjectList<BQuery> *list, BVolume *volume)
|
||||||
|
{
|
||||||
|
BQuery *query = new BQuery;
|
||||||
|
// have to fake a copy constructor here because BQuery doesn't have
|
||||||
|
// a copy constructor
|
||||||
|
|
||||||
|
BString buffer;
|
||||||
|
const_cast<BQuery *>(copyThis)->GetPredicate(&buffer);
|
||||||
|
query->SetPredicate(buffer.String());
|
||||||
|
|
||||||
|
query->SetTarget(BMessenger(target));
|
||||||
|
query->SetVolume(volume);
|
||||||
|
|
||||||
|
status_t result = query->Fetch();
|
||||||
|
if (result != B_OK) {
|
||||||
|
PRINT(("fetch error %s\n", strerror(result)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
list->AddItem(query);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QueryEntryListCollection::~QueryEntryListCollection()
|
||||||
|
{
|
||||||
|
if (fQueryListRep->CloseQueryList())
|
||||||
|
delete fQueryListRep;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QueryEntryListCollection *
|
||||||
|
QueryEntryListCollection::Clone()
|
||||||
|
{
|
||||||
|
fQueryListRep->OpenQueryList();
|
||||||
|
return new QueryEntryListCollection(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QueryEntryListCollection::QueryEntryListCollection(
|
||||||
|
const QueryEntryListCollection &cloneThis)
|
||||||
|
: EntryListBase(),
|
||||||
|
fQueryListRep(cloneThis.fQueryListRep)
|
||||||
|
{
|
||||||
|
// only to be used by the Clone routine
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
QueryEntryListCollection::ClearOldPoseList()
|
||||||
|
{
|
||||||
|
delete fQueryListRep->fOldPoseList;
|
||||||
|
fQueryListRep->fOldPoseList = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
QueryEntryListCollection::GetNextEntry(BEntry *entry, bool traverse)
|
||||||
|
{
|
||||||
|
status_t result = B_ERROR;
|
||||||
|
|
||||||
|
for (int32 count = fQueryListRep->fQueryList->CountItems();
|
||||||
|
fQueryListRep->fQueryListIndex < count;
|
||||||
|
fQueryListRep->fQueryListIndex++) {
|
||||||
|
result = fQueryListRep->fQueryList->ItemAt(fQueryListRep->fQueryListIndex)
|
||||||
|
->GetNextEntry(entry, traverse);
|
||||||
|
if (result == B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
QueryEntryListCollection::GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count)
|
||||||
|
{
|
||||||
|
int32 result = 0;
|
||||||
|
|
||||||
|
for (int32 queryCount = fQueryListRep->fQueryList->CountItems();
|
||||||
|
fQueryListRep->fQueryListIndex < queryCount;
|
||||||
|
fQueryListRep->fQueryListIndex++) {
|
||||||
|
|
||||||
|
result = fQueryListRep->fQueryList->ItemAt(fQueryListRep->fQueryListIndex)
|
||||||
|
->GetNextDirents(buffer, length, count);
|
||||||
|
if (result > 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
QueryEntryListCollection::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
status_t result = B_ERROR;
|
||||||
|
|
||||||
|
for (int32 count = fQueryListRep->fQueryList->CountItems();
|
||||||
|
fQueryListRep->fQueryListIndex < count;
|
||||||
|
fQueryListRep->fQueryListIndex++) {
|
||||||
|
|
||||||
|
result = fQueryListRep->fQueryList->ItemAt(fQueryListRep->fQueryListIndex)
|
||||||
|
->GetNextRef(ref);
|
||||||
|
if (result == B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
QueryEntryListCollection::Rewind()
|
||||||
|
{
|
||||||
|
fQueryListRep->fQueryListIndex = 0;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
QueryEntryListCollection::CountEntries()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
QueryEntryListCollection::ShowResultsFromTrash() const
|
||||||
|
{
|
||||||
|
return fQueryListRep->fShowResultsFromTrash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
QueryEntryListCollection::DynamicDateQuery() const
|
||||||
|
{
|
||||||
|
return fQueryListRep->fDynamicDateQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
QueryEntryListCollection::DynamicDateRefreshEveryHour() const
|
||||||
|
{
|
||||||
|
return fQueryListRep->fRefreshEveryHour;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
QueryEntryListCollection::DynamicDateRefreshEveryMinute() const
|
||||||
|
{
|
||||||
|
return fQueryListRep->fRefreshEveryMinute;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
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 _QUERY_POSE_VIEW_H
|
||||||
|
#define _QUERY_POSE_VIEW_H
|
||||||
|
|
||||||
|
class BQuery;
|
||||||
|
|
||||||
|
#include "EntryIterator.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BQueryContainerWindow;
|
||||||
|
class QueryEntryListCollection;
|
||||||
|
|
||||||
|
class BQueryPoseView : public BPoseView {
|
||||||
|
public:
|
||||||
|
BQueryPoseView(Model *, BRect, uint32 resizeMask = B_FOLLOW_ALL);
|
||||||
|
virtual ~BQueryPoseView();
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage *message);
|
||||||
|
|
||||||
|
const char *SearchForType() const;
|
||||||
|
BQueryContainerWindow *ContainerWindow() const;
|
||||||
|
bool ActiveOnDevice(dev_t) const;
|
||||||
|
|
||||||
|
void Refresh();
|
||||||
|
// makes queries that are static but need to appear dynamic
|
||||||
|
// live - for instance for a query that contains a
|
||||||
|
// date == today - RestartQuery gets called on midnight to update
|
||||||
|
// the contents
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void RestoreState(AttributeStreamNode *);
|
||||||
|
virtual void RestoreState(const BMessage &);
|
||||||
|
virtual void SavePoseLocations(BRect * = NULL);
|
||||||
|
virtual void SetUpDefaultColumnsIfNeeded();
|
||||||
|
virtual void SetViewMode(uint32);
|
||||||
|
virtual void OpenParent();
|
||||||
|
virtual void EditQueries();
|
||||||
|
virtual EntryListBase *InitDirentIterator(const entry_ref *);
|
||||||
|
virtual uint32 WatchNewNodeMask();
|
||||||
|
virtual bool ShouldShowPose(const Model *, const PoseInfo *);
|
||||||
|
virtual void AddPosesCompleted();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// list of all the queries this PoseView represents
|
||||||
|
// typically there will be one query per volume specified
|
||||||
|
// QueryEntryListCollection provides the abstraction layer
|
||||||
|
// defining the iterators for _add_poses_
|
||||||
|
bool fShowResultsFromTrash;
|
||||||
|
mutable BString fSearchForMimeType;
|
||||||
|
|
||||||
|
BObjectList<BQuery> *fQueryList;
|
||||||
|
QueryEntryListCollection *fQueryListContainer;
|
||||||
|
|
||||||
|
bool fCreateOldPoseList;
|
||||||
|
|
||||||
|
typedef BPoseView _inherited;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class QueryEntryListCollection : public EntryListBase {
|
||||||
|
// This will become a replacement for BDirectory and QueryList in a
|
||||||
|
// PoseView, allowing PoseView to have an arbitrary collection of
|
||||||
|
// elements that behave as an EntryList
|
||||||
|
// For now just manage a list of BQueries
|
||||||
|
|
||||||
|
|
||||||
|
class QueryListRep {
|
||||||
|
public:
|
||||||
|
QueryListRep(BObjectList<BQuery> *queryList)
|
||||||
|
: fQueryList(queryList),
|
||||||
|
fRefCount(0),
|
||||||
|
fShowResultsFromTrash(0),
|
||||||
|
fOldPoseList(NULL)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~QueryListRep()
|
||||||
|
{
|
||||||
|
ASSERT(fRefCount <= 0);
|
||||||
|
delete fQueryList;
|
||||||
|
delete fOldPoseList;
|
||||||
|
}
|
||||||
|
|
||||||
|
BObjectList<BQuery> *OpenQueryList()
|
||||||
|
{
|
||||||
|
fRefCount++;
|
||||||
|
return fQueryList;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CloseQueryList()
|
||||||
|
{
|
||||||
|
return atomic_add(&fRefCount, -1) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BObjectList<BQuery> *fQueryList;
|
||||||
|
int32 fRefCount;
|
||||||
|
bool fShowResultsFromTrash;
|
||||||
|
int32 fQueryListIndex;
|
||||||
|
bool fDynamicDateQuery;
|
||||||
|
bool fRefreshEveryHour;
|
||||||
|
bool fRefreshEveryMinute;
|
||||||
|
|
||||||
|
PoseList *fOldPoseList;
|
||||||
|
// when doing a Refresh, this list is used to detect poses that
|
||||||
|
// are no longer a part of a fDynamicDateQuery and need to be removed
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
QueryEntryListCollection(Model *, BHandler * = NULL, PoseList *oldPoseList = NULL);
|
||||||
|
virtual ~QueryEntryListCollection();
|
||||||
|
|
||||||
|
QueryEntryListCollection *Clone();
|
||||||
|
|
||||||
|
BObjectList<BQuery> *QueryList() const
|
||||||
|
{ return fQueryListRep->fQueryList; }
|
||||||
|
|
||||||
|
PoseList *OldPoseList() const
|
||||||
|
{ return fQueryListRep->fOldPoseList; }
|
||||||
|
void ClearOldPoseList();
|
||||||
|
|
||||||
|
virtual status_t GetNextEntry(BEntry *entry, bool traverse = false);
|
||||||
|
virtual status_t GetNextRef(entry_ref *ref);
|
||||||
|
virtual int32 GetNextDirents(struct dirent *buffer, size_t length,
|
||||||
|
int32 count = INT_MAX);
|
||||||
|
|
||||||
|
virtual status_t Rewind();
|
||||||
|
virtual int32 CountEntries();
|
||||||
|
|
||||||
|
bool ShowResultsFromTrash() const;
|
||||||
|
bool DynamicDateQuery() const;
|
||||||
|
bool DynamicDateRefreshEveryHour() const;
|
||||||
|
bool DynamicDateRefreshEveryMinute() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QueryEntryListCollection(const QueryEntryListCollection &);
|
||||||
|
// only to be used by the Clone routine
|
||||||
|
status_t FetchOneQuery(const BQuery *, BHandler *target,
|
||||||
|
BObjectList<BQuery> *, BVolume *);
|
||||||
|
|
||||||
|
QueryListRep *fQueryListRep;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,457 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Roster.h>
|
||||||
|
|
||||||
|
#include "Attributes.h"
|
||||||
|
#include "IconMenuItem.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "NavMenu.h"
|
||||||
|
#include "PoseView.h"
|
||||||
|
#include "RecentItems.h"
|
||||||
|
#include "SlowMenu.h"
|
||||||
|
#include "Tracker.h"
|
||||||
|
#include "Utilities.h"
|
||||||
|
|
||||||
|
class RecentItemsMenu : public BSlowMenu {
|
||||||
|
public:
|
||||||
|
RecentItemsMenu(const char *title, BMessage *openMessage,
|
||||||
|
BHandler *itemTarget, int32 maxItems)
|
||||||
|
: BSlowMenu(title),
|
||||||
|
fTargetMesage(openMessage),
|
||||||
|
fItemTarget(itemTarget),
|
||||||
|
fMaxCount(maxItems)
|
||||||
|
{}
|
||||||
|
virtual ~RecentItemsMenu();
|
||||||
|
|
||||||
|
virtual bool StartBuildingItemList();
|
||||||
|
virtual bool AddNextItem();
|
||||||
|
virtual void DoneBuildingItemList() {}
|
||||||
|
virtual void ClearMenuBuildingState();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const BMessage *FileMessage()
|
||||||
|
{ return fTargetMesage; }
|
||||||
|
virtual const BMessage *ContainerMessage()
|
||||||
|
{ return fTargetMesage; }
|
||||||
|
|
||||||
|
BRecentItemsList *fTterator;
|
||||||
|
BMessage *fTargetMesage;
|
||||||
|
BHandler *fItemTarget;
|
||||||
|
int32 fCount;
|
||||||
|
int32 fSanityCount;
|
||||||
|
int32 fMaxCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
RecentItemsMenu::~RecentItemsMenu()
|
||||||
|
{
|
||||||
|
delete fTterator;
|
||||||
|
delete fTargetMesage;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
RecentItemsMenu::AddNextItem()
|
||||||
|
{
|
||||||
|
BMenuItem *item = fTterator->GetNextMenuItem(FileMessage(),
|
||||||
|
ContainerMessage(), fItemTarget);
|
||||||
|
|
||||||
|
if (item) {
|
||||||
|
AddItem(item);
|
||||||
|
fCount++;
|
||||||
|
}
|
||||||
|
fSanityCount++;
|
||||||
|
|
||||||
|
return fCount < fMaxCount - 1 && (fSanityCount < fMaxCount + 20);
|
||||||
|
// fSanityCount is a hacky way of dealing with a lot of stale
|
||||||
|
// recent apps
|
||||||
|
}
|
||||||
|
bool
|
||||||
|
RecentItemsMenu::StartBuildingItemList()
|
||||||
|
{
|
||||||
|
// remove any preexisting items
|
||||||
|
int32 itemCount = CountItems();
|
||||||
|
while (itemCount--)
|
||||||
|
delete RemoveItem((int32)0);
|
||||||
|
|
||||||
|
fCount = 0;
|
||||||
|
fSanityCount = 0;
|
||||||
|
fTterator->Rewind();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
RecentItemsMenu::ClearMenuBuildingState()
|
||||||
|
{
|
||||||
|
fMenuBuilt = false;
|
||||||
|
// force rebuilding each time
|
||||||
|
fTterator->Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BRecentItemsList::BRecentItemsList(int32 maxItems, bool navMenuFolders)
|
||||||
|
: fMaxItems(maxItems),
|
||||||
|
fNavMenuFolders(navMenuFolders)
|
||||||
|
{
|
||||||
|
InitIconPreloader();
|
||||||
|
// need the icon cache
|
||||||
|
Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BRecentItemsList::Rewind()
|
||||||
|
{
|
||||||
|
fIndex = 0;
|
||||||
|
fItems.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMenuItem *
|
||||||
|
BRecentItemsList::GetNextMenuItem(const BMessage *fileOpenInvokeMessage,
|
||||||
|
const BMessage *containerOpenInvokeMessage,
|
||||||
|
BHandler *target, entry_ref *currentItemRef)
|
||||||
|
{
|
||||||
|
entry_ref ref;
|
||||||
|
if (GetNextRef(&ref) != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Model model(&ref, true);
|
||||||
|
if (model.InitCheck() != B_OK)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
bool container = false;
|
||||||
|
if (model.IsSymLink()) {
|
||||||
|
|
||||||
|
Model *newResolvedModel = NULL;
|
||||||
|
Model *result = model.LinkTo();
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
newResolvedModel = new Model(model.EntryRef(), true, true);
|
||||||
|
|
||||||
|
if (newResolvedModel->InitCheck() != B_OK) {
|
||||||
|
// broken link, still can show though, bail
|
||||||
|
delete newResolvedModel;
|
||||||
|
result = NULL;
|
||||||
|
} else
|
||||||
|
result = newResolvedModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
BModelOpener opener(result);
|
||||||
|
// open the model, if it ain't open already
|
||||||
|
|
||||||
|
PoseInfo poseInfo;
|
||||||
|
ssize_t size = -1;
|
||||||
|
|
||||||
|
if (result->Node())
|
||||||
|
size = result->Node()->ReadAttr(kAttrPoseInfo, B_RAW_TYPE, 0,
|
||||||
|
&poseInfo, sizeof(poseInfo));
|
||||||
|
|
||||||
|
result->CloseNode();
|
||||||
|
|
||||||
|
if (size == sizeof(poseInfo) && !BPoseView::PoseVisible(result,
|
||||||
|
&poseInfo, false)) {
|
||||||
|
// link target sez it doesn't want to be visible,
|
||||||
|
// don't show the link
|
||||||
|
PRINT(("not showing hidden item %s\n", model.Name()));
|
||||||
|
delete newResolvedModel;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ref = *result->EntryRef();
|
||||||
|
container = result->IsContainer();
|
||||||
|
}
|
||||||
|
model.SetLinkTo(result);
|
||||||
|
} else {
|
||||||
|
ref = *model.EntryRef();
|
||||||
|
container = model.IsContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if user asked for it, return the current item ref
|
||||||
|
if (currentItemRef)
|
||||||
|
*currentItemRef = ref;
|
||||||
|
|
||||||
|
BMessage *message;
|
||||||
|
if (container && containerOpenInvokeMessage)
|
||||||
|
message = new BMessage(*containerOpenInvokeMessage);
|
||||||
|
else if (!container && fileOpenInvokeMessage)
|
||||||
|
message = new BMessage(*fileOpenInvokeMessage);
|
||||||
|
else
|
||||||
|
message = new BMessage(B_REFS_RECEIVED);
|
||||||
|
|
||||||
|
message->AddRef("refs", model.EntryRef());
|
||||||
|
|
||||||
|
// Truncate the name if necessary
|
||||||
|
BString truncatedString(model.Name());
|
||||||
|
be_plain_font->TruncateString(&truncatedString, B_TRUNCATE_END,
|
||||||
|
BNavMenu::GetMaxMenuWidth());
|
||||||
|
|
||||||
|
ModelMenuItem *item = NULL;
|
||||||
|
if (!container || !fNavMenuFolders)
|
||||||
|
item = new ModelMenuItem(&model, truncatedString.String(), message);
|
||||||
|
else {
|
||||||
|
// add another nav menu item if it's a directory
|
||||||
|
BNavMenu *menu = new BNavMenu(truncatedString.String(), message->what,
|
||||||
|
target, 0);
|
||||||
|
|
||||||
|
menu->SetNavDir(&ref);
|
||||||
|
ModelMenuItem *item = new ModelMenuItem(&model, menu);
|
||||||
|
item->SetMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item && target)
|
||||||
|
item->SetTarget(target);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BRecentItemsList::GetNextRef(entry_ref *result)
|
||||||
|
{
|
||||||
|
return fItems.FindRef("refs", fIndex++, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
BRecentFilesList::BRecentFilesList(int32 maxItems, bool navMenuFolders,
|
||||||
|
const char *ofType, const char *openedByAppSig)
|
||||||
|
: BRecentItemsList(maxItems, navMenuFolders),
|
||||||
|
fType(ofType),
|
||||||
|
fTypes(NULL),
|
||||||
|
fTypeCount(0),
|
||||||
|
fAppSig(openedByAppSig)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BRecentFilesList::BRecentFilesList(int32 maxItems, bool navMenuFolders,
|
||||||
|
const char *ofTypeList[], int32 ofTypeListCount, const char *openedByAppSig)
|
||||||
|
: BRecentItemsList(maxItems, navMenuFolders),
|
||||||
|
fType(NULL),
|
||||||
|
fTypes(NULL),
|
||||||
|
fTypeCount(ofTypeListCount),
|
||||||
|
fAppSig(openedByAppSig)
|
||||||
|
{
|
||||||
|
if (fTypeCount) {
|
||||||
|
fTypes = new char *[ofTypeListCount];
|
||||||
|
for (int32 index = 0; index < ofTypeListCount; index++)
|
||||||
|
fTypes[index] = strdup(ofTypeList[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BRecentFilesList::~BRecentFilesList()
|
||||||
|
{
|
||||||
|
if (fTypeCount) {
|
||||||
|
for (int32 index = 0; index < fTypeCount; index++)
|
||||||
|
free(fTypes[index]);
|
||||||
|
delete [] fTypes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BRecentFilesList::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
if (fIndex == 0) {
|
||||||
|
// Lazy roster Get
|
||||||
|
if (fTypes)
|
||||||
|
BRoster().GetRecentDocuments(&fItems, fMaxItems,
|
||||||
|
const_cast<const char **>(fTypes),
|
||||||
|
fTypeCount, fAppSig.Length() ? fAppSig.String() : NULL);
|
||||||
|
else
|
||||||
|
BRoster().GetRecentDocuments(&fItems, fMaxItems,
|
||||||
|
fType.Length() ? fType.String() : NULL,
|
||||||
|
fAppSig.Length() ? fAppSig.String() : NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
return BRecentItemsList::GetNextRef(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RecentFilesMenu : public RecentItemsMenu {
|
||||||
|
public:
|
||||||
|
RecentFilesMenu(const char *title, BMessage *openFileMessage,
|
||||||
|
BMessage *openFolderMessage, BHandler *target,
|
||||||
|
int32 maxItems, bool navMenuFolders, const char *ofType,
|
||||||
|
const char *openedByAppSig);
|
||||||
|
|
||||||
|
RecentFilesMenu(const char *title, BMessage *openFileMessage,
|
||||||
|
BMessage *openFolderMessage, BHandler *target,
|
||||||
|
int32 maxItems, bool navMenuFolders, const char *ofTypeList[],
|
||||||
|
int32 ofTypeListCount, const char *openedByAppSig);
|
||||||
|
|
||||||
|
virtual ~RecentFilesMenu();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const BMessage *ContainerMessage()
|
||||||
|
{ return openFolderMessage; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
BMessage *openFolderMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
RecentFilesMenu::RecentFilesMenu(const char *title, BMessage *openFileMessage,
|
||||||
|
BMessage *openFolderMessage, BHandler *target, int32 maxItems,
|
||||||
|
bool navMenuFolders, const char *ofType, const char *openedByAppSig)
|
||||||
|
: RecentItemsMenu(title, openFileMessage, target, maxItems),
|
||||||
|
openFolderMessage(openFolderMessage)
|
||||||
|
{
|
||||||
|
fTterator = new BRecentFilesList(maxItems + 10, navMenuFolders,
|
||||||
|
ofType, openedByAppSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RecentFilesMenu::RecentFilesMenu(const char *title, BMessage *openFileMessage,
|
||||||
|
BMessage *openFolderMessage, BHandler *target, int32 maxItems,
|
||||||
|
bool navMenuFolders, const char *ofTypeList[], int32 ofTypeListCount,
|
||||||
|
const char *openedByAppSig)
|
||||||
|
: RecentItemsMenu(title, openFileMessage, target, maxItems),
|
||||||
|
openFolderMessage(openFolderMessage)
|
||||||
|
{
|
||||||
|
fTterator = new BRecentFilesList(maxItems + 10, navMenuFolders,
|
||||||
|
ofTypeList, ofTypeListCount, openedByAppSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
RecentFilesMenu::~RecentFilesMenu()
|
||||||
|
{
|
||||||
|
delete openFolderMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
BMenu *
|
||||||
|
BRecentFilesList::NewFileListMenu(const char *title,
|
||||||
|
BMessage *openFileMessage, BMessage *openFolderMessage,
|
||||||
|
BHandler *target, int32 maxItems, bool navMenuFolders, const char *ofType,
|
||||||
|
const char *openedByAppSig)
|
||||||
|
{
|
||||||
|
return new RecentFilesMenu(title, openFileMessage,
|
||||||
|
openFolderMessage, target, maxItems, navMenuFolders, ofType, openedByAppSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
BMenu *
|
||||||
|
BRecentFilesList::NewFileListMenu(const char *title,
|
||||||
|
BMessage *openFileMessage, BMessage *openFolderMessage,
|
||||||
|
BHandler *target, int32 maxItems, bool navMenuFolders, const char *ofTypeList[],
|
||||||
|
int32 ofTypeListCount, const char *openedByAppSig)
|
||||||
|
{
|
||||||
|
return new RecentFilesMenu(title, openFileMessage,
|
||||||
|
openFolderMessage, target, maxItems, navMenuFolders, ofTypeList,
|
||||||
|
ofTypeListCount, openedByAppSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
class RecentFoldersMenu : public RecentItemsMenu {
|
||||||
|
public:
|
||||||
|
RecentFoldersMenu(const char *title, BMessage *openMessage,
|
||||||
|
BHandler *target, int32 maxItems, bool navMenuFolders,
|
||||||
|
const char *openedByAppSig);
|
||||||
|
};
|
||||||
|
|
||||||
|
RecentFoldersMenu::RecentFoldersMenu(const char *title, BMessage *openMessage,
|
||||||
|
BHandler *target, int32 maxItems, bool navMenuFolders, const char *openedByAppSig)
|
||||||
|
: RecentItemsMenu(title, openMessage, target, maxItems)
|
||||||
|
{
|
||||||
|
fTterator = new BRecentFoldersList(maxItems + 10, navMenuFolders,
|
||||||
|
openedByAppSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
BMenu *
|
||||||
|
BRecentFoldersList::NewFolderListMenu(const char *title,
|
||||||
|
BMessage *openMessage, BHandler *target, int32 maxItems,
|
||||||
|
bool navMenuFolders, const char *openedByAppSig)
|
||||||
|
{
|
||||||
|
return new RecentFoldersMenu(title, openMessage, target, maxItems,
|
||||||
|
navMenuFolders, openedByAppSig);
|
||||||
|
}
|
||||||
|
|
||||||
|
BRecentFoldersList::BRecentFoldersList(int32 maxItems, bool navMenuFolders,
|
||||||
|
const char *openedByAppSig)
|
||||||
|
: BRecentItemsList(maxItems, navMenuFolders),
|
||||||
|
fAppSig(openedByAppSig)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BRecentFoldersList::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
if (fIndex == 0) {
|
||||||
|
// Lazy roster Get
|
||||||
|
BRoster().GetRecentFolders(&fItems, fMaxItems,
|
||||||
|
fAppSig.Length() ? fAppSig.String() : NULL);
|
||||||
|
|
||||||
|
}
|
||||||
|
return BRecentItemsList::GetNextRef(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
BRecentAppsList::BRecentAppsList(int32 maxItems)
|
||||||
|
: BRecentItemsList(maxItems, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BRecentAppsList::GetNextRef(entry_ref *ref)
|
||||||
|
{
|
||||||
|
if (fIndex == 0) {
|
||||||
|
// Lazy roster Get
|
||||||
|
BRoster().GetRecentApps(&fItems, fMaxItems);
|
||||||
|
}
|
||||||
|
return BRecentItemsList::GetNextRef(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
class RecentAppsMenu : public RecentItemsMenu {
|
||||||
|
public:
|
||||||
|
RecentAppsMenu(const char *title, BMessage *openMessage,
|
||||||
|
BHandler *target, int32 maxItems);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
RecentAppsMenu::RecentAppsMenu(const char *title, BMessage *openMessage,
|
||||||
|
BHandler *target, int32 maxItems)
|
||||||
|
: RecentItemsMenu(title, openMessage, target, maxItems)
|
||||||
|
{
|
||||||
|
fTterator = new BRecentAppsList(maxItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMenu *
|
||||||
|
BRecentAppsList::NewAppListMenu(const char *title, BMessage *openMessage,
|
||||||
|
BHandler *target, int32 maxItems)
|
||||||
|
{
|
||||||
|
return new RecentAppsMenu(title, openMessage, target, maxItems);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
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 __RECENT_ITEMS_LIST__
|
||||||
|
#define __RECENT_ITEMS_LIST__
|
||||||
|
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
/* BRecentItemsList classes allow creating an entire menu with
|
||||||
|
* recent files, folders, apps. If the user wishes to add items to
|
||||||
|
* their own menu, they can instead use the GetNextMenuItem call to
|
||||||
|
* get one menu at a time to add it to their app.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class BMenuItem;
|
||||||
|
class BMenu;
|
||||||
|
|
||||||
|
class BRecentItemsList {
|
||||||
|
public:
|
||||||
|
BRecentItemsList(int32 maxItems, bool navMenuFolders);
|
||||||
|
/* if <navMenuFolders> passed, folder items get NavMenu-style
|
||||||
|
* subdirectories attached to them
|
||||||
|
*/
|
||||||
|
|
||||||
|
virtual ~BRecentItemsList() {}
|
||||||
|
|
||||||
|
virtual void Rewind();
|
||||||
|
/* resets the iteration */
|
||||||
|
|
||||||
|
virtual BMenuItem *GetNextMenuItem(const BMessage *fileOpenMessage = NULL,
|
||||||
|
const BMessage *containerOpenMessage = NULL,
|
||||||
|
BHandler *target = NULL, entry_ref *currentItemRef = NULL);
|
||||||
|
/* if <fileOpenMessage> specified, the item for a file gets a copy with
|
||||||
|
* the item ref attached as "refs", otherwise a default B_REFS_RECEIVED
|
||||||
|
* message message gets attached
|
||||||
|
* if <containerOpenMessage> specified, the item for a folder, volume or query
|
||||||
|
* gets a copy with the item ref attached as "refs", otherwise a default
|
||||||
|
* B_REFS_RECEIVED message message gets attached
|
||||||
|
* if <currentItemRef> gets passed, the caller gets to look at the
|
||||||
|
* entry_ref corresponding to the item
|
||||||
|
*/
|
||||||
|
|
||||||
|
virtual status_t GetNextRef(entry_ref *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BMessage fItems;
|
||||||
|
int32 fIndex;
|
||||||
|
int32 fMaxItems;
|
||||||
|
bool fNavMenuFolders;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
virtual void _r1();
|
||||||
|
virtual void _r2();
|
||||||
|
virtual void _r3();
|
||||||
|
virtual void _r4();
|
||||||
|
virtual void _r5();
|
||||||
|
virtual void _r6();
|
||||||
|
virtual void _r7();
|
||||||
|
virtual void _r8();
|
||||||
|
virtual void _r9();
|
||||||
|
virtual void _r10();
|
||||||
|
|
||||||
|
uint32 _reserved[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
class BRecentFilesList : public BRecentItemsList {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* use one of the two constructors to set up next item iteration */
|
||||||
|
BRecentFilesList(int32 maxItems = 10, bool navMenuFolders = false,
|
||||||
|
const char *ofType = NULL, const char *openedByAppSig = NULL);
|
||||||
|
BRecentFilesList(int32 maxItems, bool navMenuFolders, const char *ofTypeList[],
|
||||||
|
int32 ofTypeListCount, const char *openedByAppSig = NULL);
|
||||||
|
virtual ~BRecentFilesList();
|
||||||
|
|
||||||
|
/* use one of the two NewFileListMenu calls to get an entire menu */
|
||||||
|
static BMenu *NewFileListMenu(const char *title,
|
||||||
|
BMessage *openFileMessage = NULL, BMessage *openFolderMessage = NULL,
|
||||||
|
BHandler *target = NULL,
|
||||||
|
int32 maxItems = 10, bool navMenuFolders = false,
|
||||||
|
const char *ofType = NULL, const char *openedByAppSig = NULL);
|
||||||
|
|
||||||
|
static BMenu *NewFileListMenu(const char *title,
|
||||||
|
BMessage *openFileMessage, BMessage *openFolderMessage,
|
||||||
|
BHandler *target,
|
||||||
|
int32 maxItems, bool navMenuFolders,
|
||||||
|
const char *ofTypeList[], int32 ofTypeListCount,
|
||||||
|
const char *openedByAppSig);
|
||||||
|
|
||||||
|
virtual status_t GetNextRef(entry_ref *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
BString fType;
|
||||||
|
char **fTypes;
|
||||||
|
int32 fTypeCount;
|
||||||
|
BString fAppSig;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void _r11();
|
||||||
|
virtual void _r12();
|
||||||
|
virtual void _r13();
|
||||||
|
virtual void _r14();
|
||||||
|
virtual void _r15();
|
||||||
|
virtual void _r16();
|
||||||
|
virtual void _r17();
|
||||||
|
virtual void _r18();
|
||||||
|
virtual void _r19();
|
||||||
|
virtual void _r110();
|
||||||
|
|
||||||
|
uint32 _reserved[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
class BRecentFoldersList : public BRecentItemsList {
|
||||||
|
public:
|
||||||
|
/* use the constructor to set up next item iteration */
|
||||||
|
BRecentFoldersList(int32 maxItems, bool navMenuFolders = false,
|
||||||
|
const char *openedByAppSig = NULL);
|
||||||
|
|
||||||
|
/* use NewFolderListMenu to get an entire menu */
|
||||||
|
static BMenu *NewFolderListMenu(const char *title,
|
||||||
|
BMessage *openMessage = NULL, BHandler *target = NULL,
|
||||||
|
int32 maxItems = 10, bool navMenuFolders = false,
|
||||||
|
const char *openedByAppSig = NULL);
|
||||||
|
|
||||||
|
virtual status_t GetNextRef(entry_ref *);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BString fAppSig;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void _r21();
|
||||||
|
virtual void _r22();
|
||||||
|
virtual void _r23();
|
||||||
|
virtual void _r24();
|
||||||
|
virtual void _r25();
|
||||||
|
virtual void _r26();
|
||||||
|
virtual void _r27();
|
||||||
|
virtual void _r28();
|
||||||
|
virtual void _r29();
|
||||||
|
virtual void _r210();
|
||||||
|
|
||||||
|
uint32 _reserved[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
class BRecentAppsList : public BRecentItemsList {
|
||||||
|
public:
|
||||||
|
/* use the constructor to set up next item iteration */
|
||||||
|
BRecentAppsList(int32 maxItems);
|
||||||
|
|
||||||
|
/* use NewFolderListMenu to get an entire menu */
|
||||||
|
static BMenu *NewAppListMenu(const char *title,
|
||||||
|
BMessage *openMessage = NULL, BHandler *target = NULL,
|
||||||
|
int32 maxItems = 10);
|
||||||
|
|
||||||
|
virtual status_t GetNextRef(entry_ref *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void _r31();
|
||||||
|
virtual void _r32();
|
||||||
|
virtual void _r33();
|
||||||
|
virtual void _r34();
|
||||||
|
virtual void _r35();
|
||||||
|
virtual void _r36();
|
||||||
|
virtual void _r37();
|
||||||
|
virtual void _r38();
|
||||||
|
virtual void _r39();
|
||||||
|
virtual void _r310();
|
||||||
|
|
||||||
|
uint32 _reserved[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// This code is based on regexp.c, v.1.3 by Henry Spencer:
|
||||||
|
|
||||||
|
// @(#)regexp.c 1.3 of 18 April 87
|
||||||
|
//
|
||||||
|
// Copyright (c) 1986 by University of Toronto.
|
||||||
|
// Written by Henry Spencer. Not derived from licensed software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any
|
||||||
|
// purpose on any computer system, and to redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The author is not responsible for the consequences of use of
|
||||||
|
// this software, no matter how awful, even if they arise
|
||||||
|
// from defects in it.
|
||||||
|
//
|
||||||
|
// 2. The origin of this software must not be misrepresented, either
|
||||||
|
// by explicit claim or by omission.
|
||||||
|
//
|
||||||
|
// 3. Altered versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// Beware that some of this code is subtly aware of the way operator
|
||||||
|
// precedence is structured in regular expressions. Serious changes in
|
||||||
|
// regular-expression syntax might require a total rethink.
|
||||||
|
//
|
||||||
|
|
||||||
|
// ALTERED VERSION: Adapted to ANSI C and C++ for the OpenTracker
|
||||||
|
// project (www.opentracker.org), Jul 11, 2000.
|
||||||
|
|
||||||
|
#ifndef _REG_EXP_H
|
||||||
|
#define _REG_EXP_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
enum {
|
||||||
|
REGEXP_UNMATCHED_PARENTHESIS = B_ERRORS_END,
|
||||||
|
REGEXP_TOO_BIG,
|
||||||
|
REGEXP_TOO_MANY_PARENTHESIS,
|
||||||
|
REGEXP_JUNK_ON_END,
|
||||||
|
REGEXP_STAR_PLUS_OPERAND_EMPTY,
|
||||||
|
REGEXP_NESTED_STAR_QUESTION_PLUS,
|
||||||
|
REGEXP_INVALID_BRACKET_RANGE,
|
||||||
|
REGEXP_UNMATCHED_BRACKET,
|
||||||
|
REGEXP_INTERNAL_ERROR,
|
||||||
|
REGEXP_QUESTION_PLUS_STAR_FOLLOWS_NOTHING,
|
||||||
|
REGEXP_TRAILING_BACKSLASH,
|
||||||
|
REGEXP_CORRUPTED_PROGRAM,
|
||||||
|
REGEXP_MEMORY_CORRUPTION,
|
||||||
|
REGEXP_CORRUPTED_POINTERS,
|
||||||
|
REGEXP_CORRUPTED_OPCODE
|
||||||
|
};
|
||||||
|
|
||||||
|
const int32 kSubExpressionMax = 10;
|
||||||
|
|
||||||
|
struct regexp {
|
||||||
|
const char *startp[kSubExpressionMax];
|
||||||
|
const char *endp[kSubExpressionMax];
|
||||||
|
char regstart; /* Internal use only. See RegExp.cpp for details. */
|
||||||
|
char reganch; /* Internal use only. */
|
||||||
|
const char *regmust;/* Internal use only. */
|
||||||
|
int regmlen; /* Internal use only. */
|
||||||
|
char program[1]; /* Unwarranted chumminess with compiler. */
|
||||||
|
};
|
||||||
|
|
||||||
|
class RegExp {
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegExp();
|
||||||
|
RegExp(const char *);
|
||||||
|
RegExp(const BString &);
|
||||||
|
~RegExp();
|
||||||
|
|
||||||
|
status_t InitCheck() const;
|
||||||
|
|
||||||
|
status_t SetTo(const char*);
|
||||||
|
status_t SetTo(const BString &);
|
||||||
|
|
||||||
|
bool Matches(const char *string) const;
|
||||||
|
bool Matches(const BString &) const;
|
||||||
|
|
||||||
|
int32 RunMatcher(regexp *, const char *) const;
|
||||||
|
regexp *Compile(const char *);
|
||||||
|
regexp *Expression() const;
|
||||||
|
const char *ErrorString() const;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
void Dump();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void SetError(status_t error) const;
|
||||||
|
|
||||||
|
// Working functions for Compile():
|
||||||
|
char *Reg(int32, int32 *);
|
||||||
|
char *Branch(int32 *);
|
||||||
|
char *Piece(int32 *);
|
||||||
|
char *Atom(int32 *);
|
||||||
|
char *Node(char);
|
||||||
|
char *Next(char *);
|
||||||
|
const char *Next(const char *) const;
|
||||||
|
void Char(char);
|
||||||
|
void Insert(char, char *);
|
||||||
|
void Tail(char *, char *);
|
||||||
|
void OpTail(char *, char *);
|
||||||
|
|
||||||
|
// Working functions for RunMatcher():
|
||||||
|
int32 Try(regexp *, const char *) const;
|
||||||
|
int32 Match(const char *) const;
|
||||||
|
int32 Repeat(const char *) const;
|
||||||
|
|
||||||
|
// Utility functions:
|
||||||
|
#ifdef DEBUG
|
||||||
|
char *Prop(const char *) const;
|
||||||
|
void RegExpError(const char *) const;
|
||||||
|
#endif
|
||||||
|
inline int32 UCharAt(const char *p) const;
|
||||||
|
inline char *Operand(char* p) const;
|
||||||
|
inline const char *Operand(const char* p) const;
|
||||||
|
inline bool IsMult(char c) const;
|
||||||
|
|
||||||
|
// --------- Variables -------------
|
||||||
|
|
||||||
|
mutable status_t fError;
|
||||||
|
regexp *fRegExp;
|
||||||
|
|
||||||
|
// Work variables for Compile().
|
||||||
|
|
||||||
|
const char *fInputScanPointer;
|
||||||
|
int32 fParenthesisCount;
|
||||||
|
char fDummy;
|
||||||
|
char *fCodeEmitPointer; // &fDummy = don't.
|
||||||
|
long fCodeSize;
|
||||||
|
|
||||||
|
// Work variables for RunMatcher().
|
||||||
|
|
||||||
|
mutable const char *fStringInputPointer;
|
||||||
|
mutable const char *fRegBol; // Beginning of input, for ^ check.
|
||||||
|
mutable const char **fStartPArrayPointer;
|
||||||
|
mutable const char **fEndPArrayPointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using namespace BPrivate;
|
||||||
|
|
||||||
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user