So I am building a cross platform QT text editor. I am developing on Linux, to target for Windows. I am making it as easy as possible for the user to save the text file with whichever encoding that they wish.
I compiled the project with with M Cross Environment "MXE"
via the tutorial on their website.
On Linux, everything works perfectly as I want it to so far.
However, on Windows, if I create a file with the text editor (no matter what encoding I choose) and then open it in Notepad, the entire file is in one line.
I am fairly certain that I have found the problem. If I open the file that my QT text editor has created, Emacs says that it has a "Unix" "end of line style."
I am assuming that Windows does not recognize the new line characters because they are Unix style. However, I am unsure how to change the "end of line style" in QTextStream
. The documentation did not seem to be of any help, and I wasn't able to find anyone else on Stack overflow or otherwise that has the same problem.
The following is my code for saving the file. The encodeString
variable controls which encoding the file is saved in.
void mainwindow::on_actionSave_triggered()
{
if (!saveFile.isEmpty())
{
//"saveFile" is populated with the file name when the file is first opened.
QFile file(saveFile);
if (!file.open(QIODevice::WriteOnly))
{
qDebug() << "Could not find file."
}
else
{
//The following if statements will save the file in the proper encoding dependant on the value of "encodeString."
QTextStream stream(&file)
if (encodeString == "Plain Text")
{
stream << ui->textEdit->toPlainText();
stream.flush();
file.close();
}
if (encodeString == "UTF-8")
{
stream.setCodec("UTF-8");
stream.setGenerateByteOrderMark(true);
stream << ui->textEdit->toPlainText();
stream.flush();
file.close();
}
if (encodeString == "UTF-16")
{
stream.setCodec("UTF-16");
stream.setGenerateByteOrderMark(true);
stream << ui->textEdit->toPlainText();
stream.flush();
file.close();
}
if (encodeString == "UTF-16BE")
{
stream.setCodec("UTF-16BE");
stream.setGenerateByteOrderMark(true);
stream << ui->textEdit->toPlainText();
stream.flush();
file.close();
}
if (encodeString == "UTF-32")
{
stream.setCodec("UTF-32");
stream.setGenerateByteOrderMark(true);
stream << ui->textEdit->toPlainText();
stream.flush();
file.close();
}
if (encodeString == "UTF-32BE")
{
stream.setCodec("UTF-32BE");
stream.setGenerateByteOrderMark(true);
stream << ui->textEdit->toPlainText();
stream.flush();
file.close();
}
}
}
}
The following is the code for opening the file. It is just streamed to ui->textEdit
As a secondary question, I would love to be able to record the encoding of the file that is being opened into the value of encodeString
.
void MainWindow::on_actionOpen_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QString(), tr("All Files (*.*);;Text Files (*.txt);;C++ Files (*.cpp *.h)")); //Opens the QDialog for opening files.
saveFile =fileName; //Sets the value of "saveFile" to the value of "fileName." This insures that any time a "Save" function is performed, the file that the text is saved to, is the one that is intended.
MainWindow::setWindowTitle(saveFile);
if(!fileName.isEmpty()) // As long as the file name variable is not empty, this will trigger.
{
QFile file(fileName);
if(!file.open(QIODevice::ReadOnly)) // If the file could not be opened, it will trigger this error message.
{
QMessageBox::critical(this, tr("Error"), tr("Could not open file"));
return;
}
QTextStream in(&file); //This sets the variable "in" to be the contents of the file.
ui->textEdit->setText(in.readAll()); //This sets the text that is in the text edit field to be the contents of the file.
file.close(); //This closes the file so that no memory errors are caused by having too many files open.
}
}
I honestly hate answering my own questions on here, but I was actually able to find someone else on the QT forum that had the same problem. That is here https://forum.qt.io/topic/42464/qplaintextedit-eats-line-endings . Using the information from this post and a little tweak, I was able not only to save the files with the proper Windows "line-ending", but I was also able to save the files with the proper encoding. The text in QTextEdit
is saved to a Qstring
. The .replace
function of Qstring
is then used to change the line ending from \n
to \r\n
. The QTextStream
encoding is then set (or not if it is plain text), and the Qstring
is streamed to the QTextStream
. The QTextStream
is then sent to the file. Saving and manipulation of the Qstring
is done before the encoding if
statements to cut down on the amount of code that is needed.
Here is the full save function.
void MainWindow::on_actionSave_triggered() // Saves the file
{
if (!saveFile.isEmpty())
{
QString wSave;
QFile file(saveFile);
wSave = ui->textEdit->toPlainText();
wSave.replace("\n", "\r\n");
wSave.replace("\r\r\n", "\r\n");
if (!file.open(QIODevice::WriteOnly)) // This if statement makes sure that the file can be written to.
{
// error message
}
else
{
QTextStream stream(&file); // Prepares the file to receive the QTextStream
if (encodeString == "Plain Text") //The next set of "if" statements set the encoding that the file will be saved in. This is set by the combo box in the text editor.
{
qDebug() << wSave;
stream << wSave;
stream.flush();
file.close();
}
if (encodeString == "UTF-8")
{
stream.setCodec("UTF-8");
stream.setGenerateByteOrderMark(true);
stream << wSave;
stream.flush();
file.close();
}
if (encodeString == "UTF-16")
{
stream.setCodec("UTF-16");
stream.setGenerateByteOrderMark(true);
stream << wSave;
stream.flush();
file.close();
}
if (encodeString == "UTF-16BE")
{
stream.setCodec("UTF-16BE");
stream.setGenerateByteOrderMark(true);
stream << wSave;
stream.flush();
file.close();
}
if (encodeString == "UTF-32")
{
stream.setCodec("UTF-32");
stream.setGenerateByteOrderMark(true);
stream << wSave;
stream.flush();
file.close();
}
if (encodeString == "UTF-32BE")
{
stream.setCodec("UTF-32BE");
stream.setGenerateByteOrderMark(true);
stream << wSave;
stream.flush();
file.close();
}
}
}
}