January 25, 2012

ThomasJoachim ThomasJoachim
Lab Rat
24 posts

QTextEdit and QTextDocumentWriter

 

Hello
working with QTextEdit is very fine. Saving files is not so fine.

A new line is always marked with a LineFeed (0×0A).
For other software I need Carriage Return (0×0D) and LineFeed(0×0A).

How can I configure QTextDocumentWriter to this for me?

Thomas

7 replies

January 26, 2012

Volker Volker
Ant Farmer
5428 posts

Did you try to use a QFile opened with mode QIODevice::Text and pass its pointer to the QTextDocumentWriter constructor?

January 26, 2012

ThomasJoachim ThomasJoachim
Lab Rat
24 posts

Hello,
I have to check it this evening. What I found is, that the Carriage Returns are eliminated automatically.

Thanks

January 26, 2012

ThomasJoachim ThomasJoachim
Lab Rat
24 posts

Hallo Volker,
Das ist der Code, den ich irgendwo gefunden und programmiert habe.
Eigentlich brauche ich nur reine Text-Dateien (aber mir CR/LF) und eine entsprechende Prüfung, ob es tatsächlich ein reines Textfile ist.

Vielen Dank

  1.   if (!QFile::exists(f))
  2.         return false;
  3.     QFile file(f);
  4.     if (!file.open(QFile::ReadOnly))
  5.         return false;
  6.  
  7.     QByteArray data = file.readAll();
  8.     QTextCodec *codec = Qt::codecForHtml(data);
  9.     QString str = codec->toUnicode(data);
  10.     if (Qt::mightBeRichText(str)) {
  11.         textEdit->setHtml(str);
  12.     } else {
  13.         str = QString::fromLocal8Bit(data);
  14.         textEdit->setPlainText(str);
  15.     }

January 26, 2012

Volker Volker
Ant Farmer
5428 posts

Hm, ich würde sagen, das geht nicht mit Qt Bordmitteln direkt. Ob es sich um HTML oder plain text handelt, kann man mit mightBeRichText herausfinden.

Wenn Du rausfinden willst, ob die Zeilenenden passen, würde ich den Dateiinhalt in ein QByteArray einlesen (zumindest die ersten paar Kilobyte). Dann nach der ersten Position eines newlines (LF) suchen und schauen, ob das Byte davor ein CR ist.

Ist vielleicht nicht wirklich effektiv, elegant ist sicher auch anders, aber sollte funktionieren.

January 27, 2012

ThomasJoachim ThomasJoachim
Lab Rat
24 posts

Wenn dann aber CR LF drin sind, sind die CR ja nach dem abspeichern weg, was der Anwendung, die die Dateien bekommen soll nicht gefällt.

  1.      
  2.       QTextDocumentWriter writer(fileName);
  3.       writer.setFormat("plaintext");
  4.       success = writer.write(textEdit->document());

Warum auch immer das so ist. Schliesslich ist es MS-Windows und da war schon immer CR LF
?

Gruss Thomas

January 27, 2012

Volker Volker
Ant Farmer
5428 posts

Das einzige was mir dazu jetzt einfällt, wäre ein manuelles einlesen der Zeilen und wieder rausschreiben mit CRLF dran. So in etwa könnte ich mir das vorstellen:

  1. QFile input("abc.txt");
  2. input.open(QIODevice::ReadOnly);
  3.  
  4. QFile output("xyz.txt");
  5. output.open(QIODevice::WriteOnly);
  6.  
  7. while(input.canReadLine()) {
  8.     QByteArray line = input.readLine();
  9.     // line.at(size-1) == LF
  10.     // line.at(size-2) könnte ein CR sein
  11.     // falls ja: nichts machen, die Zeile passt
  12.     // falls nein: das LF durch ein CR tauschen und das LF anhängen
  13.     int size = line.size();
  14.     if(line.at(size-2) != '\r') {
  15.         line[size-1] = '\r';
  16.         line.append('\n');
  17.     }
  18.     output.write(line);
  19. }
  20.  
  21. output.close();
  22. input.close();

Anstelle von QFile als input-device kannst Du auch einen QBuffer nehmen, in den Du einen QString stopfst.

January 28, 2012

ThomasJoachim ThomasJoachim
Lab Rat
24 posts

Hallo Volker,
Vielen Dank für den Hinweis.

So ähnlich habe ich es nun gelöst.

  1.   if (!QFile::exists(f))
  2.         return false;
  3.     QFile file(f);
  4.     if (!file.open(QIODevice::Text | QFile::ReadOnly))
  5.         return false;
  6.  
  7.     QByteArray data = file.readAll(); // --> hier waren schon alle CR verschwunden

Beim Rausschreiben folgt dann:

  1.       QTextDocument *doc = textEdit->document();
  2.       QString data = doc->toPlainText();
  3.       QByteArray bytes;
  4.       bytes.append(data);
  5.  
  6.       QFile outputFile(fileName);
  7.       QFile::FileError err = outputFile.error();
  8.  
  9.       if (outputFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
  10.       {
  11.         outputFile.write(bytes); // das muss es wohl gewesen sein siehe untern **
  12.         outputFile.close();
  13.         success = true;
  14.       }
  15.     }
  • bei QFile stand da irgendwo in der Docu:
    The QIODevice::Text flag passed to open() tells Qt to convert Windows-style line terminators (”\r\n”) into C++-style terminators (”\n”)

Das war dann auch so. Nach dem read waren alle verschwunden und kamen wieder nach dem write().
Die ursprüngliche Lösung mit QTextDocumentWriter hat nicht funktioniert, da waren CR weg.

 
  ‹‹ VS2010 und QT 4.8.0 scheitert      Eigene Widgets (nicht QML) mit Qt Creator ››

You must log in to post a reply. Not a member yet? Register here!