trim zeros from (substring of) nsString in xpcom - firefox

I'm trying to get trim leading zeros if any from a substring of a string containing alphanumeric such as ABC13, 09889, etc.
Here is the sample code i'm trying. Not sure about what type of string would fit for this purpose, hence using nsString.
nsString logicId;
// this is nice way to assing values to nsString, mozilla way.
logicId.Assign(NS_ConvertASCIItoUTF16((v)));// v is my value such as ABC786
if(logicId.Length() > 0)
{
nsAString& lastFive = Substring(logicId, 17, 5);
// lastFive is now a string representing the last 5 characters
// let's trim leading zeros.
lastFive.Trim("0", true, false);
plugin->mId.Assign(lastFive);
}
Since a substring is just a const pointer, you can't do a trim on it. So how do get a substring and still trim on it. Any suggestions?

i managed to do it as :
nsString logicId;
logicId.Assign(NS_ConvertASCIItoUTF16((v)));
/* mozilla style */
if(logicId.Length() > 0)
{
nsString lastFive(Substring(logicId, 17, 5));
//and then trim that
lastFive.Trim("0", true, false);
plugin->mId.Assign(lastFive);
//printf("%s\n", NS_ConvertUTF16toUTF8(lastFive).get());
}

Related

Make UITextField with VoiceOver read numbers as digits

Our App has a few UITextField where users enter alphanumeric input codes such as "AA149873A".
We'd like voice over to read these as "A A 1 4 9 8 7 2 A", but it instead reads the digits as a number: "One hundred and forty nine thousand, eight hundred and seventy three".
Is there some way to configure UITextField so that it knows its content shouldn't be thought of as numbers, but individual digits?
Thanks.
We'd like voice over to read these as "A A 1 4 9 8 7 2 A", but it instead reads the digits as a number: "One hundred and forty nine thousand, eight hundred and seventy three".
The fastest wy to reach your goal is to add spaces between each character in the accessibilityValue of the UITextField as follows: 🤓
class AccessibilityTextField: UITextField {
var _str: String?
override var text: String? {
get { return _str}
set {
_str = newValue!
accessibilityValue = _str!.map{String($0)}.joined(separator: " ")
}
}
convenience init() { self.init() }
required init?(coder: NSCoder) { super.init(coder: coder) }
}
I didn't implement all the text field delegate stuff to test it ⟹ I created a blank project only with an UITextField adding a "BB0024FG" plain text and changed the text in the viewDidAppear of my view controller:
myTextField.text = "AA14987A"
In the end, VoiceOver spells out each character after another without reading out the initial plain text. 👍
Following this rationale, you have a way that let VoiceOver know that the UITextField content must be thought as individual digits. 😉
As of iOS 13 it is possible to add a string attribute to direct voice-over vocalisation to spell strings out as individual letters and digits.
I've not found a way to direct UITextField to add this attribute to its content. However, a UITextField subclass can override it's accessibilityValue to achieve this.
The subclass given here adds a property to enable or disable this behaviour.
final class AccessibilityTextField: UITextField {
var isAlphanumeric: Bool = false
override public var accessibilityAttributedValue: NSAttributedString? {
get {
guard let text = text, !text.isEmpty else {
return nil
}
return NSAttributedString(string: text, attributes: valueAttributes)
}
set {
// Ignore these values.
_ = newValue
}
}
private var valueAttributes: [NSAttributedString.Key: Any] {
guard #available(iOS 13.0, *), isAlphanumeric else {
return [:]
}
return [.accessibilitySpeechSpellOut: true]
}
}
An alternative approach is given in another answer here that doesn't use the iOS 13 feature . accessibilitySpeechSpellOut. However, I've seen it suggested that this is not ideal for brail output systems as they also use accessibilityLabel. Perhaps this is a good fallback on pre iOS 13 systems.

NumberFormatter, NSLocale, Xcode, iOS, Swift 3.0

Problem: A textField with a "number" containing a decimal separator (a comma in my case), how can I change this to a decimal separator that Xcode will understand (.), and the other way around - display a result with the local decimal separator?
Ok...half way there...
let label = Input.text
let formatter = NumberFormatter()
let maybeNumber = formatter.number(from: label!)
if maybeNumber != nil {
Output.text = String(describing: maybeNumber!)
}
I'm not sure if this is what you mean, but you can change the comma in the textField.text to a (.) by using this piece of code:
textField.text = textField.text.replacingOccurrences(of: ",", with: ".", options: NSString.CompareOptions.literal, range: nil)
This finds the commas in your textField and replaces them with (.)

Win API wrong textbox output

I've been tying to build a simple Win Api program (using CodeBlocks) and ran into a weird problem.
case WM_COMMAND:{
if (LOWORD(wParam) == Calculate) {
int A=0, ArrayReset = 0;
char textread[256];
SendMessage((HWND)Box1,(UINT) EM_GETLINE, (WPARAM)1, (LPARAM)&textread);
A = atoi(textread);
itoa(ArrayReset, textread, 10);
itoa(A, textread, 10);
SendMessage((HWND)Box1,(UINT) WM_SETTEXT, (WPARAM)1,(LPARAM)&textread);
(My program is a bit more complicated, but this is just to show the problematic point)
Now, what I expect the code to do is to read the value in Box1, convert it into integer, convert it back to char array, and print this array back on the same Box1. Basically, some converting with no difference in the end result.
However, there is this strange problem. The code works with single digit numbers just fine, but if I enter a number with more digits, like 12 or 356, I get 1200 and 3560 respectively. If the input number is bigger than a thousand, it works fine again.
Is this a problem because of my method of resetting array's value back to 0, or does it have to do something with the conversion processes?
There are some mistakes in this code.
For starters, (LPARAM)&textread should be either (LPARAM)textread or (LPARAM)&textread[0].
But more importantly, you are not preparing the EM_GETLINE message correctly:
lParam
A pointer to the buffer that receives a copy of the line. Before sending the message, set the first word of this buffer to the size, in TCHARs, of the buffer. For ANSI text, this is the number of bytes; for Unicode text, this is the number of characters. The size in the first word is overwritten by the copied line.
Try this instead:
case WM_COMMAND:{
if (LOWORD(wParam) == Calculate) {
int A = 0;
TCHAR textread[256];
*((LPWORD)&textread) = 256; // <-- add this
SendMessage(Box1, EM_GETLINE, 0, (LPARAM)textread);
_stscanf(textread, _T("%d"), &A);
_stprintf(textread, _T("%d"), A);
SendMessage(Box1, WM_SETTEXT, 0, (LPARAM)textread);
}
break;
I think you have several problems there.
First, you didn't show us what Parse1 is. Beware that you must set the size of the buffer in the first word of the buffer. Also, why do you pass 1 as the WPARAM? This is the zero-based index of the line to retrieve from a multiline edit control, but is ignored if the edit is single line.
Also, what is with the first itoa call?
Here is an example that works:
TCHAR textread[256] = {0};
*(reinterpret_cast<WORD*>(&textread)) = 256;
::SendMessage(hwnd, EM_GETLINE, 0, reinterpret_cast<LPARAM>(&textread));
auto n = _ttoi(textread);
_itot_s(n, textread, 256, 10);
::SendMessage(hwnd, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(&textread));

Getting Glyph names using Core Text

For a small side project, I need to have all glyph names available in a font. So, I thought to make this:
CTFontRef f = CTFontCreateWithName(CFSTR("Zapfino"), 40, NULL);
CFIndex count = CTFontGetGlyphCount(f);
printf("There are %ld glyphs\n", count);
for (CGGlyph i = 1; i < count + 1; i++)
{
CTGlyphInfoRef gi = CTGlyphInfoCreateWithGlyph(i, f, CFSTR("(c)"));
CFStringRef name = CTGlyphInfoGetGlyphName(gi);
CGFontIndex idx = CTGlyphInfoGetCharacterIdentifier(gi);
printf("Glyph: %4hu, idx: %4hu ", i, idx);
CFShow(name);
printf("\n");
}
Creating the font and getting the glyph count works just fine. The name of the glyph is always NULL though. The CTGlyphInfoRef variable 'gi' gets a value. Any thoughts? What am I missing here?
You've misunderstood what CTGlyphInfo is about. It's not a way to query for information about a glyph. It's a representation of a substitution of a glyph for a string. You can set a glyph info object as the value for the kCTGlyphInfoAttributeName attribute in an attributed string. That glyph then replaces that range of attributed text, if the text matches the base string.
You can use CGFontCopyGlyphNameForGlyph() to get the name for a glyph from a font. You can create the CGFontRef directly using the CGFontCreate...() functions. You can also create one from a CTFont using CTFontCopyGraphicsFont().

Select hyphenated word with double-click

UPDATE: Per the recommendation below, here's specifically what I'd like to do: If I double-click the mouse cursor anywhere from the "b" to the "n" of "blue-green", I want all of the word "blue-green" should be highlighted. How can this be done? Currently, depending on where you click, it treats "blue-green" as three separate character strings. So, if you double click between the "b" and "e" of "blue" it highlights only "blue" and not "-green." If you double-click the hyphen, it highlights the hyphen alone. And if you double-click between the "g" and "n" of "green" it highlights only "green" and not "blue-".
ORIGINAL: When I double-click a hyphenated word or set of characters (e.g. "123-abc" or "blue-green" etc.), only the part of the word that I double-clicked is highlighted. I'd like the whole word to be highlighted.
I'm using Windows 7 Pro. If it needs to be done on a per-application basis, I'm most interested in fixing it for Google Chrome, but any Windows-compatible web browser would be OK.
Old question, but I happen to have been working on the same issue. Here's my solution:
jsFiddle.net
"use strict"
// Tweak to make a double-click select words with hyphens
//
// As of 2016-0816, None of the major Mac browser selects whole words
// with hyphens, like "ad-lib". This tweak fixes the hypen issue.
//
// Note: Firefox 48.0 doesn't automatically select whole words with
// apostrophes like "doesn't". This tweak also treats that.
;(function selectWholeWordsWithHyphens(){
var pOutput = document.getElementById("output")
var selection = window.getSelection()
// Regex designed to find a word+hyphen before the selected word.
// Example: ad-|lib|
// It finds the last chunk with no non-word characters (except for
// ' and -) before the first selected character.
var startRegex = /(\w+'?-?)+-$/g
// Regex designed to find a hyphen+word after the selected word.
// Example: |ad|-lib
var endRegex = /^-('?-?\w+)+/
// Edge case: check if the selection contains no word
// characters. If so, then don't do anything to extend it.
var edgeRegex = /\w/
document.body.ondblclick = selectHyphenatedWords
function selectHyphenatedWords(event) {
if (!selection.rangeCount) {
return
}
var range = selection.getRangeAt(0)
var container = range.startContainer
var string = container.textContent
var selectionUpdated = false
if (string.substring(range.startOffset, range.endOffset)
.search(edgeRegex) < 0) {
// There are no word characters selected
return
}
extendSelectionBackBeforeHypen(string, range.startOffset)
extendSelectionForwardAfterHyphen(string, range.endOffset)
if (selectionUpdated) {
selection.removeAllRanges()
selection.addRange(range)
}
function extendSelectionBackBeforeHypen(string, offset) {
var lastIndex = 0
var result
, index
string = string.substring(0, offset)
while (result = startRegex.exec(string)) {
index = result.index
lastIndex = startRegex.lastIndex
}
if (lastIndex === offset) {
range.setStart(container, index)
selectionUpdated = true
}
}
function extendSelectionForwardAfterHyphen(string, offset) {
if (!offset) {
return
}
string = string.substring(offset)
var result = endRegex.exec(string)
if (result) {
range.setEnd(container, offset + result[0].length)
selectionUpdated = true
}
}
}
})()
It's a standard through all programs that it will do that because they all run off the operating system's typing configuration/program thing. To fix it you would need to do something in System32. I don't know what you would need to do but I suspect this is your problem. You should probably go into more detail though about specifically what it is you want.

Resources