URL avec accents dans un NSTextView
regatta
Membre
Bonjour,
j'ai un texte affiché dans un NSTextView (type RTF) et je cherche à transformer en URL un mot sélectionné : le mot "toto" doit devenir "http://toto.htm".
J'ai créé un menu contextuel qui appelle une routine dans laquelle le mot sélectionné est convertit et la conversion vient remplacer le mot sélectionné dans la NSTextView.
J'ai utilisé une méthode "artisanale" dans laquelle je code en RTF le lien. Cela fonctionne si le mot n'a pas d'accent ; sinon le caractère accentué est mal codé
J'ai pourtant testé avec divers encodages dont NSMacOSRomanStringEncoding et bien d'autres.
En cherchant dans les programme Apple, TextEdit semble traiter ce cas, mais en regardant le source, je n'arrive pas à trouver le code dans le programme :fouf):
une idée pour résoudre ce problème !
j'ai un texte affiché dans un NSTextView (type RTF) et je cherche à transformer en URL un mot sélectionné : le mot "toto" doit devenir "http://toto.htm".
J'ai créé un menu contextuel qui appelle une routine dans laquelle le mot sélectionné est convertit et la conversion vient remplacer le mot sélectionné dans la NSTextView.
J'ai utilisé une méthode "artisanale" dans laquelle je code en RTF le lien. Cela fonctionne si le mot n'a pas d'accent ; sinon le caractère accentué est mal codé
J'ai pourtant testé avec divers encodages dont NSMacOSRomanStringEncoding et bien d'autres.
En cherchant dans les programme Apple, TextEdit semble traiter ce cas, mais en regardant le source, je n'arrive pas à trouver le code dans le programme :fouf):
une idée pour résoudre ce problème !
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
(Tu parles de "la méthode artisanale" passant par du RTF... J'ai pas tout compris ce que tu voulais dire, ce que le format RTF vient faire dans la création de ton URL à partir de ton texte, et ce que tu appelles méthode artisanale...)
J'ai utilisé Textedit dans lequel j'ai saisi un URL, puis Smultron pour regarder le codage ; enfin j'ai remplacé mon texte sélectionné par son équivalent en URL en construisanrt un NSData et en insérant mon mot par dans le NSData :
[data appendData:[texte dataUsingEncoding:NSMacOSRomanStringEncoding]];
Enfin [self replaceCharactersInRange:[[ranges objectAtIndex: 0] rangeValue] withRTF:data];
remplace mon mot sélectionné par son équivalent url dans l'affichage.
De l'artisanal quoi ???
Mais ta méthode me semble parfaitement répondre à la question
Je teste.
Merci
Pourquoi passer par un NSData, d'où te vient cette idée ? Parce que tu voulais utiliser [tt]replaceCharactersInRange: withRTF:[/tt] et que tu avais besoin d'un NSData c'est ça ? Mais pourquoi uiliser cette méthode et donc passer par du RTF alors que ton texte d'origine n'est manifestement pas du RTF (et s'il en est, il faut absolument récupérer le texte non-RTF, le texte seul sans les balises de mise en forme RTF, quoi, car s'il y en a il ne faudrait pas qu'elles se retrouvent dans ton URL...)
Bref, la bidouille, c'est parfois utile, mais c'est "dangereux" aussi, faut pas faire un peu n'importe quoi juste parce que ça a l'air de coller ! Là je vois mal le but de construire ton NSData avec des appendData qui n'ont pas lieu d'être ici (si tu as besoin de construire ton texte par morceaux, fais-le avec des NSString (méthodes stringWithFormat ou appendString) avant la conversion en NSData... et encore si cette dernière s'avère nécessaire... bref, rester logique quoi :P
Il est stocké dans une base de donnée, relu ou sauvegardé si je fais des modifications.
De là l'utilisation de NSData !
Par contre, je ne vois pas comment utiliser stringByAddingPercentEscapesUsingEncoding pour résoudre mon problème !
[texte stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[self replaceCharactersInRange:[[ranges objectAtIndex: 0] rangeValue] withString:texte];
ne remplace pas le texte sélectionné (texte) par http://contenu_de_texte.htm
1) Comme sa signature et la doc l'indiquent, et comme le laissent sous-entendre les conventions de nommage, [tt]- (NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)encoding[/tt] ne transforment pas ta chaà®ne, mais en retourne une nouvelle.
Donc si "texte" est ton texte que tu veux échapper avec des %xx pour l'utiliser ensuite pour construire ton URL, il faut récupérer le résultat de la méthode ci-dessous, appliquée à la variable "texte", dans une autre variable !
2) C'est qui ce "self" ? Dans quoi mets-tu la méthode ? C'est pas plutôt à la chaà®ne contenue dans ton NSTextField ou ta base ou autre plutôt que tu veux appliquer [tt]replaceCharactersnRange:withString:[/tt] ? En effet, à ma connaissance, cette méthode est une méthode de NSMutableString... donc est-ce voulu que tu l'appliques à "self", dont je doute qu'il soit une NSMutableString ? Ou alors tu as créé une méthode ayant la même signature dans la classe dans laquelle tu mets ce code, pour faciliter les choses, qui se charger de récupérer le texte, sous forme de MutableString, la modifier, et remettre le nouveau texte ?
Enfin un peu plus de détails aideraient à comprendre si c'est voulu ou une erreur de ta part, en fait à quel endroit mets-tu ce code (qu'on sache à quoi self fait référence) ?
Sinon pour le coup du RTF, tu utilises les classes faites pour, de manière à convertir proprement tes données RTF en NSData et vice-versa ? J'ai l'impression que tu te contentes de transformer ton NSString en NSData sans autre forme de procès ? Tu passes au moins par NSAttributedString ou qqch du genre ? Un peu plus de détails là aussi pour vérifier que tu ne fais pas fausse route serait utile.
Après sélection du mot à transformer en URL, et un clic droit sur le menu contextuel, je récupère le contenu de la sélection, tente de transformer le texte sélectionné en une adresse url, qui remplace le mot sélectionné et je sauvegarde le nouveau contenu du texte.
Après, lorsque je clic sur l'url, j'utilise la méthode de NSTextView - (void)clickedOnLink:(id)link atIndex:(NSUInteger)charIndex pour lire le mot clé et afficher le texte correspondant au mot clé.
Voici l'écran avant ma méthode artisanale
Après la transformation
Après le clic sur le lien créé
(si les images s'affichent correctement !)
Je souhaite remplacer "Wollastonite" par "http://Wollastonite" pour que NSTextView le considère comme un URL et que son delegate puisse utiliser "clickedOnLink" pour afficher le texte de la base correspondant au minéral Wollastonite".
Cela fonctionne correctement avec mon horreur de code à part si un accent est dans le mot sélectionné !
Si on prend le mot Trémolite, Textedit sauvegarde le lien sous la forme
{\field{\*\fldinst{HYPERLINK "http://Trémolite"}}{\fldrslt
\f0\fs24 \cf0 Tr\'e9molite}}}
Le codage dans le lien est différent du codage du mot !
Ajout : j'avais pas vu la boulette :-\\
NSString * texte2 = [texte stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
Il faut que tu évites, autant que faire se peut*, d'utiliser des méthodes artisanales alors que Cocoa fournit tout ce qu'il faut... En effet il est préférable d'utiliser les méthodes qui te sont mises à disposition car en général quand c'est Apple qui les a codées, ils pensent alors à gérer tous les cas de figure et toutes les petites subtilités...
Dans ton cas donc, c'est une très mauvaise idée de chercher à créer les données RTF par toi même. Tu as en effet déjà pu remarquer qu'il faut que tu penses à gérer le cas des accents... et il y a sans doute d'autres subtilités. De plus, si tu veux pouvoir sélectionner un bout de texte mis en forme dans ton texte, dont une partie est en gras et l'autre pas par exemple, et mettre ceci en lien... si tu fais le code de génération des données RTF toi-même, ça commence à faire un sacré paquet de cas à se préoccuper...
Alors pourquoi se prendre la tête à réinventer la roue quand Cocoa prévoit tout ce qu'il faut pour te faciliter la vie ?
En particulier, NSAttributedString et ses Additions te donnent tout ce qu'il faut pour créer une NSAttributedString qui intègre les liens, de façon propre.
Comme tu peux facilement récupérer la NSAttributedString sélectionnée lrs de ton clic droit (et donc avoir ainsi une chaà®ne qui garde les informations de formattage, tant qu'à faire autant éviter de s'en priver), il suffit de rajouter à cette NSAttributedString l'attribut [tt]NSLinkAttributeName[/tt] avec le lien que tu veux.
Donc les étapes à réaliser :
En faisant ainsi, tu n'as ainsi pas à descendre bas niveau (et c'est là ton erreur à mon sens) ni à comprendre comment fonctionne le RTF : on se fiche de savoir comment le RTF se démerde pour coder les liens et tout ce que tu veux, on laisse Cocoa se débrouiller avec ce qu'on lui demande, c'est à dire juste ce que tu veux sans chercher plus loin, c'est à dire ajouter un attribut de lien au texte sélectionné. Faut pas chercher plus loin et manipuler le RTF toi-même, tu risques plus de fouttre le boxon dans ton texte et/ou oublier des cas qu'autre chose !!
Note de plus qu'en faisant ainsi, l'étape 3 peut se contenter de convertir ton texte avec [tt]stringByAddingPercentEscapesUsingEncoding[/tt] : je ne suis même pas sûr que tu aies besoin d'ajouter le "http://" devant (que tu ajoutais pour qu'il réalise que c'est un lien, si j'ai tout suivi), puisque tu demandes explicitement à ton NSAttributedString d'ajouter l'attribut comme étant de type lien ! (D'ailleurs à se demander si même le percentEscape est utile). Du moment que c'est toi ensuite qui intercepte l'évènement de clic sur un lien dans ta NSTextView, et donc intercepter le résultat pour en récupérer le mot clé cliqué...
----
En suivant cette procédure haut niveau, non seulement tu n'as pas à te demander comment le format RTF est foutu sous le capot, tu n'as pas à te préoccuper des petites subtilités et cas auxquels tu aurais pu ne pas penser... et en plus si le format sous-jacent change ou est géré autrement, tu t'en fiches : tu laisses Cocoa tout faire, tu te contentes de lui dire exactement ce que tu veux (rajouter un lien à ton mot) et pas bidouiller par toi-même pour y arriver...
Et ça c'est un conseil général, évite de descendre trop bas niveau quand ce n'est pas nécessaire, vérifie avant que Cocoa ne te permet pas de faire directement ce que tu veux
*j'adore cette expression
Si j'ai utilisé une méthode artisanale, c'est que je n'ai pas trouvé d'autre solution
D'où ma question dans le forum !
Je développe dans un tout autre domaine et je ne réinvente pas la roue si j'ai une solution standard, et maintenant j'ai cette solution.
Ajout : cela marche nickel (après passage en SDK 10.5). Effectivement j'avais vu que les attributs n'étaient pas repris, mais je voulais traiter un problème avant l'autre ; maintenant tous les problèmes sont réglés pour le lien !
Merci et A+
Eric