/// <summary> /// Retourne la liste des positions des derniers caractères de chaque ligne (dans S). /// </summary> /// <remarks>Utilise <c>finDeLignes</c> comme cache.</remarks> /// <returns>La liste des positions des derniers caractères de chaque ligne (dans S)</returns> protected override List <int> GetLastLinesPos() { logger.ConditionalDebug("GetLastLinesPos"); if (finsDeLigne == null) { logger.ConditionalTrace("txtRange.Start: {0}, txtRange.Length: {1}", txtRange.Start, txtRange.Length); finsDeLigne = new List <int>(7); int i = 1; int startColoredLine = 0; TextRange theLine = txtRange.Lines(i); while ((theLine.Start > startColoredLine) && (theLine.Start + theLine.Length) <= (txtRange.Start + txtRange.Length)) { logger.ConditionalTrace("i: {0}, theLine - Start: {1}, Length: {2}", i, theLine.Start, theLine.Length); if (theLine.Length > 0) { int endFormattedLine = theLine.Start + theLine.Length - 1; finsDeLigne.Add(endFormattedLine - txtRange.Start); } startColoredLine = theLine.Start; i++; theLine = txtRange.Lines(i); } } logger.ConditionalTrace("EXIT GetLastLinesPos"); return(finsDeLigne); }
// **************************************************************************************** // * public methods * // **************************************************************************************** public RTBText(RichTextBox theRTB) : base(theRTB.Text) { logger.ConditionalDebug("RTBText"); rtb = theRTB; logger.ConditionalTrace(rtb.Text); finDeLignes = new List <int>(); if (theRTB.Multiline) { int lineStart = 0; string[] theLines = theRTB.Lines; for (int i = 0; i < theLines.Length; i++) { int eol = lineStart + theLines[i].Length - 1; finDeLignes.Add(eol); lineStart = eol + 2; } } #if DEBUG for (int i = 0; i < finDeLignes.Count; i++) { logger.ConditionalTrace("finDeLignes[{0}] == {1}", i, finDeLignes[i]); } #endif }
/// <summary> /// Constructor of a FormatButton. The different <c>PictureBox</c>es must be at exactly the same possition. Their visibility is /// set according to the start status. /// </summary> /// <param name="inUnsetPict">The <c>PictureBox</c> that shows unset status.</param> /// <param name="inSetPict">The <c>PictureBox</c> that shows set status.</param> /// <param name="inPressedPict">The <c>PictureBox</c> that shows the status when the button is pressed.</param> /// <param name="inSetOverPict">The <c>PictureBox</c> that shows the status when the mouse is over the set button. This is typically a /// supplementary visible frame around the button</param> /// <param name="inSetAct">The method that must be called when the button is set</param> /// <param name="inUnsetAct">The method that must be called when the button is unset</param> /// <param name="startState"><c>true</c> means set, <c>false</c> means unset</param> public FormatButtonHandler2(PictureBox inPictBox, Image inUnsetPict, Image inSetPict, Image inPressedPict, Image inSetOverPict, Action inSetAct, Action inUnsetAct, bool startState) { logger.ConditionalTrace("Contructor FormatButtonHandler"); picts = new Image[(int)Pict.nrPict]; theBox = inPictBox; picts[(int)Pict.pressedPict] = inPressedPict; picts[(int)Pict.setOverPict] = inSetOverPict; picts[(int)Pict.setPict] = inSetPict; picts[(int)Pict.unsetPict] = inUnsetPict; setFormat = inSetAct; unsetFormat = inUnsetAct; activePict = Pict.nrPict; // no picture displayed yet if (startState) { state = State.set; } else { state = State.unset; } ActivatePict(state); theBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pbx_MouseDown); theBox.MouseEnter += new System.EventHandler(this.pbx_MouseEnter); theBox.MouseLeave += new System.EventHandler(this.pbx_MouseLeave); theBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pbx_MouseUp); }
protected AutomLetter() : base(" ", 0) { logger.ConditionalTrace("AutomLetter"); Letter = '$'; ruleOrder = null; rules = null; }
private TimeSpan DispatchTimers() { var now = GetTimestamp(); if (timers.Count == 0) { Log.ConditionalTrace("Quick return 1"); nextTimerDue = TimeSpan.MaxValue; return(Timeout.InfiniteTimeSpan); } // [Heuristic] // Problem: We don't want to recheck the list each time a new Task // is processed from the queue. // Idea: On very high load, when the queue is permanently full and // the current cache is in 'inf' cache state starting timers // will only add more load which won't be processed anyway. // So we wait for that the queue is empty then we recheck. // When we are not in 'inf' state we will just check like normal. if (queue.Count > 0 && now + CombineTimerThreshold < nextTimerDue && nextTimerDue != TimeSpan.MaxValue) { Log.ConditionalTrace("Quick return 2"); return(nextTimerDue - now); } Log.ConditionalTrace("Recalc"); var timeTillNextTimer = TimeSpan.MaxValue; foreach (var timer in timers) // TODO might be modified { var due = timer.Timestamp + timer.Interval; TimeSpan wait; if (due < now) { _ = Invoke(timer.Method); timer.Timestamp = GetTimestamp(); wait = timer.Interval; } else { wait = due - now; } if (wait < timeTillNextTimer) { timeTillNextTimer = wait; } } Trace.Assert(timeTillNextTimer != TimeSpan.MaxValue); timeTillNextTimer = timeTillNextTimer.Max(CombineTimerThreshold); nextTimerDue = now + timeTillNextTimer; return(timeTillNextTimer); }
/// <summary> /// Permet de mettre le <see cref="CharFormatting"/> pour une famille de ponctuation /// sans que la situation du mâître soit impactée. /// </summary> /// <remarks>Devrait être <c>private</c>, mais doit être visible pour la gestion des /// annulations. NE PAS UTILISER DANS UN AUTRE CONTEXTE!</remarks> /// <param name="p">La famille de ponctuation.</param> /// <param name="toCF">Le nouveau <see cref="CharFormatting"/>.</param> public void SetCFwoState(Ponctuation p, CharFormatting toCF) { logger.ConditionalTrace("SetCFwoState, p: {0}, to: {1}", p, toCF.ToString()); if (toCF != charFormats[p]) { UndoFactory.ExceutingAction(new PonctAction("Format ponct.", this, "ponctCF", p, charFormats[p], toCF)); charFormats[p] = toCF; OnPonctFormattingModified(p); } }
/// <summary> /// Cherche les phonèmes dans <c>pw</c> et complète <c>pw</c> pour qu'il contienne l'information. /// </summary> /// <param name="pw">Le <see cref="PhonWord"/> à analyser et à compléter avec ses phonèmes.</param> /// <param name="conf">La <see cref="Config"/> à utiliser au cours de cette analyse.</param> public void FindPhons(PhonWord pw, Config conf) { logger.ConditionalTrace("FindPhons"); Debug.Assert(pw != null); if (!AutomDictionary.FindPhons(pw, conf)) { int pos = 0; string w = pw.GetWord(); AutomLetter al; while (pos < w.Length) { if (automLetters.TryGetValue(w[pos], out al)) { al.FireRule(pw, ref pos, conf); } else if (automLetters.TryGetValue('*', out al)) { // strange character encountered --> handle it as letter '*' al.FireRule(pw, ref pos, conf); } else { // this should not happen!! string message = String.Format(ConfigBase.cultF, "La règle générique n'existe pas et on en aurait besoin..."); throw new KeyNotFoundException(message); } } // while } // if } // FindPhons
private bool TryResolve(Module module, bool force) { var result = TryResolve(module.Obj, module.Status, force); if (result) { module.SetInitalized(); Log.ConditionalTrace("Module {0} added", module); } else { Log.ConditionalTrace("Module {0} waiting for {1}", module, string.Join(", ", GetUnresolvedResolvable(module).Select(x => x.Name))); } return(result); }
private void UpdateRichTextBox(object sender, EventArgs e) { logger.ConditionalTrace("UpdateRichTextBox"); if (!resetting) { ProgressNotifier.thePN.Start(); rTBText.MarkNoir(theConfCopy); rTBText.MarkDuo(theConfCopy); ProgressNotifier.thePN.Completed(); } }
/// <summary> /// Checks to ensure we haven't extracted too many bytes, or taken too long. /// This exists primarily to mitigate the risks of quines (archives that /// contain themselves) and zip bombs (specially constructed to expand to huge /// sizes). /// Ref: https://alf.nu/ZipQuine /// </summary> /// <param name="additionalBytes"></param> private void CheckResourceGovernor(long additionalBytes = 0) { Logger.ConditionalTrace("CheckResourceGovernor(duration={0}, bytes={1})", GovernorStopwatch.Elapsed.TotalMilliseconds, CurrentOperationProcessedBytesLeft); if (GovernorStopwatch.Elapsed > Timeout) { throw new TimeoutException(string.Format($"Processing timeout exceeded: {GovernorStopwatch.Elapsed.TotalMilliseconds} ms.")); } if (CurrentOperationProcessedBytesLeft - additionalBytes <= 0) { throw new OverflowException(string.Format($"Too many bytes extracted, exceeding limit.")); } }
/************************ CONSTRUCTOR ****************************************** * Create an AutomRule Object * s: the string containing the specification of the automata * pos: on entry, the position of the first character of the Rule (should be ') * on exit the position of the last character of the Rule (should be ']') * SortedRuleNames: The valid RuleNames in a sorted array where BinarySearch can be executed. * * if s is not a valid Rule specification, an ArgumentException is thrown. * The RuleName can be read in the correpsonding Property. ***********************************************************************************************/ public AutomRule(string s, ref int pos, List <string> SortedRuleNames) : base(s, pos) { logger.ConditionalTrace("AutomRule"); /* A Rule has the Syntax * 'ruleName' : [{list of DirectionRegex separated by ','}, 'phoneme', pas] * where * regexRule is '+|-':/regEx/i * phoneme is a string * pas is an integer * * ruleName has to be part of ruleNames */ // Let's parse the ruleName Debug.Assert(s[pos] == '\'', String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, il ne commence pas par \'.", pos - start, s.Substring(start, (pos + 1) - start))); pos = GetNextChar(pos + 1); var endOfRuleNameApostrophyPos = s.IndexOf('\'', pos); Debug.Assert(endOfRuleNameApostrophyPos > pos, String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, le nom de la règle ne se termine pas par \'.", pos - start, s.Substring(start, (pos + 1) - start))); RuleName = s.Substring(pos, endOfRuleNameApostrophyPos - pos).Trim(); // check that ruleName is in ruleNames Debug.Assert(SortedRuleNames.BinarySearch(RuleName) >= 0, String.Format(ConfigBase.cultF, "AutomRule: {0} ne se trouve pas dans la liste des noms de règles.", RuleName)); pos = endOfRuleNameApostrophyPos; // Let's find the colon pos = GetNextChar(pos + 1); Debug.Assert(s[pos] == ':', String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, on attend un \':\'", pos - start, s.Substring(start, (pos + 1) - start))); // let's find the [ pos = GetNextChar(pos + 1); Debug.Assert(s[pos] == '[', String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, on attend un \'[\'", pos - start, s.Substring(start, (pos + 1) - start))); // let's find the RuleFilter pos = GetNextChar(pos + 1); rf = new AutomRuleFilter(s, ref pos); // let's find the comma pos = GetNextChar(pos + 1); Debug.Assert(s[pos] == ',', String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, on attend une \',\' avant le phonème.", pos - start, s.Substring(start, (pos + 1) - start))); // let's find the phoneme pos = GetNextChar(pos + 1); Debug.Assert(s[pos] == '\'', String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, on attend \' au début du phonème.", pos - start, s.Substring(start, (pos + 1) - start))); // let's find the phoneme name pos = GetNextChar(pos + 1); var endOfPhonemeApostrophyPos = s.IndexOf('\'', pos); Debug.Assert(endOfPhonemeApostrophyPos > pos, String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, le nom du phonème ne se termine pas par \'.", pos - start, s.Substring(start, (pos + 1) - start))); var phonemeName = s.Substring(pos, endOfPhonemeApostrophyPos - pos).Trim(); p = (Phonemes)Enum.Parse(typeof(Phonemes), phonemeName); pos = endOfPhonemeApostrophyPos; // let's find the comma pos = GetNextChar(pos + 1); Debug.Assert(s[pos] == ',', String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, on attend une \',\' avant le pas.", pos - start, s.Substring(start, (pos + 1) - start))); // let's find the increment i.e. le pas pos = GetNextChar(pos + 1); var endOfNumberPos = s.IndexOfAny("],".ToCharArray(), pos); Debug.Assert(endOfNumberPos > pos, String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, on attend \']\' ou \',\' après le pas.", pos - start, s.Substring(start, (pos + 1) - start))); var theIntString = s.Substring(pos, endOfNumberPos - pos).Trim(); incr = int.Parse(theIntString, ConfigBase.cultF); pos = endOfNumberPos; // if we are on a coma, there is an identifier to load. if (s[pos] == ',') { pos = GetNextChar(pos + 1); var endOfFlagName = s.IndexOf(']', pos); Debug.Assert(endOfFlagName > pos, String.Format(ConfigBase.cultF, "La pos {0} de {1} n'est pas un AutomRule, on attend \']\' après le nom de flag.", pos - start, s.Substring(start, (pos + 1) - start))); var flagName = s.Substring(pos, endOfFlagName - pos).Trim(); flag = (ColConfWin.RuleFlag)Enum.Parse(typeof(ColConfWin.RuleFlag), flagName); pos = endOfFlagName; } else { flag = ColConfWin.RuleFlag.undefined; } end = pos; } // constructor AutomRule
/// <summary> /// Cherche une ou plusieurs diérèses dans le vers, transforme les mots correspondants /// jusqu'à ce que le nombre de pieds voulu soit atteint ou qu'il n'y ait plus de diérèse /// détectable. /// </summary> /// <param name="conf">La <c>Config</c> à utiliser pour l'identification des pieds.</param> /// <param name="nbrPiedsVoulu">Le nombre de pieds souhaité après la mise en évidence des /// diérèses. </param> /// <exception cref="ArgumentOutOfRangeException">Si <c>nbrPiedsVoulu</c> n'est pas /// plus grand que zéro.</exception> public void ChercheDierese(int nbrPiedsVoulu) { logger.ConditionalDebug("ChercheDierese, nrPiedsVoulu: {0}, vers; {1}", nbrPiedsVoulu, ToString()); if (nbrPiedsVoulu > MaxNrPieds) { logger.Info( "Chercher diérèse pour vers de plus de [0] pieds. Non exécuté. nrPiedsVoulu: {1}", MaxNrPieds, nbrPiedsVoulu); return; } if (nbrPiedsVoulu <= 0) { logger.Fatal("nbrPiedsVoulu == {0}", nbrPiedsVoulu); throw new ArgumentOutOfRangeException(nameof(nbrPiedsVoulu), "doit être plus grand que 0"); } // traitement spécial pour les nombres de pieds pairs, parcequ'ils le valent bien! if (nbrPiedsVoulu % 2 == 0) { // nombre pair de pieds // Y a-t-il un hémistiche à la moitié du vers ou juste avant? int demiVers = nbrPiedsVoulu / 2; List <PhonWord> moitie1 = new List <PhonWord>(5); int i = 0; int piedsM1 = 0; while (i < pWordList.Count && piedsM1 < demiVers - 1) { moitie1.Add(pWordList[i]); piedsM1 = ComptePieds(moitie1); i++; } // En prenant les cas dans cet ordre, on favorise légèrement la recherche de la // diérèse dans la première partie du vers. Il y a au moins un exemple dans le // poème de référence où cette approche est justifiée: // "D'affreux bohémiens, des vainqueurs de charnier" // Faut-il rallonger "bohémines" ou "charnier"? Il y a certainement des cas // qui demanderaient l'approche opposée. Je ne vois pas comment les distinguer // sans tenir compte du sens ou d'éléments que j'ignore jusqu'ici comme la // virgule dans le vers de V. Hugo. if (piedsM1 == demiVers - 1) { List <PhonWord> moitie2 = new List <PhonWord>(5); while (i < pWordList.Count) { moitie2.Add(pWordList[i]); i++; } ChercherDierese(moitie1, demiVers); if (ComptePieds(pWordList) < nbrPiedsVoulu) { ChercherDierese(moitie2, demiVers); } if (ComptePieds(pWordList) < nbrPiedsVoulu) { ChercherDierese(pWordList, nbrPiedsVoulu); } } else if (piedsM1 == demiVers) { // hypothèse: on a trouvé l'hémistiche List <PhonWord> moitie2 = new List <PhonWord>(5); while (i < pWordList.Count) { moitie2.Add(pWordList[i]); i++; } ChercherDierese(moitie2, demiVers); if (ComptePieds(pWordList) < nbrPiedsVoulu) { ChercherDierese(moitie1, demiVers); } if (ComptePieds(pWordList) < nbrPiedsVoulu) { ChercherDierese(pWordList, nbrPiedsVoulu); } } else if (piedsM1 > demiVers) { // On est allés trop loin. // on n'a pas réussi à trouver d'hémistiche. ChercherDierese(pWordList, nbrPiedsVoulu); } else { // Bizarre: le vers entier semble faire moins de la moitié des pieds voulus... logger.Info("On demande {0} pieds pour le vers {1}.", nbrPiedsVoulu, ToString()); ChercherDierese(pWordList, nbrPiedsVoulu); // ça ne devrait pas marcher... } } else { // nombre impair de pieds voulu. logger.ConditionalDebug("Nombre impair ({0}) de pieds voulus pour {1}", nbrPiedsVoulu, ToString()); ChercherDierese(pWordList, nbrPiedsVoulu); } nrPieds = ComptePieds(pWordList); if (nrPieds != nbrPiedsVoulu) { logger.ConditionalTrace( "!! Diérèse pas trouvée. nbrPiedsVoulu: {0}, nrPieds: {1}, vers: \'{2}\'," + "syls: \'{3}\'", nbrPiedsVoulu, nrPieds, ToString(), Syllabes()); } }
/// <summary> /// Indique la progression de la tâche. /// </summary> /// <remarks>Autant que possible, ne pas appeler cette méthode plus d'une fois par pourcent.</remarks> /// <param name="progression">en pourcents (0 - 100) l'état de progression de la tâche.</param> public void InProgress(int progression) { logger.ConditionalTrace(ConfigBase.cultF, "InProgress {0}%", progression); OnProgressEvent(progression); }
/// <summary> /// Empêche que les actions soient enregistrées pour pouvoir ensuite être annulées. /// Fonctionne en paire avec <see cref="EnableUndoRegistration"/> qui doit être appelé /// quand les actions peuvent à nouveau être enregistrées. /// </summary> /// <remarks>Les appels de cette méthode peuvent être imbriqués. Mais un /// <see cref="EnableUndoRegistration"/> doit correspondre à un <c>Disable</c></remarks> public static void DisableUndoRegistration() { logger.ConditionalTrace("DisableUndoRegistration"); disableRegistering++; }