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:
Philippe Saint-Pierre
2009-08-14 22:44:44 +00:00
parent 47eb033980
commit 498c03bdd6
4 changed files with 91 additions and 23 deletions
+5 -4
View File
@@ -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;
} }
+3 -2
View File
@@ -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();
+82 -16
View File
@@ -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
} }
+1 -1
View File
@@ -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: