Seite 1 von 1

TextEditor - Speicherproblem

Verfasst: 22. August 2008 19:15
von Roque
Hi,

in meinem TextEditor übernimmt folgende Methode (natürlich ausgelöst als Slot) das Speichern:

Code: Alles auswählen


void MainWindow::saveFile()
{	
	QString fileName = QFileDialog::getSaveFileName(this);

	if(fileName.isEmpty())					{
		return;
	}

	if(QFile::exists(fileName))				{
		QString bakName = fileName;

		bakName.append("~bak");										QFile::copy (fileName, bakName);
	}
	
	QFile file(fileName);

	if(!file.open(QIODevice::WriteOnly | QIODevice::Text))	
	{
		QMessageBox::warning(this, tr("Fehler beim Öffnen"),
			tr("Datei nicht in Datei schreiben %1: \n%2.")
			.arg(fileName).arg(file.errorString() ) );

		return;
	}

	file.write((editor ->toPlainText()).toAscii());				

	statusBar() ->showMessage(tr("Dokument erfolgreich gespeichert") );

	setWindowTitle(fileName);
}

1. Problem: Wie kann ich die Funktion dazu bringen, .txt Dateien auszugeben? Unter Windows werden in diesem Fall nur immer Typ-lose Dateien erzeugt...

2.Problem: der oben beschriebene Code führt ja "Speichern unter" aus. Wie würde die Implementierung nur für "Speichern" (in die selbe Datei) aussehen?

Sorry für die fehlerhafte Formatierung des Codes...

Danke für eure Hilfe!
Johannes

Verfasst: 22. August 2008 20:01
von upsala
1. Entweder pauschal die Endung, wenn sie nicht vorhanden ist, anhängen. Oder der Funktion mehr Parameter mitgeben und abhängig vom gewählten Filter die entsprechende Kennung anhängen.

2. Soll das eine Fangfrage sein?

Verfasst: 23. August 2008 11:09
von Roque
Zu 2.: Wieso Fangfrage? Es geht darum, Text im Editor unter dem gleichen Namen abzuspeichern - also ohne FileDialog die Datei überschreiben. Wie kann man das realisieren?

Verfasst: 23. August 2008 11:29
von Zonk
Du brauchst in der Software eine Variable "actualFilename" oder so ähnlich.
in ihr hinterlegst du den Dateiname..

Wenn du wss öfnest, hinterlegst du den Dateinamen beim Laden direkt in der Variable.

Wenn du ein neues Dokument editierst lässt du die Variable erstmal leer ( die solltest Anfangs ja ohnehin mit "" initialisieren ).


Wenn jemand "Speichern" klickt, und ein Dateiname hinterlegt ist: speichern.
Wenn jemand "Speichern" klickt und es ist KEIN Dateiname hinterlegt, dann musst du intern die Funktion von "Speichern unter" aufrufen.

Wenn jemand "Speichern unter" klickt, musst du den Filename mit Fildedialog erfragen, in "actualFilename" hinterlegen und dann die Funktion "Speichern" aufrufen.

Thats it :)

Verfasst: 23. August 2008 14:29
von Roque
@Zonk: vielen Dank für den Tipp! Hast du zu dem Vorgehen zufällig etwas Source-Code?

Verfasst: 23. August 2008 14:52
von Zonk
mope, icht in vorzeigbarer form.. ist halt in meinern klassen verstreut, das aufarbeiten mehr Zeit kostet als dich das erarbeiten ;)


so ind er Form:


hauptklasse:


bool myClass::save()
{
if ( filename != "" )
{
performSave( filename );
}
else
{
SaveAs();
}
}


bool myclass::SaveAs()
{
filename = QFileDialog::getSaveFileName( ..... );
if ( filename != NULL )
performSave( filename );
}

Verfasst: 24. August 2008 14:09
von Roque
Anhand Deines Schemas habe ich nun versucht, den Code nach dem Modell umzusetzen:

Im Konstruktor wird fileName = "" gesetzt.

Dann die Speicher-Methode:


void MainWindow::saveFile()
{
QFile file(fileName);

if(fileName != "")
{

file.write((editor ->toPlainText()).toAscii());
statusBar() ->showMessage(tr("Dokument erfolgreich gespeichert") );
setWindowTitle(fileName);

}

else
{
save_asFile();
}

}

void MainWindow::save_asFile()
{

QString fileName = QFileDialog::getSaveFileName(this, tr("Datei speichern unter..."), "", "Text - Dateien(*txt);;");

QFile file(fileName);

if(fileName.isEmpty()) //Diverse Fehler-Abfragen
{
return;
}

if(QFile::exists(fileName))
{
QString bakName = fileName;

bakName.append("~bak");
QFile::copy (fileName, bakName);
}

if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QMessageBox::warning(this, tr("Fehler beim Öffnen"),
tr("Datei nicht in Datei schreiben %1: \n%2.") .arg(fileName).arg(file.errorString() ) );

return;
}


file.write((editor ->toPlainText()).toAscii());
statusBar() ->showMessage(tr("Dokument erfolgreich gespeichert") );

setWindowTitle(fileName);
}


Probleme: 1. nach dem Aufruf von save_asFile wird aus irgendeinem Grund nichts in fileName reingeschrieben - d.h. ein erneutes Aufrufen der Save-Methode führt wieder zu save_asFile().

2. Wie kann ich beim Abspeichern die Datei-Endung .txt anhängen? Die Methode "produziert" nur Typlose Dateien...

Für ein paar Tipps wäre ich dankbar!

Grüße
Johannes

Verfasst: 24. August 2008 21:59
von upsala
1. Es gibt hier Tags für Code-Markierung
2. Um den Code lesbarer zu gestalten, erweist es sich als sinnvoll diesen einzurücken.
3. fileName ist bei dir teilweise eine lokale Variable
4. *txt trifft auf mehr zu als nur txt-Dateien
5. Das anhängen von Dateiendungen hatten wir schon mal besprochen. Die notwendigen Funktionen finden sich in der Doku zu QString.

Verfasst: 25. August 2008 00:27
von Roque
1.Die Tags habe ich zu Beginn verwendet (siehe oben), die Formatierung machte aber große Probleme.
2.Ok, werde ich in Zukunft beachten.
3.fileName wird im Konstruktor initialisiert und sollte demnach in allen Methoden gültig sein... der Code stammt so größtenteils aus einem Qt-Buch.
4.Was meinst du damit genau?
5.Werde dazu mal die Suche bemühen... Danke :)

Verfasst: 25. August 2008 08:46
von pfid
Korrigiert mich wenn ich falsch liege, aber

1) Man braucht man den Filename-String nicht mit "" zu initialisieren, da ein QString ohne Zuweisung/Initialisierung eh leer (null) ist
2) müsstest du dann allerdings nicht mit if (string == "") prüfen, sondern mit string.isEmpyt(), da ein QString() keinen Leerstring enthält.

wobei 2) imho in jedem Fall besser ist, da auf null und Leerstring geprüft wird.
Roque hat geschrieben:3.fileName wird im Konstruktor initialisiert und sollte demnach in allen Methoden gültig sein... der Code stammt so größtenteils aus einem Qt-Buch.

Code: Alles auswählen

void MainWindow::save_asFile()
{

QString fileName = QFileDialog::getSaveFileName(this, tr("Datei speichern unter..."), "", "Text - Dateien(*txt);;"); 
fileName ist eine lokale Variable.