Some more work on the undo buffer. Added a quick and dirty implementation of WidthBuffer (it's needed by OpenTracker). We'll want to implement it correctly.
Multi-byte character insertion/deletion works now in TextView (thanks to Marc Flerackers) git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5135 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -23,6 +23,8 @@
|
|||||||
// Author: Marc Flerackers ([email protected])
|
// Author: Marc Flerackers ([email protected])
|
||||||
// Description: Text storage used by BTextView
|
// Description: Text storage used by BTextView
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
#ifndef __TEXTGAPBUFFER_H
|
||||||
|
#define __TEXTGAPBUFFER_H
|
||||||
|
|
||||||
// Standard Includes -----------------------------------------------------------
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
|
||||||
@@ -92,6 +94,8 @@ _BTextGapBuffer_::operator[](long index) const
|
|||||||
{
|
{
|
||||||
return (index < fGapIndex) ? fBuffer[index] : fBuffer[index + fGapCount];
|
return (index < fGapIndex) ? fBuffer[index] : fBuffer[index + fGapCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif //__TEXTGAPBUFFER_H
|
||||||
/*
|
/*
|
||||||
* $Log $
|
* $Log $
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#include "StyleBuffer.h"
|
#include "StyleBuffer.h"
|
||||||
#include "TextGapBuffer.h"
|
#include "TextGapBuffer.h"
|
||||||
#include "UndoBuffer.h"
|
#include "UndoBuffer.h"
|
||||||
|
#include "WidthBuffer.h"
|
||||||
|
|
||||||
// Local Defines ---------------------------------------------------------------
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
|
||||||
@@ -141,9 +142,13 @@ prop_list[] =
|
|||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
sem_id BTextView::sWidthSem = B_BAD_SEM_ID; // Created/deleted by init/fini_interface_kit
|
|
||||||
|
// Initialized/finalized by init/fini_interface_kit ?
|
||||||
|
_BWidthBuffer_* BTextView::sWidths = NULL;
|
||||||
|
sem_id BTextView::sWidthSem = B_BAD_SEM_ID;
|
||||||
int32 BTextView::sWidthAtom = 0;
|
int32 BTextView::sWidthAtom = 0;
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
BTextView::BTextView(BRect frame, const char *name, BRect textRect,
|
BTextView::BTextView(BRect frame, const char *name, BRect textRect,
|
||||||
uint32 resizeMask, uint32 flags)
|
uint32 resizeMask, uint32 flags)
|
||||||
@@ -285,6 +290,7 @@ BTextView::~BTextView()
|
|||||||
delete fStyles;
|
delete fStyles;
|
||||||
delete fDisallowedChars;
|
delete fDisallowedChars;
|
||||||
delete fUndo;
|
delete fUndo;
|
||||||
|
delete fOffscreen;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
BArchivable *
|
BArchivable *
|
||||||
@@ -387,7 +393,8 @@ BTextView::MouseDown(BPoint where)
|
|||||||
BPoint loc;
|
BPoint loc;
|
||||||
ulong buttons;
|
ulong buttons;
|
||||||
GetMouse(&loc, &buttons);
|
GetMouse(&loc, &buttons);
|
||||||
// was the secondary button clicked?
|
// TODO: here we shouldn't check for B_SECONDARY_MOUSE_BUTTON,
|
||||||
|
// since dragging works also with the primary button.
|
||||||
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
||||||
// was the click within the selection range?
|
// was the click within the selection range?
|
||||||
if ((mouseOffset >= fSelStart) && (mouseOffset <= fSelEnd)) {
|
if ((mouseOffset >= fSelStart) && (mouseOffset <= fSelEnd)) {
|
||||||
@@ -559,6 +566,7 @@ BTextView::WindowActivated(bool state)
|
|||||||
void
|
void
|
||||||
BTextView::KeyDown(const char *bytes, int32 numBytes)
|
BTextView::KeyDown(const char *bytes, int32 numBytes)
|
||||||
{
|
{
|
||||||
|
//TODO: Remove this and move it to specific key handlers ?
|
||||||
if (!fEditable)
|
if (!fEditable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1072,7 +1080,7 @@ BTextView::Copy(BClipboard *clipboard)
|
|||||||
fSelEnd - fSelStart);
|
fSelEnd - fSelStart);
|
||||||
|
|
||||||
int32 size;
|
int32 size;
|
||||||
if (IsStylable()) {
|
if (fStylable) {
|
||||||
text_run_array *runArray = RunArray(fSelStart, fSelEnd, &size);
|
text_run_array *runArray = RunArray(fSelStart, fSelEnd, &size);
|
||||||
clip->AddData("application/x-vnd.Be-text_run_array", B_MIME_TYPE,
|
clip->AddData("application/x-vnd.Be-text_run_array", B_MIME_TYPE,
|
||||||
runArray, size);
|
runArray, size);
|
||||||
@@ -1099,7 +1107,7 @@ BTextView::Paste(BClipboard *clipboard)
|
|||||||
text_run_array *runArray = NULL;
|
text_run_array *runArray = NULL;
|
||||||
ssize_t runLen = 0;
|
ssize_t runLen = 0;
|
||||||
|
|
||||||
if (IsStylable())
|
if (fStylable)
|
||||||
clip->FindData("application/x-vnd.Be-text_run_array", B_MIME_TYPE,
|
clip->FindData("application/x-vnd.Be-text_run_array", B_MIME_TYPE,
|
||||||
(const void **)&runArray, &runLen);
|
(const void **)&runArray, &runLen);
|
||||||
|
|
||||||
@@ -1458,10 +1466,10 @@ BTextView::OffsetAt(BPoint point) const
|
|||||||
{
|
{
|
||||||
// should we even bother?
|
// should we even bother?
|
||||||
if (point.y >= fTextRect.bottom)
|
if (point.y >= fTextRect.bottom)
|
||||||
return (fText->Length());
|
return fText->Length();
|
||||||
else {
|
else {
|
||||||
if (point.y < fTextRect.top)
|
if (point.y < fTextRect.top)
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 lineNum = LineAt(point);
|
int32 lineNum = LineAt(point);
|
||||||
@@ -1942,7 +1950,8 @@ BTextView::SetAlignment(alignment flag)
|
|||||||
fAlignment = flag;
|
fAlignment = flag;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
alignment BTextView::Alignment() const
|
alignment
|
||||||
|
BTextView::Alignment() const
|
||||||
{
|
{
|
||||||
return fAlignment;
|
return fAlignment;
|
||||||
}
|
}
|
||||||
@@ -2004,6 +2013,8 @@ BTextView::DoesUndo() const
|
|||||||
void
|
void
|
||||||
BTextView::HideTyping(bool enabled)
|
BTextView::HideTyping(bool enabled)
|
||||||
{
|
{
|
||||||
|
//TODO: Implement ?
|
||||||
|
//fText->SetPasswordMode(enabled);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
@@ -2248,14 +2259,6 @@ BTextView::InitObject(BRect textRect, const BFont *initialFont,
|
|||||||
void
|
void
|
||||||
BTextView::HandleBackspace()
|
BTextView::HandleBackspace()
|
||||||
{
|
{
|
||||||
if (fSelStart == fSelEnd) {
|
|
||||||
if (fSelStart == 0)
|
|
||||||
return;
|
|
||||||
else
|
|
||||||
fSelStart--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Highlight(fSelStart, fSelEnd);
|
|
||||||
|
|
||||||
if (fUndo) {
|
if (fUndo) {
|
||||||
_BTypingUndoBuffer_ *undoBuffer = dynamic_cast<_BTypingUndoBuffer_ *>(fUndo);
|
_BTypingUndoBuffer_ *undoBuffer = dynamic_cast<_BTypingUndoBuffer_ *>(fUndo);
|
||||||
@@ -2266,6 +2269,14 @@ BTextView::HandleBackspace()
|
|||||||
undoBuffer->BackwardErase();
|
undoBuffer->BackwardErase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fSelStart == fSelEnd) {
|
||||||
|
if (fSelStart == 0)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
fSelStart = PreviousInitialByte(fSelStart);
|
||||||
|
} else
|
||||||
|
Highlight(fSelStart, fSelEnd);
|
||||||
|
|
||||||
DeleteText(fSelStart, fSelEnd);
|
DeleteText(fSelStart, fSelEnd);
|
||||||
fSelEnd = fSelStart;
|
fSelEnd = fSelStart;
|
||||||
|
|
||||||
@@ -2354,15 +2365,6 @@ BTextView::HandleArrowKey(uint32 inArrowKey)
|
|||||||
void
|
void
|
||||||
BTextView::HandleDelete()
|
BTextView::HandleDelete()
|
||||||
{
|
{
|
||||||
if (fSelStart == fSelEnd) {
|
|
||||||
if (fSelEnd == fText->Length())
|
|
||||||
return;
|
|
||||||
else
|
|
||||||
fSelEnd = NextInitialByte(fSelEnd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Highlight(fSelStart, fSelEnd);
|
|
||||||
|
|
||||||
if (fUndo) {
|
if (fUndo) {
|
||||||
_BTypingUndoBuffer_ *undoBuffer = dynamic_cast<_BTypingUndoBuffer_ *>(fUndo);
|
_BTypingUndoBuffer_ *undoBuffer = dynamic_cast<_BTypingUndoBuffer_ *>(fUndo);
|
||||||
if (!undoBuffer) {
|
if (!undoBuffer) {
|
||||||
@@ -2372,6 +2374,15 @@ BTextView::HandleDelete()
|
|||||||
undoBuffer->ForwardErase();
|
undoBuffer->ForwardErase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fSelStart == fSelEnd) {
|
||||||
|
if (fSelEnd == fText->Length())
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
fSelEnd = NextInitialByte(fSelEnd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Highlight(fSelStart, fSelEnd);
|
||||||
|
|
||||||
DeleteText(fSelStart, fSelEnd);
|
DeleteText(fSelStart, fSelEnd);
|
||||||
|
|
||||||
fSelEnd = fSelStart;
|
fSelEnd = fSelStart;
|
||||||
@@ -2404,8 +2415,6 @@ BTextView::HandlePageKey(uint32 inPageKey)
|
|||||||
void
|
void
|
||||||
BTextView::HandleAlphaKey(const char *bytes, int32 numBytes)
|
BTextView::HandleAlphaKey(const char *bytes, int32 numBytes)
|
||||||
{
|
{
|
||||||
bool refresh = fSelStart != fText->Length();
|
|
||||||
|
|
||||||
if (fUndo) {
|
if (fUndo) {
|
||||||
_BTypingUndoBuffer_ *undoBuffer = dynamic_cast<_BTypingUndoBuffer_ *>(fUndo);
|
_BTypingUndoBuffer_ *undoBuffer = dynamic_cast<_BTypingUndoBuffer_ *>(fUndo);
|
||||||
if (!undoBuffer) {
|
if (!undoBuffer) {
|
||||||
@@ -2415,6 +2424,8 @@ BTextView::HandleAlphaKey(const char *bytes, int32 numBytes)
|
|||||||
undoBuffer->InputCharacter(numBytes);
|
undoBuffer->InputCharacter(numBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool refresh = fSelStart != fText->Length();
|
||||||
|
|
||||||
if (fSelStart != fSelEnd) {
|
if (fSelStart != fSelEnd) {
|
||||||
Highlight(fSelStart, fSelEnd);
|
Highlight(fSelStart, fSelEnd);
|
||||||
DeleteText(fSelStart, fSelEnd);
|
DeleteText(fSelStart, fSelEnd);
|
||||||
@@ -2627,10 +2638,10 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent,
|
|||||||
offset = (offset < limit) ? offset + 1 : limit;
|
offset = (offset < limit) ? offset + 1 : limit;
|
||||||
|
|
||||||
// iterate through the style runs
|
// iterate through the style runs
|
||||||
int32 length = offset;
|
int32 length = offset;
|
||||||
int32 startOffset = fromOffset;
|
int32 startOffset = fromOffset;
|
||||||
int32 numChars;
|
int32 numChars;
|
||||||
while ((numChars = fStyles->Iterate(startOffset, length, NULL, NULL, &ascent, &descent) != 0)) {
|
while ((numChars = fStyles->Iterate(startOffset, length, NULL, NULL, &ascent, &descent)) != 0) {
|
||||||
*outAscent = (ascent > *outAscent) ? ascent : *outAscent;
|
*outAscent = (ascent > *outAscent) ? ascent : *outAscent;
|
||||||
*outDescent = (descent > *outDescent) ? descent : *outDescent;
|
*outDescent = (descent > *outDescent) ? descent : *outDescent;
|
||||||
|
|
||||||
@@ -2775,7 +2786,7 @@ BTextView::StyledWidth(int32 fromOffset, int32 length, float *outAscent,
|
|||||||
// iterate through the style runs
|
// iterate through the style runs
|
||||||
const BFont *font = NULL;
|
const BFont *font = NULL;
|
||||||
int32 numChars;
|
int32 numChars;
|
||||||
while ((numChars = fStyles->Iterate(fromOffset, length, &font, NULL, &ascent, &descent) != 0)) {
|
while ((numChars = fStyles->Iterate(fromOffset, length, &font, NULL, &ascent, &descent)) != 0) {
|
||||||
maxAscent = (ascent > maxAscent) ? ascent : maxAscent;
|
maxAscent = (ascent > maxAscent) ? ascent : maxAscent;
|
||||||
maxDescent = (descent > maxDescent) ? descent : maxDescent;
|
maxDescent = (descent > maxDescent) ? descent : maxDescent;
|
||||||
|
|
||||||
@@ -2884,7 +2895,7 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset,
|
|||||||
const BFont *font = NULL;
|
const BFont *font = NULL;
|
||||||
const rgb_color *color = NULL;
|
const rgb_color *color = NULL;
|
||||||
int32 numChars;
|
int32 numChars;
|
||||||
while ((numChars = fStyles->Iterate(offset, length, &font, &color) != 0)) {
|
while ((numChars = fStyles->Iterate(offset, length, &font, &color)) != 0) {
|
||||||
SetFont(font);
|
SetFont(font);
|
||||||
SetHighColor(*color);
|
SetHighColor(*color);
|
||||||
|
|
||||||
@@ -3077,7 +3088,7 @@ BTextView::MessageDropped(BMessage *inMessage, BPoint where, BPoint offset)
|
|||||||
|
|
||||||
text_run_array *runArray = NULL;
|
text_run_array *runArray = NULL;
|
||||||
ssize_t runLen = 0;
|
ssize_t runLen = 0;
|
||||||
if (IsStylable())
|
if (fStylable)
|
||||||
inMessage->FindData("application/x-vnd.Be-text_run_array", B_MIME_TYPE,
|
inMessage->FindData("application/x-vnd.Be-text_run_array", B_MIME_TYPE,
|
||||||
(const void **)&runArray, &runLen);
|
(const void **)&runArray, &runLen);
|
||||||
|
|
||||||
|
|||||||
@@ -264,7 +264,8 @@ _BTypingUndoBuffer_::_BTypingUndoBuffer_(BTextView *textView)
|
|||||||
_BUndoBuffer_(textView, B_UNDO_TYPING),
|
_BUndoBuffer_(textView, B_UNDO_TYPING),
|
||||||
fTypedText(NULL),
|
fTypedText(NULL),
|
||||||
fTypedStart(fStart),
|
fTypedStart(fStart),
|
||||||
fNumBytes(0)
|
fTypedEnd(fEnd),
|
||||||
|
fUndone(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,14 +279,18 @@ _BTypingUndoBuffer_::~_BTypingUndoBuffer_()
|
|||||||
void
|
void
|
||||||
_BTypingUndoBuffer_::UndoSelf(BClipboard *clipboard)
|
_BTypingUndoBuffer_::UndoSelf(BClipboard *clipboard)
|
||||||
{
|
{
|
||||||
|
int32 len = fTypedEnd - fTypedStart;
|
||||||
|
|
||||||
free(fTypedText);
|
free(fTypedText);
|
||||||
fTypedText = (char *)malloc(fNumBytes);
|
fTypedText = NULL;
|
||||||
memcpy(fTypedText, fTextView->Text() + fTypedStart, fNumBytes);
|
fTypedText = (char *)malloc(len);
|
||||||
|
memcpy(fTypedText, fTextView->Text() + fTypedStart, len);
|
||||||
|
|
||||||
fTextView->Select(fTypedStart, fTypedStart);
|
fTextView->Select(fTypedStart, fTypedStart);
|
||||||
fTextView->Delete(fTypedStart, fTypedStart + fNumBytes);
|
fTextView->Delete(fTypedStart, fTypedEnd);
|
||||||
fTextView->Insert(fTextData, fTextLength);
|
fTextView->Insert(fTextData, fTextLength);
|
||||||
fTextView->Select(fStart, fEnd);
|
fTextView->Select(fStart, fEnd);
|
||||||
|
fUndone++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -294,7 +299,8 @@ _BTypingUndoBuffer_::RedoSelf(BClipboard *clipboard)
|
|||||||
{
|
{
|
||||||
fTextView->Select(fTypedStart, fTypedStart);
|
fTextView->Select(fTypedStart, fTypedStart);
|
||||||
fTextView->Delete(fTypedStart, fTypedStart + fTextLength);
|
fTextView->Delete(fTypedStart, fTypedStart + fTextLength);
|
||||||
fTextView->Insert(fTypedText, fNumBytes);
|
fTextView->Insert(fTypedText, fTypedEnd - fTypedStart);
|
||||||
|
fUndone--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -304,22 +310,22 @@ _BTypingUndoBuffer_::InputCharacter(int32 len)
|
|||||||
int32 start, end;
|
int32 start, end;
|
||||||
fTextView->GetSelection(&start, &end);
|
fTextView->GetSelection(&start, &end);
|
||||||
|
|
||||||
int32 currentPos = fTypedStart + fNumBytes;
|
if (start != fTypedEnd || end != fTypedEnd)
|
||||||
if (start != currentPos)
|
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
fNumBytes += len;
|
fTypedEnd += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_BTypingUndoBuffer_::Reset()
|
_BTypingUndoBuffer_::Reset()
|
||||||
{
|
{
|
||||||
|
printf("Reset\n");
|
||||||
free(fTextData);
|
free(fTextData);
|
||||||
fTextView->GetSelection(&fStart, &fEnd);
|
fTextView->GetSelection(&fStart, &fEnd);
|
||||||
fTextLength = fEnd - fStart;
|
fTextLength = fEnd - fStart;
|
||||||
fTypedStart = fStart;
|
fTypedStart = fStart;
|
||||||
fNumBytes = 0;
|
fTypedEnd = fStart;
|
||||||
|
|
||||||
fTextData = (char *)malloc(fTextLength);
|
fTextData = (char *)malloc(fTextLength);
|
||||||
memcpy(fTextData, fTextView->Text() + fStart, fTextLength);
|
memcpy(fTextData, fTextView->Text() + fStart, fTextLength);
|
||||||
@@ -327,36 +333,93 @@ _BTypingUndoBuffer_::Reset()
|
|||||||
free(fTypedText);
|
free(fTypedText);
|
||||||
fTypedText = NULL;
|
fTypedText = NULL;
|
||||||
fRedo = false;
|
fRedo = false;
|
||||||
|
fUndone = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
_BTypingUndoBuffer_::ForwardErase()
|
|
||||||
{
|
|
||||||
//TODO: Fix this. Currently, it just resets the
|
|
||||||
//undobuffer every time DELETE is pressed, while
|
|
||||||
//it should reset it just the first time it's pressed.
|
|
||||||
//Moreover, it doesn't work with multi-byte characters.
|
|
||||||
int32 start, end;
|
|
||||||
fTextView->GetSelection(&start, &end);
|
|
||||||
|
|
||||||
int32 currentPos = fTypedStart + fNumBytes;
|
// TODO: This isn't completely safe and it's even slower than parsing byte
|
||||||
if (start != currentPos)
|
// by byte, but I'll change it later.
|
||||||
Reset();
|
static inline int32
|
||||||
|
UTF8_char_len(uchar c)
|
||||||
|
{
|
||||||
|
return ((0xE5000000 >> ((c >> 3) & 0x1E)) & 3) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_BTypingUndoBuffer_::BackwardErase()
|
_BTypingUndoBuffer_::BackwardErase()
|
||||||
{
|
{
|
||||||
//TODO: Fix this. Currently, it just resets the
|
|
||||||
//undobuffer every time BACKSPACE is pressed, while
|
|
||||||
//it should reset it just the first time it's pressed.
|
|
||||||
//Moreover, it doesn't work with multi-byte characters.
|
|
||||||
int32 start, end;
|
int32 start, end;
|
||||||
fTextView->GetSelection(&start, &end);
|
fTextView->GetSelection(&start, &end);
|
||||||
|
|
||||||
int32 currentPos = fTypedStart + fNumBytes;
|
int32 charLen = UTF8_char_len(fTextView->ByteAt(start - 1));
|
||||||
if (start != currentPos)
|
printf("Char Len: %d\n", charLen);
|
||||||
|
|
||||||
|
if (start != fTypedEnd || end != fTypedEnd) {
|
||||||
Reset();
|
Reset();
|
||||||
|
// if we've got a selection, we're already done
|
||||||
|
if (start != end)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *buffer = (char *)malloc(fTextLength + charLen);
|
||||||
|
memcpy(buffer + charLen, fTextData, fTextLength);
|
||||||
|
|
||||||
|
fTypedStart = start - charLen;
|
||||||
|
start = fTypedStart;
|
||||||
|
for (int32 x = 0; x < charLen; x++)
|
||||||
|
buffer[x] = fTextView->ByteAt(start + x);
|
||||||
|
free(fTextData);
|
||||||
|
fTextData = buffer;
|
||||||
|
|
||||||
|
fTextLength += charLen;
|
||||||
|
fTypedEnd -= charLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_BTypingUndoBuffer_::ForwardErase()
|
||||||
|
{
|
||||||
|
int32 start, end;
|
||||||
|
|
||||||
|
fTextView->GetSelection(&start, &end);
|
||||||
|
|
||||||
|
int32 charLen = UTF8_char_len(fTextView->ByteAt(start));
|
||||||
|
printf("Char Len: %d\n", charLen);
|
||||||
|
|
||||||
|
if (start != fTypedEnd || end != fTypedEnd || fUndone > 0) {
|
||||||
|
Reset();
|
||||||
|
// if we've got a selection, we're already done
|
||||||
|
if (fStart == fEnd) {
|
||||||
|
free(fTextData);
|
||||||
|
fTextLength = charLen;
|
||||||
|
fTextData = (char *)malloc(fTextLength);
|
||||||
|
|
||||||
|
// store the erased character
|
||||||
|
for (int32 x = 0; x < charLen; x++)
|
||||||
|
fTextData[x] = fTextView->ByteAt(start + x);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Here we need to store the erased text, so we get the text that it's
|
||||||
|
// already in the buffer, and we add the erased character.
|
||||||
|
// a realloc + memmove would maybe be cleaner, but that way we spare a
|
||||||
|
// copy (malloc + memcpy vs realloc + memmove).
|
||||||
|
|
||||||
|
int32 newLength = fTextLength + charLen;
|
||||||
|
char *buffer = (char *)malloc(newLength);
|
||||||
|
|
||||||
|
// copy the already stored data
|
||||||
|
memcpy(buffer, fTextData, fTextLength);
|
||||||
|
|
||||||
|
if (fTextLength < newLength) {
|
||||||
|
// store the erased character
|
||||||
|
for (int32 x = 0; x < charLen; x++)
|
||||||
|
buffer[fTextLength] = fTextView->ByteAt(start + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
fTextLength = newLength;
|
||||||
|
free(fTextData);
|
||||||
|
fTextData = buffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -56,6 +56,7 @@ protected:
|
|||||||
|
|
||||||
bool fRedo;
|
bool fRedo;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
undo_state fState;
|
undo_state fState;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,7 +138,8 @@ private:
|
|||||||
|
|
||||||
char *fTypedText;
|
char *fTypedText;
|
||||||
int32 fTypedStart;
|
int32 fTypedStart;
|
||||||
int32 fNumBytes;
|
int32 fTypedEnd;
|
||||||
|
int32 fUndone;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__UNDOBUFFER_H
|
#endif //__UNDOBUFFER_H
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
// A quick and dirty implementation of _BWidthBuffer_, needed to compile
|
||||||
|
// OpenTracker. We'll want to implement it correctly.
|
||||||
|
|
||||||
|
#include <Font.h>
|
||||||
|
|
||||||
|
#include "WidthBuffer.h"
|
||||||
|
|
||||||
|
_BWidthBuffer_::_BWidthBuffer_()
|
||||||
|
{
|
||||||
|
//TODO: Implement
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_BWidthBuffer_::~_BWidthBuffer_()
|
||||||
|
{
|
||||||
|
//TODO: Implement
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
_BWidthBuffer_::StringWidth(const char *inText, int32 fromOffset, int32 length,
|
||||||
|
const BFont *inStyle)
|
||||||
|
{
|
||||||
|
// TODO: Should use local hashed items
|
||||||
|
return inStyle->StringWidth(inText + fromOffset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
_BWidthBuffer_::StringWidth(_BTextGapBuffer_ &inBuffer, int32 fromOffset, int32 length,
|
||||||
|
const BFont *inStyle)
|
||||||
|
{
|
||||||
|
return inStyle->StringWidth(inBuffer.Text() + fromOffset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
_BWidthBuffer_::FindTable(const BFont *inStyle, int32 *outIndex)
|
||||||
|
{
|
||||||
|
float fontSize = inStyle->Size();
|
||||||
|
int32 fontCode = inStyle->FamilyAndStyle();
|
||||||
|
|
||||||
|
for (int32 i = 0; i < fItemCount; i++) {
|
||||||
|
#if B_BEOS_VERSION_DANO
|
||||||
|
if (*inStyle == fBuffer[i].font) {
|
||||||
|
#else
|
||||||
|
if (fontSize == fBuffer[i].fontSize && fontCode == fBuffer[i].fontCode) {
|
||||||
|
#endif
|
||||||
|
*outIndex = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*outIndex = -1;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
_BWidthBuffer_::InsertTable(const BFont *font)
|
||||||
|
{
|
||||||
|
//TODO: Implement
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
_BWidthBuffer_::GetEscapement(uint32 code, int32 index, float *escapement)
|
||||||
|
{
|
||||||
|
//TODO: Implement
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
_BWidthBuffer_::Hash(uint32 val)
|
||||||
|
{
|
||||||
|
//TODO: Implement
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_BWidthBuffer_::HashEscapements(const char *inText, int32 numChars, int32,
|
||||||
|
int32, const BFont *inStyle)
|
||||||
|
{
|
||||||
|
//TODO: Implement
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#ifndef __WIDTHBUFFER_H
|
||||||
|
#define __WIDTHBUFFER_H
|
||||||
|
|
||||||
|
#include "TextGapBuffer.h"
|
||||||
|
#include "TextViewSupportBuffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct _width_table_ {
|
||||||
|
#if B_BEOS_VERSION_DANO
|
||||||
|
BFont font; // corresponding font
|
||||||
|
#else
|
||||||
|
int32 fontCode; // font code
|
||||||
|
float fontSize; // font size
|
||||||
|
#endif
|
||||||
|
int32 hashCount; // number of hashed items
|
||||||
|
int32 tableCount; // size of table
|
||||||
|
void *widths; // width table
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class _BWidthBuffer_ : public _BTextViewSupportBuffer_<_width_table_> {
|
||||||
|
public:
|
||||||
|
_BWidthBuffer_();
|
||||||
|
virtual ~_BWidthBuffer_();
|
||||||
|
|
||||||
|
float StringWidth(const char *inText, int32 fromOffset, int32 length,
|
||||||
|
const BFont *inStyle);
|
||||||
|
float StringWidth(_BTextGapBuffer_ &, int32 fromOffset, int32 length,
|
||||||
|
const BFont *inStyle);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool FindTable(const BFont *font, int32 *outIndex);
|
||||||
|
int32 InsertTable(const BFont *font);
|
||||||
|
|
||||||
|
bool GetEscapement(uint32, int32, float *);
|
||||||
|
void HashEscapements(const char *, int32, int32, int32, const BFont *);
|
||||||
|
|
||||||
|
uint32 Hash(uint32);
|
||||||
|
|
||||||
|
void CCheck();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __WIDTHBUFFER_H
|
||||||
Reference in New Issue
Block a user