* 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:
Axel Dörfler
2006-11-15 10:32:20 +00:00
parent 499aacdd0a
commit 1415b63512
7 changed files with 250 additions and 33 deletions
@@ -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
+53 -31
View File
@@ -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
+91 -1
View File
@@ -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)
+2 -1
View File
@@ -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;
+1
View File
@@ -12,6 +12,7 @@ Preference FileTypes :
FileTypesWindow.cpp
ApplicationTypesWindow.cpp
AttributeListView.cpp
DropTargetListView.cpp
MimeTypeListView.cpp
NewFileTypeWindow.cpp
AttributeWindow.cpp