* Implemented Copy(), Cut(), and Paste() for the hex mode. Additionally, the

text view will now accept raw data in text mode as well.
* This closes bug #3327.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28976 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-01-21 08:31:44 +00:00
parent 8bc239bc55
commit cb744e5c22
+168 -36
View File
@@ -1,21 +1,28 @@
/* /*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2004-2009, Axel Dörfler, [email protected].
** Distributed under the terms of the Haiku License. * Distributed under the terms of the MIT License.
*/ */
#include "FindWindow.h" #include "FindWindow.h"
#include "DataView.h"
#include "DiskProbe.h" #include "DiskProbe.h"
#include <AutoLocker.h>
#include <Application.h> #include <Application.h>
#include <TextView.h> #include <Autolock.h>
#include <MenuField.h>
#include <PopUpMenu.h>
#include <MenuItem.h>
#include <Button.h>
#include <ScrollView.h>
#include <CheckBox.h>
#include <Beep.h> #include <Beep.h>
#include <Button.h>
#include <CheckBox.h>
#include <Clipboard.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <Mime.h>
#include <PopUpMenu.h>
#include <ScrollView.h>
#include <TextView.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@@ -28,7 +35,8 @@ static const uint32 kMsgStartFind = 'SFnd';
class FindTextView : public BTextView { class FindTextView : public BTextView {
public: public:
FindTextView(BRect frame, const char *name, BRect textRect, uint32 resizeMask); FindTextView(BRect frame, const char* name,
BRect textRect, uint32 resizeMask);
virtual void MakeFocus(bool state); virtual void MakeFocus(bool state);
virtual void TargetedByScrollView(BScrollView* view); virtual void TargetedByScrollView(BScrollView* view);
@@ -41,23 +49,27 @@ class FindTextView : public BTextView {
virtual void KeyDown(const char* bytes, int32 numBytes); virtual void KeyDown(const char* bytes, int32 numBytes);
virtual bool AcceptsPaste(BClipboard* clipboard);
virtual void Copy(BClipboard* clipboard);
virtual void Cut(BClipboard* clipboard);
virtual void Paste(BClipboard* clipboard);
protected: protected:
virtual void InsertText(const char* text, int32 length, virtual void InsertText(const char* text, int32 length,
int32 offset, const text_run_array* runs); int32 offset, const text_run_array* runs);
private: private:
void HexReformat(int32 oldCursor, int32 &newCursor); void _HexReformat(int32 oldCursor, int32& newCursor);
status_t GetHexFromData(const uint8 *in, size_t inSize, char **_hex, size_t *_hexSize); status_t _GetHexFromData(const uint8* in, size_t inSize,
status_t GetDataFromHex(const char *text, size_t textLength, uint8 **_data, size_t *_dataSize); char** _hex, size_t* _hexSize);
status_t _GetDataFromHex(const char* text, size_t textLength,
uint8** _data, size_t* _dataSize);
BScrollView* fScrollView; BScrollView* fScrollView;
find_mode fMode; find_mode fMode;
}; };
//---------------
FindTextView::FindTextView(BRect frame, const char* name, BRect textRect, FindTextView::FindTextView(BRect frame, const char* name, BRect textRect,
uint32 resizeMask) uint32 resizeMask)
: BTextView(frame, name, textRect, resizeMask), : BTextView(frame, name, textRect, resizeMask),
@@ -86,7 +98,7 @@ FindTextView::TargetedByScrollView(BScrollView *view)
void void
FindTextView::HexReformat(int32 oldCursor, int32 &newCursor) FindTextView::_HexReformat(int32 oldCursor, int32& newCursor)
{ {
const char* text = Text(); const char* text = Text();
int32 textLength = TextLength(); int32 textLength = TextLength();
@@ -145,7 +157,7 @@ FindTextView::InsertText(const char *text, int32 length, int32 offset,
GetSelection(&start, &end); GetSelection(&start, &end);
int32 cursor; int32 cursor;
HexReformat(offset, cursor); _HexReformat(offset, cursor);
if (length == 1 && start == offset) if (length == 1 && start == offset)
Select(cursor + 1, cursor + 1); Select(cursor + 1, cursor + 1);
@@ -193,7 +205,7 @@ FindTextView::KeyDown(const char *bytes, int32 numBytes)
if (bytes[0] == B_BACKSPACE) if (bytes[0] == B_BACKSPACE)
GetSelection(&start, &end); GetSelection(&start, &end);
HexReformat(start, start); _HexReformat(start, start);
Select(start, start); Select(start, start);
return; return;
} }
@@ -217,8 +229,122 @@ FindTextView::KeyDown(const char *bytes, int32 numBytes)
} }
bool
FindTextView::AcceptsPaste(BClipboard* clipboard)
{
if (clipboard == NULL)
return false;
AutoLocker<BClipboard> _(clipboard);
BMessage* clip = clipboard->Data();
if (clip == NULL)
return false;
if (clip->HasData(B_FILE_MIME_TYPE, B_MIME_TYPE)
|| clip->HasData("text/plain", B_MIME_TYPE))
return true;
return BTextView::AcceptsPaste(clipboard);
}
void
FindTextView::Copy(BClipboard* clipboard)
{
if (fMode != kHexMode) {
BTextView::Copy(clipboard);
return;
}
int32 start, end;
GetSelection(&start, &end);
if (clipboard == NULL || start == end)
return;
AutoLocker<BClipboard> _(clipboard);
BMessage* clip = clipboard->Data();
if (clip == NULL)
return;
// convert hex-text to real data
uint8* data;
size_t dataSize;
if (_GetDataFromHex(Text() + start, end - start, &data, &dataSize)
!= B_OK)
return;
clip->AddData(B_FILE_MIME_TYPE, B_MIME_TYPE, data, dataSize);
if (is_valid_utf8(data, dataSize))
clip->AddData("text/plain", B_MIME_TYPE, data, dataSize);
free(data);
}
void
FindTextView::Cut(BClipboard* clipboard)
{
if (fMode != kHexMode) {
BTextView::Cut(clipboard);
return;
}
int32 start, end;
GetSelection(&start, &end);
if (clipboard == NULL || start == end)
return;
AutoLocker<BClipboard> _(clipboard);
BMessage* clip = clipboard->Data();
if (clip == NULL)
return;
Copy(clipboard);
Clear();
}
void
FindTextView::Paste(BClipboard* clipboard)
{
if (clipboard == NULL)
return;
AutoLocker<BClipboard> _(clipboard);
BMessage* clip = clipboard->Data();
if (clip == NULL)
return;
const uint8* data;
ssize_t dataSize;
if (clip->FindData(B_FILE_MIME_TYPE, B_MIME_TYPE, (const void**)&data,
&dataSize) == B_OK) {
if (fMode == kHexMode) {
char* hex;
size_t hexSize;
if (_GetHexFromData(data, dataSize, &hex, &hexSize) < B_OK)
return;
SetText(hex, hexSize);
free(hex);
} else
SetText((char*)data, dataSize);
return;
}
BTextView::Paste(clipboard);
}
status_t status_t
FindTextView::GetHexFromData(const uint8 *in, size_t inSize, char **_hex, size_t *_hexSize) FindTextView::_GetHexFromData(const uint8* in, size_t inSize, char** _hex,
size_t* _hexSize)
{ {
char* hex = (char*)malloc(inSize * 3 + 1); char* hex = (char*)malloc(inSize * 3 + 1);
if (hex == NULL) if (hex == NULL)
@@ -237,7 +363,8 @@ FindTextView::GetHexFromData(const uint8 *in, size_t inSize, char **_hex, size_t
status_t status_t
FindTextView::GetDataFromHex(const char *text, size_t textLength, uint8 **_data, size_t *_dataSize) FindTextView::_GetDataFromHex(const char* text, size_t textLength, uint8** _data,
size_t* _dataSize)
{ {
uint8* data = (uint8*)malloc(textLength); uint8* data = (uint8*)malloc(textLength);
if (data == NULL) if (data == NULL)
@@ -285,7 +412,8 @@ FindTextView::SetMode(find_mode mode)
char* hex; char* hex;
size_t hexSize; size_t hexSize;
if (GetHexFromData((const uint8 *)Text(), TextLength(), &hex, &hexSize) < B_OK) if (_GetHexFromData((const uint8*)Text(), TextLength(), &hex, &hexSize)
< B_OK)
return B_NO_MEMORY; return B_NO_MEMORY;
fMode = mode; fMode = mode;
@@ -297,7 +425,7 @@ FindTextView::SetMode(find_mode mode)
uint8* data; uint8* data;
size_t dataSize; size_t dataSize;
if (GetDataFromHex(Text(), TextLength(), &data, &dataSize) < B_OK) if (_GetDataFromHex(Text(), TextLength(), &data, &dataSize) < B_OK)
return B_NO_MEMORY; return B_NO_MEMORY;
fMode = mode; fMode = mode;
@@ -315,13 +443,14 @@ FindTextView::SetData(BMessage &message)
{ {
const uint8* data; const uint8* data;
ssize_t dataSize; ssize_t dataSize;
if (message.FindData("data", B_RAW_TYPE, (const void **)&data, &dataSize) != B_OK) if (message.FindData("data", B_RAW_TYPE,
(const void**)&data, &dataSize) != B_OK)
return; return;
if (fMode == kHexMode) { if (fMode == kHexMode) {
char* hex; char* hex;
size_t hexSize; size_t hexSize;
if (GetHexFromData(data, dataSize, &hex, &hexSize) < B_OK) if (_GetHexFromData(data, dataSize, &hex, &hexSize) < B_OK)
return; return;
SetText(hex, hexSize); SetText(hex, hexSize);
@@ -338,7 +467,7 @@ FindTextView::GetData(BMessage &message)
// convert hex-text to real data // convert hex-text to real data
uint8* data; uint8* data;
size_t dataSize; size_t dataSize;
if (GetDataFromHex(Text(), TextLength(), &data, &dataSize) != B_OK) if (_GetDataFromHex(Text(), TextLength(), &data, &dataSize) != B_OK)
return; return;
message.AddData("data", B_RAW_TYPE, data, dataSize); message.AddData("data", B_RAW_TYPE, data, dataSize);
@@ -369,11 +498,13 @@ FindWindow::FindWindow(BRect _rect, BMessage &previous, BMessenger &target,
fMenu = new BPopUpMenu("mode"); fMenu = new BPopUpMenu("mode");
BMessage* message; BMessage* message;
BMenuItem* item; BMenuItem* item;
fMenu->AddItem(item = new BMenuItem("Text", message = new BMessage(kMsgFindMode))); fMenu->AddItem(item = new BMenuItem("Text",
message = new BMessage(kMsgFindMode)));
message->AddInt8("mode", kAsciiMode); message->AddInt8("mode", kAsciiMode);
if (mode == kAsciiMode) if (mode == kAsciiMode)
item->SetMarked(true); item->SetMarked(true);
fMenu->AddItem(item = new BMenuItem("Hexadecimal", message = new BMessage(kMsgFindMode))); fMenu->AddItem(item = new BMenuItem("Hexadecimal",
message = new BMessage(kMsgFindMode)));
message->AddInt8("mode", kHexMode); message->AddInt8("mode", kHexMode);
if (mode == kHexMode) if (mode == kHexMode)
item->SetMarked(true); item->SetMarked(true);
@@ -387,8 +518,8 @@ FindWindow::FindWindow(BRect _rect, BMessage &previous, BMessenger &target,
// add the bottom widgets // add the bottom widgets
BButton *button = new BButton(rect, B_EMPTY_STRING, "Find", new BMessage(kMsgStartFind), BButton* button = new BButton(rect, B_EMPTY_STRING, "Find",
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); new BMessage(kMsgStartFind), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
button->MakeDefault(true); button->MakeDefault(true);
button->ResizeToPreferred(); button->ResizeToPreferred();
button->MoveTo(rect.right - button->Bounds().Width(), button->MoveTo(rect.right - button->Bounds().Width(),
@@ -401,7 +532,8 @@ FindWindow::FindWindow(BRect _rect, BMessage &previous, BMessenger &target,
fCaseCheckBox->MoveTo(5, button->Frame().top); fCaseCheckBox->MoveTo(5, button->Frame().top);
bool caseSensitive; bool caseSensitive;
if (previous.FindBool("case_sensitive", &caseSensitive) != B_OK) { if (previous.FindBool("case_sensitive", &caseSensitive) != B_OK) {
if (settings == NULL || settings->FindBool("case_sensitive", &caseSensitive) != B_OK) if (settings == NULL
|| settings->FindBool("case_sensitive", &caseSensitive) != B_OK)
caseSensitive = true; caseSensitive = true;
} }
fCaseCheckBox->SetValue(caseSensitive); fCaseCheckBox->SetValue(caseSensitive);
@@ -413,19 +545,19 @@ FindWindow::FindWindow(BRect _rect, BMessage &previous, BMessenger &target,
rect.bottom = fCaseCheckBox->Frame().top - 8; rect.bottom = fCaseCheckBox->Frame().top - 8;
rect.InsetBy(2, 2); rect.InsetBy(2, 2);
fTextView = new FindTextView(rect, B_EMPTY_STRING, fTextView = new FindTextView(rect, B_EMPTY_STRING,
rect.OffsetToCopy(B_ORIGIN).InsetByCopy(3, 3), rect.OffsetToCopy(B_ORIGIN).InsetByCopy(3, 3), B_FOLLOW_ALL);
B_FOLLOW_ALL);
fTextView->SetWordWrap(true); fTextView->SetWordWrap(true);
fTextView->SetMode((find_mode)mode); fTextView->SetMode((find_mode)mode);
fTextView->SetData(previous); fTextView->SetData(previous);
BScrollView *scrollView = new BScrollView("scroller", fTextView, B_FOLLOW_ALL, B_WILL_DRAW, false, false); BScrollView* scrollView = new BScrollView("scroller", fTextView,
B_FOLLOW_ALL, B_WILL_DRAW, false, false);
view->AddChild(scrollView); view->AddChild(scrollView);
ResizeTo(290, button->Frame().Height() * 3 + 30); ResizeTo(290, button->Frame().Height() * 3 + 30);
SetSizeLimits(fCaseCheckBox->Bounds().Width() + button->Bounds().Width() + 20, SetSizeLimits(fCaseCheckBox->Bounds().Width() + button->Bounds().Width()
32768, button->Frame().Height() * 3 + 10, 32768); + 20, 32768, button->Frame().Height() * 3 + 10, 32768);
} }