1

現時点では、NSLinkAttribute を持ついくつかの範囲を持つ NSAttributedString を保持するカスタム NSTextFieldCell を持つ NSTableView があります。Apple のTableViewLinks の例と Toomas Vather のHyperlinkTextFieldのコードを統合しようとしました。

-trackMouse 関数を次のように実装しました。

- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag {

BOOL result = YES;
NSUInteger hitTestResult = [self hitTestForEvent:theEvent inRect:cellFrame ofView:controlView];
if ((hitTestResult & NSCellHitContentArea) != 0) {
    result = [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:flag];
    theEvent = [NSApp currentEvent];
    hitTestResult = [self hitTestForEvent:theEvent inRect:cellFrame ofView:controlView];
    if ((hitTestResult & NSCellHitContentArea) != 0) {
        NSAttributedString* attrValue = [self.objectValues objectForKey:@"theAttributedString"];
        NSMutableAttributedString* attributedStringWithLinks = [[NSMutableAttributedString alloc] initWithAttributedString:attrValue];

        //HOW TO GET A RIGHT INDEX?
        NSTableView* myTableView = (NSTableView *)[self controlView];
        NSPoint eventPoint = [myTableView convertPoint:[theEvent locationInWindow] fromView:nil];
        NSInteger myRow = [myTableView rowAtPoint:eventPoint];
        NSRect myBetterViewRect = [myTableView rectOfRow:myRow];


        __block NSTextView* myTextView = [[NSTextView alloc] initWithFrame:myBetterViewRect];
        [myTextView.textStorage setAttributedString:attributedStringWithLinks];

        NSPoint localPoint = [myTextView convertPoint:eventPoint fromView:myTableView];
        NSUInteger index = [myTextView.layoutManager characterIndexForPoint:localPoint inTextContainer:myTextView.textContainer fractionOfDistanceBetweenInsertionPoints:NULL];

        if (index != NSNotFound)
        {
            NSMutableArray* myHyperlinkInfos = [[NSMutableArray alloc] init];
            NSRange stringRange = NSMakeRange(0, [attrValue length]);
            [attrValue enumerateAttribute:NSLinkAttributeName inRange:stringRange options:0 usingBlock:^(id value, NSRange range, BOOL* stop)
             {
                 if (value)
                 {
                     NSUInteger rectCount = 0;
                     NSRectArray rectArray = [myTextView.layoutManager rectArrayForCharacterRange:range withinSelectedCharacterRange:range inTextContainer:myTextView.textContainer rectCount:&rectCount];
                     for (NSUInteger i = 0; i < rectCount; i++)
                     {
                         [myHyperlinkInfos addObject:@{kHyperlinkInfoCharacterRangeKey : [NSValue valueWithRange:range], kHyperlinkInfoURLKey : value, kHyperlinkInfoRectKey : [NSValue valueWithRect:rectArray[i]]}];
                     }
                 }
             }];

            for (NSDictionary* info in myHyperlinkInfos)
            {
                NSRange range = [[info objectForKey:kHyperlinkInfoCharacterRangeKey] rangeValue];
                if (NSLocationInRange(index, range))
                {
                    NSURL* url = [NSURL URLWithString:[info objectForKey:kHyperlinkInfoURLKey]];
                    [[NSWorkspace sharedWorkspace] openURL:url];
                }
            }
        }
    }
}
return result;}

セル (nstextview の) テキストをクリックしたときの文字インデックスが収まらないように見えます。そのため、テキスト内に複数のリンクがある場合でも、通常は最後のリンクが開かれます。私の推測では、クリックされたセルの nsrect が得られないということです。もしそうなら、どうすれば適切な NSRect を取得できますか?

提案、コメント、コード片、またはより簡単な解決策 (ビューベースのテーブルビューへの切り替えが含まれる場合でも) を歓迎します。

ありがとう。

4

0 に答える 0