RE: Textblock, alle Zeilen einrücken
-
In der Form liegt ein RichEdit (Txt), alClient, PlainText, WordWrap.
Darüber (genau gleich groß) ein Dummy, RichEdit (Druide), alClient, PlainText, WordWrap, Visible=false.Ich markier einen beliebigen Textblock, der Code rückt jede Zeile ein.
Den Dummy nutz ich, weil der Textblock während der Aktionen schwer/gar nicht zu erhalten war.
Da der Cursor-Vorschub zum nächsten Zeilenanfang in der while-Schleife an "\r\n" hängen blieb, ersetze ich im Druiden alle "\r\n" gegen "\n". Nun klappt - soweit getestet - jede Situation.
Problem: Die Zeilen im eingerückten Block werden kürzer. Also der Text füllt nun nicht mehr die vollen möglichen Zeilenlängen auf. Das ist auch so, wenn im Block kein "\r\n" vorhanden ist. - Ich kann mir den Grund nicht erklären. Bringt ggf. StringReplace da was durcheinander?
Kann jemand den Fehler erkennen? Der Ausrufezeichen-Kommentar markiert die Stelle:
void __fastcall TChild::TextBlockClick(TObject *Sender) { // Txt = RE, Druide = Dummy-RE // Textblock ist markiert int Start = Txt->SelStart, Ziel = Txt->SelLength; // vor dem Textblock ein '\n' ? if (Txt->Text.SubString(Start,1) == "\n") { // Zeile einrücken, Cursor an den Zeilenanfang Txt->SelText = "\t" + Txt->SelText; Txt->SelStart = Start; CarPYold = Txt->CaretPos.y; // Cursor eine Zeile tiefer // Blockende beibehalten while (Txt->CaretPos.y <= CarPYold) { Txt->SelStart++; Ziel--; } // '\t' kam dazu, also Ziel++; } // kein '\n' vor dem Textblock else if (Txt->Text.SubString(Start,1) != "\n") { // "\n" + Zeile einrücken, Cursor an den Zeilenanfang Txt->SelText = "\n\t" + Txt->SelText; Txt->SelStart = Start; CarPYold = Txt->CaretPos.y+1; // Cursor eine Zeile tiefer // Blockende beibehalten while (Txt->CaretPos.y <= CarPYold) { Txt->SelStart++; Ziel--; } // "\n\t" kam dazu, also Ziel+=2; } // Restlichen Textblock an Dummy übergeben Txt->SelLength = Ziel; Druide->Clear(); Druide->Text = Txt->SelText; // alle "\r\n" in "\n" umwandeln /* !!!! hilft, aber die Blockzeilen werden kürzer !!!! */ AnsiString Alles(Druide->Text); Druide->Text=StringReplace(Alles, "\r\n", "\n", TReplaceFlags()<<rfReplaceAll); Txt->ClearSelection(); // Bei minimal 2 Zeilen kannst du fehlerfrei arbeiten, also while (Druide->Lines->Count>1) { // bau mal ein ENTER + Einrückung Druide->SelStart = 0; Druide->SelectAll(); Druide->SelText = "\n\t" + Druide->SelText; Druide->SelStart = 0; CarPYold = Druide->CaretPos.y+1; // Cursor an den Zeilenanfang eine Zeile tiefer while (Druide->CaretPos.y <= CarPYold) { Druide->SelStart++; Druide->Refresh(); } CarPYold = Druide->CaretPos.y; // markier die erste Zeile und schick sie ans Haupt-RE Ziel = Druide->SelStart; Druide->SelStart = 0; Druide->SelLength = Ziel; Txt->SelText = Druide->SelText; Druide->ClearSelection(); } // Nun noch die letzte Leile zum Haupt-RE schicken Txt->SelText = "\n\t" + Druide->Text; }
Ob das Manöver auch mit weniger Aufwand geht? Wär für Tips dankbar.
-
hi,
ich versteh den Grund der umständlichen Aktionen nicht. Und warum brauchst du zwei RichEdit für ein
was spricht gegen sowas in abgeänderter form:
RichEdit1->Lines->Strings[0]=RichEdit1->Lines->Strings[0].Insert("\t",1);
-
Hmmm..., na ja, die Zeilen werden ziemlich lang. ZB.:
Txt->Lines->Strings[Txt->Perform(EM_EXLINEFROMCHAR,0,Txt->SelStart)] = Txt->Lines->Strings[Txt->Perform(EM_EXLINEFROMCHAR,0, Txt->SelStart)].Insert("\n\t",1);
Die Prüfung, ob der Text über dem Block mit "\n" abgeschlossen ist, bleibt. Wird darüber weiterer Text geschrieben, soll der Einrück-Block ja erhalten bleiben.
"\r\n" innerhalb des Blockes sollen erhalten bleiben. Hier muß ich was tun, da while sonst hängen bleibt. Oder ich versuch, die while wegzulassen. Vielleicht mit for die Zeilen weiterschalten?
Aber wie behalte ich den Block exakt bei? Da müßte ich sicher genau mitprotokollieren, was in der Schleife passiert.
Bzw. vom SubString jeweils die fertiggestellte Zeile vornedran abziehen. Hierfür hab ich noch keine Methode gefunden.Also ich schreib ja leidenschaftlich gern kompakten Code. Das gelingt (mir) meist nie im ersten Anlauf. Muß die Sache noch mal aufrollen. Bin also weiterhin für Tips sehr dankbar.
-
Ich denke, du hast hier alle nötigen Informationen erhalten, warum jetzt ein neuer Thread zum selben Thema!?