Truncate beginning of label - cocoa

I have a label (NSTextField) with text aligned right. When the text becomes too large to display, the end of the text is truncated (at the right edge of the label). In my case I would actually want to truncate the beginning of the text. How can I achieve this in the Interface Builder or in code?
Now
| This sentence is to |
Desired
| entence is too long |

I'm not quite sure if this works for NSTextFields, I know it does for UILabels, but have you tried :
myTextField.lineBreakMode = NSLineBreakMode.ByTruncatingHead

What you're looking for is
[[myTextField cell] setLineBreakMode: NSLineBreakByTruncatingHead];
Swift:
myTextField.cell.lineBreakMode = NSLineBreakMode.ByTruncatingHead

Related

How do I limit NSTextView to 2 lines?

I'm trying to specify the number of lines for NSTextView. My designer is requesting 2 lines of text max. I've tried NSMutableParagraph style to add the ellipses truncation that I want, but with NSMutableParagraph I can only get NSTextView with 1 line and without NSMutableParagraph, I get a scrolling text with as many lines as needed to complete text.
var attributedString = NSMutableAttributedString(string: "This is my text, I can keep going for many characters")
var para = NSMutableParagraphStyle()
para.lineBreakMode = NSLineBreakMode.ByTruncatingTail
let globalAttributes = [
NSParagraphStyleAttributeName: para
]
let range = NSRange(location:0, length: attributedString.length)
attributedString.addAttributes(globalAttributes, range: range)
cellView.myTextView!.textStorage?.setAttributedString(attributedString)
I've tried height constraint on NSTextView. I've tried:
cellView.myTextView!.textContainer?.containerSize = NSMakeSize(300, 32)
I've tried creating IBOutlet for NSScrollView that NSTextView in within and adjusting its height. No luck with getting both 2 lines and truncation. Any help is greatly appreciated. I feel like I'm just missing a method or setup. Thanks!
From 10.11 you can use this
yourTextViewObj.textContainer.maximumNumberOfLines = 2;
You can use an NSTextField configured as a multi-line label. That means setting its cell's wraps property to true and, if desired, its truncatesLastVisibleLine to true.
For NSTextField (aka label) You can just do self.textField.maximumNumberOfLines = 2;
That's it.
Max number of lines is now a property of NSTextField
label.maximumNumberOfLines = 1;

How do I get the line of text under the cursor in a TextView in gtk#?

I have a GTK# TextView and I want to read the line of text under the cursor. I don't see a single method that will do that, so I think I need to combine several method calls, like Buffer.GetText, Buffer.GetIterAtOffset, Buffer.CursorPosition, but it's not obvious to me what the right combination is.
TextIter are a bit odd to use. Buffer.CursorPosition gives you the current position.
It's easy to find the end of the line:
var end = Buffer.CursorPosition;
end.ForwardToLineEnd();
To get the first character, there's not symetrical method, so you might try:
var start = Buffer.CursorPosition;
start.BackwardChars(start.LineOffset); // LineOffset gives you the iter offset on the current line.

ZPL - zebra: print justified text block without overwriting last line

