StringEditor : The TextView wasn't sending messages saying its content was modified by the user.
Symptoms : * The Save menu item wasn't enabled * the undo/redo menu item weren't neither The fix I made was to commit the changes made by the user to the editor instance, by augmenting the InsertText and DeleteText from the TextView. This fixes ticket #3507. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32402 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -526,7 +526,7 @@ DataEditor::InitCheck()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DataEditor::AddChange(DataChange *change)
|
DataEditor::AddChange(DataChange *change, bool sendNotices)
|
||||||
{
|
{
|
||||||
if (change == NULL)
|
if (change == NULL)
|
||||||
return;
|
return;
|
||||||
@@ -537,7 +537,8 @@ DataEditor::AddChange(DataChange *change)
|
|||||||
RemoveRedos();
|
RemoveRedos();
|
||||||
change->Apply(fRealViewOffset, fView, fRealViewSize);
|
change->Apply(fRealViewOffset, fView, fRealViewSize);
|
||||||
|
|
||||||
SendNotices(change);
|
if (sendNotices)
|
||||||
|
SendNotices(change);
|
||||||
// update observers
|
// update observers
|
||||||
|
|
||||||
// try to join changes
|
// try to join changes
|
||||||
@@ -551,7 +552,7 @@ DataEditor::AddChange(DataChange *change)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DataEditor::Replace(off_t offset, const uint8 *data, size_t length)
|
DataEditor::Replace(off_t offset, const uint8 *data, size_t length, bool sendNotices)
|
||||||
{
|
{
|
||||||
if (IsReadOnly())
|
if (IsReadOnly())
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
@@ -570,7 +571,7 @@ DataEditor::Replace(off_t offset, const uint8 *data, size_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReplaceChange *change = new ReplaceChange(offset, data, length);
|
ReplaceChange *change = new ReplaceChange(offset, data, length);
|
||||||
AddChange(change);
|
AddChange(change, sendNotices);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ class DataEditor : public BLocker {
|
|||||||
|
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|
||||||
status_t Replace(off_t offset, const uint8 *data, size_t length);
|
status_t Replace(off_t offset, const uint8 *data, size_t length,
|
||||||
|
bool sendNotices = true);
|
||||||
status_t Remove(off_t offset, off_t length);
|
status_t Remove(off_t offset, off_t length);
|
||||||
status_t Insert(off_t offset, const uint8 *data, size_t length);
|
status_t Insert(off_t offset, const uint8 *data, size_t length);
|
||||||
|
|
||||||
@@ -94,7 +95,7 @@ class DataEditor : public BLocker {
|
|||||||
void SendNotices(uint32 what, BMessage *message = NULL);
|
void SendNotices(uint32 what, BMessage *message = NULL);
|
||||||
void SendNotices(DataChange *change);
|
void SendNotices(DataChange *change);
|
||||||
status_t Update();
|
status_t Update();
|
||||||
void AddChange(DataChange *change);
|
void AddChange(DataChange *change, bool sendNotices = true);
|
||||||
void ApplyChanges();
|
void ApplyChanges();
|
||||||
void RemoveRedos();
|
void RemoveRedos();
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,24 @@ static const uint32 kMsgScaleChanged = 'scch';
|
|||||||
static const uint32 kMimeTypeItem = 'miti';
|
static const uint32 kMimeTypeItem = 'miti';
|
||||||
|
|
||||||
|
|
||||||
|
class StringEditorTextView : public BTextView {
|
||||||
|
public:
|
||||||
|
StringEditorTextView(BRect rect, TypeEditorView* target);
|
||||||
|
|
||||||
|
bool fCommit;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void InsertText(const char* text,
|
||||||
|
int32 length, int32 offset,
|
||||||
|
const text_run_array* runs = NULL);
|
||||||
|
|
||||||
|
virtual void DeleteText(int32 start, int32 finish);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TypeEditorView* fTarget;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class StringEditor : public TypeEditorView {
|
class StringEditor : public TypeEditorView {
|
||||||
public:
|
public:
|
||||||
StringEditor(BRect rect, DataEditor& editor);
|
StringEditor(BRect rect, DataEditor& editor);
|
||||||
@@ -44,13 +62,13 @@ class StringEditor : public TypeEditorView {
|
|||||||
virtual void DetachedFromWindow();
|
virtual void DetachedFromWindow();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
virtual void CommitChanges();
|
virtual void CommitChanges(bool sendNotices = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _UpdateText();
|
void _UpdateText();
|
||||||
|
|
||||||
BTextView* fTextView;
|
StringEditorTextView* fTextView;
|
||||||
BString fPreviousText;
|
BString fPreviousText;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -62,7 +80,7 @@ class MimeTypeEditor : public TypeEditorView {
|
|||||||
virtual void DetachedFromWindow();
|
virtual void DetachedFromWindow();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
virtual void CommitChanges();
|
virtual void CommitChanges(bool sendNotices = true);
|
||||||
virtual bool TypeMatches();
|
virtual bool TypeMatches();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -81,7 +99,7 @@ class NumberEditor : public TypeEditorView {
|
|||||||
virtual void DetachedFromWindow();
|
virtual void DetachedFromWindow();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
virtual void CommitChanges();
|
virtual void CommitChanges(bool sendNotices = true);
|
||||||
virtual bool TypeMatches();
|
virtual bool TypeMatches();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -103,7 +121,7 @@ class BooleanEditor : public TypeEditorView {
|
|||||||
virtual void DetachedFromWindow();
|
virtual void DetachedFromWindow();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
virtual void CommitChanges();
|
virtual void CommitChanges(bool sendNotices = true);
|
||||||
virtual bool TypeMatches();
|
virtual bool TypeMatches();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -169,7 +187,7 @@ TypeEditorView::~TypeEditorView()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TypeEditorView::CommitChanges()
|
TypeEditorView::CommitChanges(bool sendNotices)
|
||||||
{
|
{
|
||||||
// the default just does nothing here
|
// the default just does nothing here
|
||||||
}
|
}
|
||||||
@@ -197,6 +215,7 @@ StringEditor::StringEditor(BRect rect, DataEditor& editor)
|
|||||||
|
|
||||||
BStringView *stringView = new BStringView(BRect(5, 5, rect.right, 20),
|
BStringView *stringView = new BStringView(BRect(5, 5, rect.right, 20),
|
||||||
B_EMPTY_STRING, "Contents:");
|
B_EMPTY_STRING, "Contents:");
|
||||||
|
|
||||||
stringView->ResizeToPreferred();
|
stringView->ResizeToPreferred();
|
||||||
AddChild(stringView);
|
AddChild(stringView);
|
||||||
|
|
||||||
@@ -205,9 +224,7 @@ StringEditor::StringEditor(BRect rect, DataEditor& editor)
|
|||||||
rect.right -= B_V_SCROLL_BAR_WIDTH;
|
rect.right -= B_V_SCROLL_BAR_WIDTH;
|
||||||
rect.bottom -= B_H_SCROLL_BAR_HEIGHT;
|
rect.bottom -= B_H_SCROLL_BAR_HEIGHT;
|
||||||
|
|
||||||
fTextView = new BTextView(rect, B_EMPTY_STRING,
|
fTextView = new StringEditorTextView(rect, this);
|
||||||
rect.OffsetToCopy(B_ORIGIN).InsetByCopy(5, 5),
|
|
||||||
B_FOLLOW_ALL, B_WILL_DRAW);
|
|
||||||
|
|
||||||
BScrollView* scrollView = new BScrollView("scroller", fTextView,
|
BScrollView* scrollView = new BScrollView("scroller", fTextView,
|
||||||
B_FOLLOW_ALL, B_WILL_DRAW, true, true);
|
B_FOLLOW_ALL, B_WILL_DRAW, true, true);
|
||||||
@@ -215,6 +232,43 @@ StringEditor::StringEditor(BRect rect, DataEditor& editor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fCommit is true if (Insert/Delete)Text is called from interaction with the user
|
||||||
|
* (text typed..)
|
||||||
|
* It's false if it's called from _UpdateText();
|
||||||
|
* This is to avoid a SetText feedback loop
|
||||||
|
* CommitChanges -> UpdateText -> SetText -> InsertText -> CommitChanges...
|
||||||
|
*/
|
||||||
|
StringEditorTextView::StringEditorTextView(BRect rect, TypeEditorView* target)
|
||||||
|
:
|
||||||
|
BTextView(rect, B_EMPTY_STRING,
|
||||||
|
rect.OffsetToCopy(B_ORIGIN).InsetByCopy(5, 5),
|
||||||
|
B_FOLLOW_ALL, B_WILL_DRAW),
|
||||||
|
fCommit(true),
|
||||||
|
fTarget(target)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StringEditorTextView::InsertText(const char* text,
|
||||||
|
int32 length, int32 offset, const text_run_array* runs)
|
||||||
|
{
|
||||||
|
BTextView::InsertText(text, length, offset, runs);
|
||||||
|
if (fCommit)
|
||||||
|
fTarget->CommitChanges(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StringEditorTextView::DeleteText(int32 start, int32 finish)
|
||||||
|
{
|
||||||
|
BTextView::DeleteText(start, finish);
|
||||||
|
if (fCommit)
|
||||||
|
fTarget->CommitChanges(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
StringEditor::_UpdateText()
|
StringEditor::_UpdateText()
|
||||||
{
|
{
|
||||||
@@ -227,7 +281,9 @@ StringEditor::_UpdateText()
|
|||||||
|
|
||||||
const char *buffer;
|
const char *buffer;
|
||||||
if (fEditor.GetViewBuffer((const uint8 **)&buffer) == B_OK) {
|
if (fEditor.GetViewBuffer((const uint8 **)&buffer) == B_OK) {
|
||||||
|
fTextView->fCommit = false;
|
||||||
fTextView->SetText(buffer);
|
fTextView->SetText(buffer);
|
||||||
|
fTextView->fCommit = true;
|
||||||
fPreviousText.SetTo(buffer);
|
fPreviousText.SetTo(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,11 +293,11 @@ StringEditor::_UpdateText()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
StringEditor::CommitChanges()
|
StringEditor::CommitChanges(bool sendNotices)
|
||||||
{
|
{
|
||||||
if (fPreviousText != fTextView->Text()) {
|
if (fPreviousText != fTextView->Text()) {
|
||||||
fEditor.Replace(0, (const uint8 *)fTextView->Text(),
|
fEditor.Replace(0, (const uint8 *)fTextView->Text(),
|
||||||
fTextView->TextLength() + 1);
|
fTextView->TextLength() + 1, sendNotices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +323,17 @@ StringEditor::DetachedFromWindow()
|
|||||||
void
|
void
|
||||||
StringEditor::MessageReceived(BMessage *message)
|
StringEditor::MessageReceived(BMessage *message)
|
||||||
{
|
{
|
||||||
BView::MessageReceived(message);
|
switch (message->what) {
|
||||||
|
case kMsgValueChanged:
|
||||||
|
CommitChanges();
|
||||||
|
break;
|
||||||
|
case kMsgDataEditorUpdate:
|
||||||
|
_UpdateText();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BView::MessageReceived(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -307,7 +373,7 @@ MimeTypeEditor::_UpdateText()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MimeTypeEditor::CommitChanges()
|
MimeTypeEditor::CommitChanges(bool sendNotices)
|
||||||
{
|
{
|
||||||
if (fPreviousText != fTextControl->Text()) {
|
if (fPreviousText != fTextControl->Text()) {
|
||||||
fEditor.Replace(0, (const uint8*)fTextControl->Text(),
|
fEditor.Replace(0, (const uint8*)fTextControl->Text(),
|
||||||
@@ -488,7 +554,7 @@ NumberEditor::TypeMatches()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
NumberEditor::CommitChanges()
|
NumberEditor::CommitChanges(bool sendNotices)
|
||||||
{
|
{
|
||||||
if (fPreviousText == fTextControl->Text())
|
if (fPreviousText == fTextControl->Text())
|
||||||
return;
|
return;
|
||||||
@@ -792,7 +858,7 @@ BooleanEditor::_UpdateMenuField()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BooleanEditor::CommitChanges()
|
BooleanEditor::CommitChanges(bool sendNotices)
|
||||||
{
|
{
|
||||||
// we're commiting the changes as they happen
|
// we're commiting the changes as they happen
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class TypeEditorView : public BView {
|
|||||||
uint32 flags, DataEditor& editor);
|
uint32 flags, DataEditor& editor);
|
||||||
~TypeEditorView();
|
~TypeEditorView();
|
||||||
|
|
||||||
virtual void CommitChanges();
|
virtual void CommitChanges(bool sendNotices = true);
|
||||||
virtual bool TypeMatches();
|
virtual bool TypeMatches();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
Reference in New Issue
Block a user