Try wrapping your changes in willChangeValueForKey: and didChangeValueForKey:.
I enclosed the modification between willChangeValueForKey and didChangeValueForKey for the key value bound to the text view – without result: no change, and no error.
Of course I controlled first that everything was OK by logging the property bound to the text view at this point of the code: the log displays the correct “string” of the text contents.
” ” ”
BTW, this unexpected particularity may be the solution to one of my future problems: I have to prevent temporary changes to the text (insertion of strings) to be recorded as permanent by the property. I thought I would have to delete every insertion made before quitting the text (hell) and I was looking to some of “stop watching changes for this key” method.
So I tried to insert raw text somewhere in the text, between two random character, and I saw that the property is not informed of the changes. Good point! But this adds some of uneasiness, too. Why are some changes recorded and others not?
Regards,
PS - With each passing week, my code is less Applescript and more Cocoa (with more Objective-C added). I suppose it’s good sign.
Read up on key-value observing.
Yes, I could read for hours, but I don’t find why a text changing by keyboard differs from setting its contents programmatically – is it that some events (mouse down, key down, and so on) are recorded and other not? Even so, your method to force the property to be notified should work.
but I don’t find why a text changing by keyboard differs from setting its contents programmatically – is it that some events (mouse down, key down, and so on) are recorded and other not?
No, it’s because some are changed via accessors, and some change ivars directly.
No, it’s because some are changed via accessors, and some change ivars directly
And how does the programmer knows it? From my point of view, I never “set” something to my editor: the text is installed by an array controller, and the bindings points to the current selection of this controller.
Until know, I didn’t set anything, and the properties were always updated when changes were made in the text: typing, drag-and-dropping, cutting and pasting, all was done “in background” by the NSTextView. So it’s the first time I try to set something directly – you mean, when ivars are set directly, there is no notifications?
replaceCharactersInRange_withAttributedString_ seems to be an accessor, why is the property not notified?
Hey, wait a minute: as I have two versions of the text, I switch between them doing so:
my gTextView's bind_toObject_withKeyPath_options_("attributedString", gCardController, "selection.cShortText", missing value)
Is it possible that this call does not automatically make selection.cShortText an observer of gTextView ?
So it’s the first time I try to set something directly – you mean, when ivars are set directly, there is no notifications?
Yes.
Ok Shane, I give up.
I admit that the couple willChangeValueForKey: and didChangeValueForKey: should force my property to be updated. Maybe the key is misspelled, and it is a syntax problem.
The textView (gTextView) is bound to the current NSMutDic item of a controller (gCardController). The key of the NSMutDic (the text to update) is cLongText. So what is the correct key?
gTextView’s willChangeValueForKey_(“gCardController.selection.cLongText”) ?
gTextView’s willChangeValueForKey_(“selection.cLongText”) ?
gTextView’s willChangeValueForKey_(“cLongText”) ?gCardController’s willChangeValueForKey_(“selection.cLongText”) ?
first item of gCardController’s selectedObjects()'s willChangeValueForKey_(“cLongText”) ?
or what else?
Sorry, but I think I give up too. Every time I think I know what you’re doing here, you confuse me
No problem, Shane, I often confuse myself.
I’ll think about this problem and come back when I’ll be able to express it clearly.
I wrote a simple AppleScript to make NSAttributedString with NSTextAttachment.
The attached image is NSImageNameComputer and appended upside down.
Is there any mistake?
--
-- Created by: Takaaki Naganoya
-- Created on: 2020/07/22
--
-- Copyright © 2020 Piyomaru Software, All Rights Reserved
--
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions
set anAttachment to current application's NSTextAttachment's alloc()'s init()
anAttachment's setImage:(current application's NSImage's imageNamed:(current application's NSImageNameComputer))
anAttachment's setBounds:(current application's NSMakeRect(0, 0, 36, 36))
set img1Str to current application's NSAttributedString's attributedStringWithAttachment:anAttachment
set anAssrStr to makeRTFfromParameters("Piyomaru Software", 24) of me
img1Str's appendAttributedString:anAssrStr
img1Str
on makeRTFfromParameters(aStr as string, aFontSize as real)
set aVal1 to current application's NSFont's fontWithName:"Helvetica" |size|:aFontSize
set aKey1 to (current application's NSFontAttributeName)
set aVal2 to current application's NSColor's blackColor()
set aKey2 to (current application's NSForegroundColorAttributeName)
set aVal3 to 0
set akey3 to (current application's NSKernAttributeName)
set keyList to {aKey1, aKey2, akey3}
set valList to {aVal1, aVal2, aVal3}
set attrsDictionary to current application's NSMutableDictionary's dictionaryWithObjects:valList forKeys:keyList
set attrStr to current application's NSMutableAttributedString's alloc()'s initWithString:aStr attributes:attrsDictionary
return attrStr
end makeRTFfromParameters
Your code produces an image the right way up here. Where are you viewing the result?
This is the result image.
Foce flip processing version is here.
Saving computer image returns appropriate results.
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
--Get Computer Icon
set anImage to current application's NSImage's imageNamed:(current application's NSImageNameComputer)
set aDesktopPath to (current application's NSProcessInfo's processInfo()'s environment()'s objectForKey:("HOME"))'s stringByAppendingString:"/Desktop/"
set savePath to aDesktopPath's stringByAppendingString:((current application's NSUUID's UUID()'s UUIDString())'s stringByAppendingString:".png")
set fRes to saveNSImageAtPathAsPNG(anImage, savePath) of me
on saveNSImageAtPathAsPNG(anImage, outPath)
set imageRep to anImage's TIFFRepresentation()
set aRawimg to current application's NSBitmapImageRep's imageRepWithData:imageRep
set pathString to current application's NSString's stringWithString:outPath
set newPath to pathString's stringByExpandingTildeInPath()
set myNewImageData to (aRawimg's representationUsingType:(current application's NSPNGFileType) |properties|:(missing value))
set aRes to (myNewImageData's writeToFile:newPath atomically:true) as boolean
return aRes
end saveNSImageAtPathAsPNG
Your code produces an image the right way up here. Where are you viewing the result?
macOS 10.13: Upside Down
macOS 10.14: Upside Down
macOS 10.15: Normal
macOS 10.16: Normal
Hmm…
Looks like there’s been a change in view flipping.
https://stackoverflow.com/questions/49649553/the-image-of-nstextattachment-is-flipped
Assign the image to an NSTextAttachmentCell, not the NSTextAttachment.
This post solved.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions
use tvLib : script "tvLib"
set aCell to current application's NSTextAttachmentCell's alloc()'s initImageCell:(current application's NSImage's imageNamed:(current application's NSImageNameComputer))
set anAttachment to current application's NSTextAttachment's alloc()'s initWithData:(missing value) ofType:(missing value)
anAttachment's setAttachmentCell:aCell
anAttachment's setBounds:(current application's NSMakeRect(0, 0, 36, 36))
set img1Str to current application's NSAttributedString's attributedStringWithAttachment:anAttachment
set anAssrStr to makeRTFfromParameters("Piyomaru Software", 24) of me
img1Str's appendAttributedString:anAssrStr
dispAttrStr("Main message", "Sub message", img1Str, 400, 80) of tvLib
on makeRTFfromParameters(aStr as string, aFontSize as real)
set aVal1 to current application's NSFont's fontWithName:"Helvetica" |size|:aFontSize
set aKey1 to (current application's NSFontAttributeName)
set aVal2 to current application's NSColor's blackColor()
set aKey2 to (current application's NSForegroundColorAttributeName)
set aVal3 to 0
set akey3 to (current application's NSKernAttributeName)
set keyList to {aKey1, aKey2, akey3}
set valList to {aVal1, aVal2, aVal3}
set attrsDictionary to current application's NSMutableDictionary's dictionaryWithObjects:valList forKeys:keyList
set attrStr to current application's NSMutableAttributedString's alloc()'s initWithString:aStr attributes:attrsDictionary
return attrStr
end makeRTFfromParameters
What happens if you use your original code, but change this:
anAttachment's setImage:(current application's NSImage's imageNamed:(current application's NSImageNameComputer))
to this:
anAttachment's attachmentCell()'s setImage:(current application's NSImage's imageNamed:(current application's NSImageNameComputer))
Like this?
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions
use tvLib : script "tvLib"
set anImage to (current application's NSImage's imageNamed:(current application's NSImageNameComputer))
set anAttachment to current application's NSTextAttachment's alloc()'s init()
anAttachment's attachmentCell()'s setImage:anImage
anAttachment's setBounds:(current application's NSMakeRect(0, 0, 32, 32))
set img1Str to current application's NSAttributedString's attributedStringWithAttachment:anAttachment
set anAssrStr to makeRTFfromParameters("Piyomaru Software", 32, "Times") of me
img1Str's appendAttributedString:anAssrStr
dispAttrStr("Main message", "Sub message", img1Str, 400, 80) of tvLib
on makeRTFfromParameters(aStr as string, aFontSize as real, aFontName as string)
set aVal1 to current application's NSFont's fontWithName:aFontName |size|:aFontSize
set aKey1 to (current application's NSFontAttributeName)
set aVal2 to current application's NSColor's blackColor()
set aKey2 to (current application's NSForegroundColorAttributeName)
set aVal3 to 0
set akey3 to (current application's NSKernAttributeName)
set keyList to {aKey1, aKey2, akey3}
set valList to {aVal1, aVal2, aVal3}
set attrsDictionary to current application's NSMutableDictionary's dictionaryWithObjects:valList forKeys:keyList
set attrStr to current application's NSMutableAttributedString's alloc()'s initWithString:aStr attributes:attrsDictionary
return attrStr
end makeRTFfromParameters
Like this?
Yes. An attachment should already have a cell, so you shouldn’t need to make another one.