Change selection's font programmatically?

  • Hi,

      I'm trying to write code that does the same as clicking a font name
    in the font panel. I.e. I want it to apply a font - whose family name
    I have - to the selection, without changing any sizes, styles etc.
    After messing a while with NSFontManager and NSFontPanel, this is the
    best I could come up with:

    -(void) doMyChangeFont: (NSString*)familyName
    {
    NSFontManager*  fm = [NSFontManager sharedFontManager];
    NSFont*        newFont = [fm convertFont:[fm selectedFont]
    toFamily: familyName];

    [[NSFontPanel sharedFontPanel] setPanelFont: newFont isMultiple: NO];
    [fm modifyFontViaPanel: self];
    }

    however, this code smashes the styles and only applies the first
    character's style to the entire range of text.

      I've also looked at NSText - which doesn't look very helpful either,
    and through the text system docs, but all this arcane stuff about
    conversion and all those messages going back and forth between the
    panel and various receivers is way over my head.

      Do any of you know an API that might be better? Has anyone done this
    yet? Can anyone give me a hint where to look, and if it's in the text
    system docs, a general overview of how the weird stuff in there works
    in plain English?
    --
    Cheers,
    M. Uli Kusterer
    ------------------------------------------------------------
            "The Witnesses of TeachText are everywhere..."
                        http://www.zathras.de
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Sep 1, 2004, at 5:35 AM, M. Uli Kusterer wrote:

    > I've also looked at NSText - which doesn't look very helpful either,
    > and through the text system docs, but all this arcane stuff about
    > conversion and all those messages going back and forth between the
    > panel and various receivers is way over my head.

    It's really not that hard--call changeAttributes: on your text view,
    passing yourself as the sender.  You will receive a call to -
    (NSDictionary *)convertAttributes:(NSDictionary *)attributes for each
    attribute run in the selected text.  From the attribute dictionary you
    are passed, take the font attribute and apply your font manager
    convertFont: call to it.  Return a new dictionary that is the same as
    the old one, except that it has the converted font rather than the
    original one.  That's it.

    If you need to do this pre-10.3, it's not that much harder either.
    Call rangeForUserCharacterAttributeChange to get the range to change.
    Make sure that it's non-empty, and that
    shouldChangeTextInRange:replacementString:nil returns true.  Call
    beginEditing on the text storage, then iterate over the range by
    effective ranges, e.g. using attribute:NSFontAttributeName
    atIndex:longestEffectiveRange:&effectiveRange inRange:.  For each
    effective range, do the conversion as I described above.  When you're
    done, call endEditing on the text storage and didChangeText on the text
    view.  Then make the same font conversion on the typing attributes.

    Douglas Davidson
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • At 9:49 Uhr -0700 01.09.2004, Douglas Davidson wrote:
    > It's really not that hard--call changeAttributes: on your text view,
    > passing yourself as the sender.  You will receive a call to -
    > (NSDictionary *)convertAttributes:(NSDictionary *)attributes for
    > each attribute run in the selected text.  From the attribute
    > dictionary you are passed, take the font attribute and apply your
    > font manager convertFont: call to it.  Return a new dictionary that
    > is the same as the old one, except that it has the converted font
    > rather than the original one.  That's it.

      Do you mind if I include this in a bug report to Radar? This is much
    more comprehensible than anything I found in Apple's docs by far.
    Maybe a little graphic (flow diagram or whatever) would have helped
    there...

    > If you need to do this pre-10.3, it's not that much harder either.
    > Call rangeForUserCharacterAttributeChange to get the range to
    > change.  Make sure that it's non-empty, and that
    > shouldChangeTextInRange:replacementString:nil returns true.  Call
    > beginEditing on the text storage, then iterate over the range by
    > effective ranges, e.g. using attribute:NSFontAttributeName
    > atIndex:longestEffectiveRange:&effectiveRange inRange:.  For each
    > effective range, do the conversion as I described above.  When
    > you're done, call endEditing on the text storage and didChangeText
    > on the text view.  Then make the same font conversion on the typing
    > attributes.

    I think I can live with 10.3 only, but anyone browsing the archives
    will probably be very happy to find this here.

      Thanks a lot for this explanation, it helped me a great deal!
    --
    Cheers,
    M. Uli Kusterer
    ------------------------------------------------------------
            "The Witnesses of TeachText are everywhere..."
                        http://www.zathras.de
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Wed, 1 Sep 2004 19:50:25 +0200, "M. Uli Kusterer"
    <Witness.of.TeachText...> said:
    > At 9:49 Uhr -0700 01.09.2004, Douglas Davidson wrote:
    >> It's really not that hard--call changeAttributes: on your text view,
    >> passing yourself as the sender.  You will receive a call to -
    >> (NSDictionary *)convertAttributes:(NSDictionary *)attributes for
    >> each attribute run in the selected text.  From the attribute
    >> dictionary you are passed, take the font attribute and apply your
    >> font manager convertFont: call to it.  Return a new dictionary that
    >> is the same as the old one, except that it has the converted font
    >> rather than the original one.  That's it.
    >
    > Do you mind if I include this in a bug report to Radar?

    I hope you will. The docs do say that calling -[NSTextView
    changeAttributes:] causes the sender to be sent convertAttributes:, but they
    don't say that you're sent it for each style run or what to do when you get
    it. Things are not helped by the fact that convertAttributes: is documented
    only under NSFontManager; it should be documented as part of the explanation
    of -[NSTextView changeAttributes:]. Otherwise it is unclear that
    convertAttributes is something you can do in the first place; it seems like
    it's something that only the font manager does. m.

    --
    matt neuburg, phd = <matt...>, <http://www.tidbits.com/matt/>
    A fool + a tool + an autorelease pool = cool!
    AppleScript: the Definitive Guide
    <http://www.amazon.com/exec/obidos/ASIN/0596005571/somethingsbymatt>
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Sep 1, 2004, at 3:42 PM, Matt Neuburg wrote:

    > I hope you will. The docs do say that calling -[NSTextView
    > changeAttributes:] causes the sender to be sent convertAttributes:,
    > but they
    > don't say that you're sent it for each style run or what to do when
    > you get
    > it. Things are not helped by the fact that convertAttributes: is
    > documented
    > only under NSFontManager; it should be documented as part of the
    > explanation
    > of -[NSTextView changeAttributes:]. Otherwise it is unclear that
    > convertAttributes is something you can do in the first place; it seems
    > like
    > it's something that only the font manager does. m.

    The AppKit release notes for 10.3 contain essentially the same
    description of the changeAttributes:/convertAttributes: mechanism as
    the one I gave in my email--as they should, since I wrote that section
    of the release notes.  Bear in mind that the release notes are written
    by the engineers, and should be studied carefully.

    Douglas Davidson
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On or about 9/1/04 4:40 PM, thus spake "Douglas Davidson"
    <ddavidso...>:

    >
    > On Sep 1, 2004, at 3:42 PM, Matt Neuburg wrote:
    >
    >> I hope you will. The docs do say that calling -[NSTextView changeAttributes:]
    >> causes the sender to be sent convertAttributes:, but they don't say that
    >> you're sent it for each style run or what to do when you get it. Things are
    >> not helped by the fact that convertAttributes: is documented only under
    >> NSFontManager; it should be documented as part of the explanation of
    >> -[NSTextView changeAttributes:]. Otherwise it is unclear that
    >> convertAttributes is something you can do in the first place; it seems like
    >> it's something that only the font manager does. m.
    >
    > The AppKit release notes for 10.3 contain essentially the same
    > description of the changeAttributes:/convertAttributes: mechanism as
    > the one I gave in my email--as they should, since I wrote that section
    > of the release notes.  Bear in mind that the release notes are written
    > by the engineers, and should be studied carefully.

    Agreed. My note was not meant as a criticism but as a positive suggestion on
    how to improve the docs. I don't think it's wrong to propose that this
    information from the release notes be incorporated, a year later, into the
    reference docs. m.

    --
    matt neuburg, phd = <matt...>, http://www.tidbits.com/matt/
    pantes anthropoi tou eidenai oregontai phusei
    AppleScript: the Definitive Guide! NOW SHIPPING...! (Finally.)
    http://www.amazon.com/exec/obidos/ASIN/0596005571/somethingsbymatt
    Subscribe to TidBITS! It's free and smart. http://www.tidbits.com/
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.