* Added a simple list view that can indicate that it accepts a dragged object.
* The extension list is now using this list view: when you drop some files on it, it will now take over their extension into the list. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19290 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2006, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "DropTargetListView.h"
|
||||
|
||||
|
||||
DropTargetListView::DropTargetListView(BRect frame, const char* name,
|
||||
list_view_type type, uint32 resizeMask, uint32 flags)
|
||||
: BListView(frame, name, type, resizeMask, flags),
|
||||
fDropTarget(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DropTargetListView::~DropTargetListView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropTargetListView::Draw(BRect updateRect)
|
||||
{
|
||||
BListView::Draw(updateRect);
|
||||
|
||||
if (fDropTarget) {
|
||||
// mark this view as a drop target
|
||||
rgb_color color = HighColor();
|
||||
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
|
||||
StrokeRect(Bounds());
|
||||
SetHighColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropTargetListView::MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* dragMessage)
|
||||
{
|
||||
if (dragMessage != NULL && AcceptsDrag(dragMessage)) {
|
||||
bool dropTarget = transit == B_ENTERED_VIEW || transit == B_INSIDE_VIEW;
|
||||
if (dropTarget != fDropTarget) {
|
||||
fDropTarget = dropTarget;
|
||||
_InvalidateFrame();
|
||||
}
|
||||
} else if (fDropTarget) {
|
||||
fDropTarget = false;
|
||||
_InvalidateFrame();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DropTargetListView::AcceptsDrag(const BMessage* /*message*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropTargetListView::_InvalidateFrame()
|
||||
{
|
||||
Invalidate();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2006, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef DROP_TARGET_LIST_VIEW_H
|
||||
#define DROP_TARGET_LIST_VIEW_H
|
||||
|
||||
|
||||
#include <ListView.h>
|
||||
|
||||
|
||||
class DropTargetListView : public BListView {
|
||||
public:
|
||||
DropTargetListView(BRect frame, const char* name,
|
||||
list_view_type type = B_SINGLE_SELECTION_LIST,
|
||||
uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||
uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE);
|
||||
virtual ~DropTargetListView();
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* dragMessage);
|
||||
|
||||
virtual bool AcceptsDrag(const BMessage* message);
|
||||
|
||||
private:
|
||||
void _InvalidateFrame();
|
||||
|
||||
bool fDropTarget;
|
||||
};
|
||||
|
||||
#endif // DROP_TARGET_LIST_VIEW_H
|
||||
@@ -38,6 +38,57 @@ compare_extensions(const void* _a, const void* _b)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
add_extensions(BMimeType& type, BList& list, const char* removeExtension)
|
||||
{
|
||||
BMessage extensions;
|
||||
status_t status = type.GetFileExtensions(&extensions);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
// replace the entry, and remove any equivalent entries
|
||||
BList newList;
|
||||
newList.AddList(&list);
|
||||
|
||||
const char* extension;
|
||||
for (int32 i = 0; extensions.FindString("extensions", i,
|
||||
&extension) == B_OK; i++) {
|
||||
bool add = true;
|
||||
for (int32 j = list.CountItems(); j-- > 0;) {
|
||||
if ((removeExtension && !strcmp(removeExtension, extension))
|
||||
|| !strcmp((const char*)list.ItemAt(j), extension)) {
|
||||
// remove this item
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (add)
|
||||
newList.AddItem((void *)extension);
|
||||
}
|
||||
|
||||
newList.SortItems(compare_extensions);
|
||||
|
||||
// Copy them to a new message (their memory is still part of the
|
||||
// original BMessage)
|
||||
BMessage newExtensions;
|
||||
for (int32 i = 0; i < newList.CountItems(); i++) {
|
||||
newExtensions.AddString("extensions", (const char*)newList.ItemAt(i));
|
||||
}
|
||||
|
||||
return type.SetFileExtensions(&newExtensions);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
replace_extension(BMimeType& type, const char* newExtension, const char* oldExtension)
|
||||
{
|
||||
BList list;
|
||||
list.AddItem((void *)newExtension);
|
||||
|
||||
return add_extensions(type, list, oldExtension);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@@ -139,37 +190,8 @@ ExtensionWindow::MessageReceived(BMessage* message)
|
||||
if (newExtension[0] == '.')
|
||||
newExtension++;
|
||||
|
||||
BMessage extensions;
|
||||
status_t status = fMimeType.GetFileExtensions(&extensions);
|
||||
if (status == B_OK) {
|
||||
// replace the entry, and remove any equivalent entries
|
||||
BList list;
|
||||
list.AddItem((void *)newExtension);
|
||||
|
||||
const char* extension;
|
||||
for (int32 i = 0; extensions.FindString("extensions", i,
|
||||
&extension) == B_OK; i++) {
|
||||
if (!strcmp(fExtension.String(), extension)
|
||||
|| !strcmp(newExtension, extension)) {
|
||||
// remove this item
|
||||
continue;
|
||||
}
|
||||
|
||||
list.AddItem((void *)extension);
|
||||
}
|
||||
|
||||
list.SortItems(compare_extensions);
|
||||
|
||||
// Copy them to a new message (their memory is still part of the
|
||||
// original BMessage)
|
||||
BMessage newExtensions;
|
||||
for (int32 i = 0; i < list.CountItems(); i++) {
|
||||
newExtensions.AddString("extensions", (const char*)list.ItemAt(i));
|
||||
}
|
||||
|
||||
status = fMimeType.SetFileExtensions(&newExtensions);
|
||||
}
|
||||
|
||||
status_t status = replace_extension(fMimeType, newExtension,
|
||||
fExtension.String());
|
||||
if (status != B_OK)
|
||||
error_alert("Could not change file extensions", status);
|
||||
|
||||
|
||||
@@ -33,4 +33,9 @@ class ExtensionWindow : public BWindow {
|
||||
BButton* fAcceptButton;
|
||||
};
|
||||
|
||||
extern status_t add_extensions(BMimeType& type, BList& list,
|
||||
const char* removeExtension = NULL);
|
||||
extern status_t replace_extension(BMimeType& type, const char* newExtension,
|
||||
const char* oldExtension);
|
||||
|
||||
#endif // EXTENSION_WINDOW_H
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "AttributeListView.h"
|
||||
#include "AttributeWindow.h"
|
||||
#include "DropTargetListView.h"
|
||||
#include "ExtensionWindow.h"
|
||||
#include "FileTypes.h"
|
||||
#include "FileTypesWindow.h"
|
||||
@@ -35,6 +36,7 @@
|
||||
#include <be_apps/Tracker/RecentItems.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
const uint32 kMsgTypeSelected = 'typs';
|
||||
@@ -87,6 +89,23 @@ class TypeIconView : public BControl {
|
||||
icon_source fIconSource;
|
||||
};
|
||||
|
||||
class ExtensionListView : public DropTargetListView {
|
||||
public:
|
||||
ExtensionListView(BRect frame, const char* name,
|
||||
list_view_type type = B_SINGLE_SELECTION_LIST,
|
||||
uint32 resizeMask = B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||
uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE);
|
||||
virtual ~ExtensionListView();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual bool AcceptsDrag(const BMessage* message);
|
||||
|
||||
void SetType(BMimeType* type);
|
||||
|
||||
private:
|
||||
BMimeType fType;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
@@ -238,6 +257,74 @@ TypeIconView::MouseDown(BPoint where)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
ExtensionListView::ExtensionListView(BRect frame, const char* name,
|
||||
list_view_type type, uint32 resizeMask, uint32 flags)
|
||||
: DropTargetListView(frame, name, type, resizeMask, flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ExtensionListView::~ExtensionListView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExtensionListView::MessageReceived(BMessage* message)
|
||||
{
|
||||
if (message->WasDropped() && AcceptsDrag(message)) {
|
||||
// create extension list
|
||||
BList list;
|
||||
entry_ref ref;
|
||||
for (int32 index = 0; message->FindRef("refs", index++, &ref) == B_OK; ) {
|
||||
const char* point = strchr(ref.name, '.');
|
||||
if (point != NULL && point[1])
|
||||
list.AddItem(strdup(++point));
|
||||
}
|
||||
|
||||
add_extensions(fType, list);
|
||||
|
||||
// delete extension list
|
||||
for (int32 index = list.CountItems(); index-- > 0;) {
|
||||
free(list.ItemAt(index));
|
||||
}
|
||||
} else
|
||||
DropTargetListView::MessageReceived(message);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ExtensionListView::AcceptsDrag(const BMessage* message)
|
||||
{
|
||||
if (fType.Type() == NULL)
|
||||
return false;
|
||||
|
||||
int32 count = 0;
|
||||
entry_ref ref;
|
||||
|
||||
for (int32 index = 0; message->FindRef("refs", index++, &ref) == B_OK; ) {
|
||||
const char* point = strchr(ref.name, '.');
|
||||
if (point != NULL && point[1])
|
||||
count++;
|
||||
}
|
||||
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExtensionListView::SetType(BMimeType* type)
|
||||
{
|
||||
if (type != NULL)
|
||||
fType.SetTo(type->Type());
|
||||
else
|
||||
fType.Unset();
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
FileTypesWindow::FileTypesWindow(const BMessage& settings)
|
||||
: BWindow(_Frame(settings), "FileTypes", B_TITLED_WINDOW,
|
||||
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS),
|
||||
@@ -395,7 +482,7 @@ FileTypesWindow::FileTypesWindow(const BMessage& settings)
|
||||
innerRect.top = fAddExtensionButton->Frame().top + 2.0f;
|
||||
innerRect.bottom = innerRect.bottom - 2.0f;
|
||||
// take scrollview border into account
|
||||
fExtensionListView = new BListView(innerRect, "listview ext",
|
||||
fExtensionListView = new ExtensionListView(innerRect, "listview ext",
|
||||
B_SINGLE_SELECTION_LIST, B_FOLLOW_LEFT_RIGHT);
|
||||
fExtensionListView->SetSelectionMessage(new BMessage(kMsgExtensionSelected));
|
||||
fExtensionListView->SetInvocationMessage(new BMessage(kMsgExtensionInvoked));
|
||||
@@ -696,6 +783,8 @@ FileTypesWindow::_SetType(BMimeType* type, int32 forceUpdate)
|
||||
rule = "";
|
||||
fRuleControl->SetText(rule.String());
|
||||
}
|
||||
|
||||
fExtensionListView->SetType(&fCurrentType);
|
||||
} else {
|
||||
fCurrentType.Unset();
|
||||
fInternalNameView->SetText(NULL);
|
||||
@@ -703,6 +792,7 @@ FileTypesWindow::_SetType(BMimeType* type, int32 forceUpdate)
|
||||
fDescriptionControl->SetText(NULL);
|
||||
fRuleControl->SetText(NULL);
|
||||
fPreferredField->Menu()->ItemAt(0)->SetMarked(true);
|
||||
fExtensionListView->SetType(NULL);
|
||||
}
|
||||
|
||||
if ((forceUpdate & B_FILE_EXTENSIONS_CHANGED) != 0)
|
||||
|
||||
@@ -19,6 +19,7 @@ class BOutlineListView;
|
||||
class BTextControl;
|
||||
|
||||
class AttributeListView;
|
||||
class ExtensionListView;
|
||||
class TypeIconView;
|
||||
class MimeTypeListView;
|
||||
class StringView;
|
||||
@@ -54,7 +55,7 @@ class FileTypesWindow : public BWindow {
|
||||
|
||||
BBox* fRecognitionBox;
|
||||
StringView* fExtensionLabel;
|
||||
BListView* fExtensionListView;
|
||||
ExtensionListView* fExtensionListView;
|
||||
BButton* fAddExtensionButton;
|
||||
BButton* fRemoveExtensionButton;
|
||||
BTextControl* fRuleControl;
|
||||
|
||||
@@ -12,6 +12,7 @@ Preference FileTypes :
|
||||
FileTypesWindow.cpp
|
||||
ApplicationTypesWindow.cpp
|
||||
AttributeListView.cpp
|
||||
DropTargetListView.cpp
|
||||
MimeTypeListView.cpp
|
||||
NewFileTypeWindow.cpp
|
||||
AttributeWindow.cpp
|
||||
|
||||
Reference in New Issue
Block a user