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 textencoding ;
|
||||
SubInclude OBOS_TOP src kits translation ;
|
||||
SubInclude OBOS_TOP src kits tracker ;
|
||||
SubInclude OBOS_TOP src kits device ;
|
||||
SubInclude OBOS_TOP src kits game ;
|
||||
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