I'm using the following command to print a justified text:
^FB1800,3,0,J^FT100,200^A0B,26,26^FH\^FDLONG TEXT TO BE PRINTED, WHICH DOESNT FIT IN ONLY 3 LINES...^FS
The command ^FB1800,3,0,J prints a field block in a width of 1800 dots, maximum 3 lines, justified.
The problem is that if the text exceeds the maximum number of lines, it overwrites the last line! :( That of course makes the text of the last line unreadable.
How can I avoid that? Does anybody know if is there a way to cut the exceeding text?
The documentation says exactly that this happens:
Text exceeding the maximum number of lines overwrites the last line. Changing the font size automatically increases or decreases the size of the block.
For reference: I'm using printer Zebra 220Xi4.
Any help would be appreciated. Thank you!
Take a look at the ^TB command. It is preferred over the ^FB command and truncates if the text exceeds the size defined in the TB params
I had just about the same problem, what fixed it in my case - although not the most elegant way - is to specify a higher number of maximum lines, and then formatting it in a way that only the first 3 are in the visible area.
In your case it would be for example ^FB1800,7,0,J instead of ^FB1800,3,0,J
This at least fixed it for me right away, because I print this text at the bottom of the label. If you need to have it somewhere in the middle or top, there might be some tricks with putting a (white) box on top of the overflow-area, since the Zebra printers seem to render before printing. Hope it helps.
Depending on the higher-level programming language you're using (assuming that you are), you could accomplish the same thing (truncate the text to be printed to a specified number of characters) with code like this (C# shown here):
public void PrintLabel(string price, string description, string barcode)
{
const int MAX_CAPS_DESC_LEN = 21;
const int MAX_LOWERCASE_DESC_LEN = 32;
try
{
bool descAllUpper = HHSUtils.IsAllUpper(description);
if (descAllUpper)
{
if (description.Length > MAX_CAPS_DESC_LEN)
{
description = description.Substring(0, MAX_CAPS_DESC_LEN);
}
}
else // not all upper
{
if (description.Length > MAX_LOWERCASE_DESC_LEN)
{
description = description.Substring(0, MAX_LOWERCASE_DESC_LEN);
}
}
. . .
This is what I'm using; is there any reason to prefer the "raw" ^TB command over this?

Algorithm help: Fit a text blurb to its textbox by length

I have a rather unusual problem, and it is hurting my brain.
Problem: Given a textbox of known length, and the text that will go inside it, make the text "fit" by truncating it with room for "..." to fit inside the box. (Context : This is for ASP.NET C#, but I think the algorithm is language agnostic.)
Example : [_________]
Text : The big brown dog jumped over the red fence.
Solution :[The bi...]
Example : [_________]
Text : Ferret
Solution :[Ferret___]
Given:
// Returns the number of px (as an int) that the arg text is in length
public int textLength(String theText, float emSize)
Question: What is the simplest and fastest way to do this?
I am afraid to do it by hacking off one character at a time, adding "..." and then checking the length because some of the strings to fit are veeeeery long.
You could do a binary search on the correct length instead, which means you only have to try log(n) sizes.
Oh, also if the text is monospaced (every character is given the width of an em) then it's pretty easy to figure this out programatically:
if str.length * emWidth < textBoxWidth
tb.text = str
else
tb.text = substring(str, 0, round_down(textBoxWidth / emWidth) - 3) + "..."
Why start from end? Start from the beginning and add letters (and ...) until it no longer fits. :)

Why does -[NSTextStorage replaceCharactersInRange: withAttributedString:] sometimes, sometimes not honor fonts in other character sets?

I'm trying to diagnose a problem in UKSyntaxColoredTextDocument 0.4 http://www.zathras.de/angelweb/blog-uksctd-oh-four.htm where text that actually lives in a different font than the one you have specified disappears as you type. (You can download and try out this cool utility to see this problem for yourself...)
Here's the background: This is some syntax coloring code that recolors as you type. It works great, but if you enter some characters that are not a part of the font set for that text view (e.g. Monaco, Helvetica) ... for instance, a symbol character or something in Japanese, which actually uses fonts like ZapfDingbatsITC or HiraKakuProN-W3 to display it, then those characters are not displayed as you type.
Let's say you have some text like this: fdsafd[☀]sfds‡[☀☀☀][日本語]...
If you paste that into the text field, and switch among syntax coloring from the popup, this invokes oldRecolorRange:, with this line:
[[textView textStorage] replaceCharactersInRange: range withAttributedString: vString];
Here, things behave as I would expect. The ASCII text, the symbols, and the Japanese text are all visible. The value of [textView textStorage] starts out, and ends up, something like this: (This is output of gdb; it's not showing the unicode characters, don't worry about that.)
df{
NSFont = "LucidaGrande 20.00 pt. P [] (0x001a3380) fobj=0x001a4970, spc=6.33";
}?{
NSFont = "ZapfDingbatsITC 20.00 pt. P [] (0x001ae720) fobj=0x001bb370, spc=5.56";
}fdsafd[{
NSFont = "LucidaGrande 20.00 pt. P [] (0x001a3380) fobj=0x001a4970, spc=6.33";
}?{
NSFont = "HiraKakuProN-W3 20.00 pt. P [] (0x001b59e0) fobj=0x001bb600, spc=6.66";
}]sfds[{
...
... even after setting the new value to be
dffdsafd[?]sfds[???][???] Nihddfdfffdfdd{
NSFont = "LucidaGrande 20.00 pt. P [] (0x001a3380) fobj=0x001a4970, spc=6.33";
}
In other words, the "foreign" fonts needed to display this string are preserved automatically somehow, even though the fonts are not specified in the replacement string.
However, when you type in one character at a time, a different call of replaceCharactersInRange:withAttributedString: in the method recolorRange: results in an attributed string that is only in the base font -- no foreign-character fonts have been added for us, so the characters out of the range of the main font are not visible at all!
dffdsafd[?]sfds[???][???] Nihddfdfffdfddx{
NSFont = "LucidaGrande 20.00 pt. P [] (0x001a3380) fobj=0x001a4970, spc=6.33";
}
Any idea why this method would be working one way in one circumstance and not in another? Is there some kind of switch that I can pass to give the NSTextStorage/NSAttributedString a hint that we want the text to display foreign characters?
Try [[textView textStorage] fixFontAttributeInRange:range]; after the [[textView textStorage] replaceCharactersInRange: range withAttributedString: vString] in recolorRange:
I think the problem is editing the text storage again in response to processEditing, which is already the tail end of an edit. -[NSTextStorage processEditing] uses fixFontAttributeInRange:, but since you're trying to edit again, something is going wrong and the fix behavior is being dropped.
When you do it for the whole document, there is a normal beginEditing/endEditing/processEditing sequence which causes fixFontAttributeInRange: to be called happily.

Resources