From 8e9afca70f0bcb2484b73e4d5cba031f83ce4bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 15 Dec 2004 14:46:39 +0000 Subject: [PATCH] Started implementing drag&drop - for now, you can drag contents out of the DiskProbe window only. Only ASCII clippings will contain "text/plain" data, so don't be surprised if Tracker sometimes doesn't create a clipping file (if you drop on Tracker). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10465 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/diskprobe/DataView.cpp | 59 ++++++++++++++++++++++++++++++--- src/apps/diskprobe/DataView.h | 1 + 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/apps/diskprobe/DataView.cpp b/src/apps/diskprobe/DataView.cpp index 2b0d43dacc..a094857fe9 100644 --- a/src/apps/diskprobe/DataView.cpp +++ b/src/apps/diskprobe/DataView.cpp @@ -30,6 +30,8 @@ static const uint32 kHexByteWidth = 3; * accepted. */ +// ToDo: a valid UTF-8 string would be nicer... + bool is_valid_ascii(uint8 *data, size_t size) { @@ -895,6 +897,45 @@ DataView::FrameResized(float width, float height) } +void +DataView::InitiateDrag(view_focus focus) +{ + BMessage *drag = new BMessage(B_MIME_DATA); + + // Add originator and action + drag->AddPointer("be:originator", this); + //drag->AddString("be:clip_name", "Byte Clipping"); + //drag->AddInt32("be_actions", B_TRASH_TARGET); + + // Add data (just like in Copy()) + uint8 *data = fData + fStart; + size_t length = fEnd + 1 - fStart; + + drag->AddData(B_FILE_MIME_TYPE, B_MIME_TYPE, data, length); + if (is_valid_ascii(data, length)) + drag->AddData("text/plain", B_MIME_TYPE, data, length); + + // get a frame that contains the whole selection - SelectionFrame() + // only spans a rectangle between the start and the end point, so + // we have to pass it the correct input values + + BRect frame; + const int32 width = kBlockSize - 1; + int32 first = fStart & ~width; + int32 last = ((fEnd + width) & ~width) - 1; + if (first == (last & ~width)) + frame = SelectionFrame(focus, fStart, fEnd); + else + frame = SelectionFrame(focus, first, last); + + BRect bounds = Bounds(); + if (!bounds.Contains(frame)) + frame = bounds & frame; + + DragMessage(drag, frame, NULL); +} + + void DataView::MouseDown(BPoint where) { @@ -902,14 +943,24 @@ DataView::MouseDown(BPoint where) BMessage *message = Looper()->CurrentMessage(); int32 buttons; - if (message == NULL || message->FindInt32("buttons", &buttons) != B_OK - || (buttons & B_PRIMARY_MOUSE_BUTTON) == 0) + if (message == NULL || message->FindInt32("buttons", &buttons) != B_OK) + return; + + view_focus newFocus; + int32 position = PositionAt(kNoFocus, where, &newFocus); + + if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0 + && position >= fStart && position <= fEnd) { + InitiateDrag(newFocus); + return; + } + + if ((buttons & B_PRIMARY_MOUSE_BUTTON) == 0) return; int32 modifiers = message->FindInt32("modifiers"); - view_focus newFocus; - fMouseSelectionStart = PositionAt(kNoFocus, where, &newFocus); + fMouseSelectionStart = position; if (fMouseSelectionStart == -1) { // "where" is outside the valid frame return; diff --git a/src/apps/diskprobe/DataView.h b/src/apps/diskprobe/DataView.h index 365763954b..8f38393ae2 100644 --- a/src/apps/diskprobe/DataView.h +++ b/src/apps/diskprobe/DataView.h @@ -77,6 +77,7 @@ class DataView : public BView { void UpdateFromEditor(BMessage *message = NULL); void ConvertLine(char *line, off_t offset, const uint8 *buffer, size_t size); + void InitiateDrag(view_focus focus); void Copy(); void Paste();