4.3 Le fichier TextEditor.cpp

Maintenant écrivons le fichier TextEditor.cpp.

Du côté du constructeur et du destructeur, rien n'a changé :

1
2
3
4
5
6
7
8
9
10
11
12
#include "TextEditor.h"
#include <QtGui/QFileDialog>

TextEditor::TextEditor()
	:QMainWindow()
{
	initialisationTextEditor();
}

TextEditor::~TextEditor(){
	
}

Heu si, en fait.

Alors, la classe QFileDialog permet d'aller chercher des fichiers à ouvrir ou à enregistrer (vous savez, la fenêtre qui s'ouvre pour vous permettre de choisir un fichier, c'est celle-la.

Et pourquoi on la met dans le fichier .cpp et pas .h ?

Là encore c'est une convention (mais pas la mienne pour une fois), qui consiste à mettre les includes des déclarations des attributs dans le .h et les includes utile au fonctionnement du programme dans le .cpp, ça permet de ne pas surcharger le .h avec des includes dans tout les sens. Bien sur, comme toutes les conventions vous n'êtes pas obliger de le faire.

Mais alors, ça veut dire que les fichiers stdio.h, sdlib.h et string devraient être dans le .cpp.

Exactement, mais pour ceux là je fait une exception, ça évite de les inclure tout le temps.

Bon, regardons la fonction d'initialisation :

1
2
3
4
5
6
7
8
9
void TextEditor::initialisationTextEditor(){
	QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
        QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
	
	initialisationActionTextEditor();
	initialisationMenuTextEditor();
	initialisationWidgetTextEditor();
	p_lastFileOpen = "";
}

La fonction qui initialise les QActions :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void TextEditor::initialisationActionTextEditor(){
	p_actionQuitter = new QAction("Quitter", this);
	connect(p_actionQuitter, SIGNAL(triggered()), SLOT(close()));
	
	p_actionOuvrir = new QAction("Ouvrir", this);
	p_actionOuvrir->setShortcut(tr("Ctrl+O"));
	connect(p_actionOuvrir, SIGNAL(triggered()), this, SLOT(ouvrir()));
	
	p_actionEnregistrer = new QAction("Enregistrer", this);
	p_actionEnregistrer->setShortcut(tr("Ctrl+S"));
	connect(p_actionEnregistrer, SIGNAL(triggered()), this, SLOT(enregistrer()));
	
	p_actionEnregistrerSous = new QAction("Enregistrer-sous", this);
	connect(p_actionEnregistrerSous, SIGNAL(triggered()), this, SLOT(enregistrerSous()));
}

Au passage je vous montre comment ajouter un raccourci à une QAction, on ne peut pas en ajouter ailleurs que sur une QAction.

La fonction qui initialise les QMenus :

1
2
3
4
5
6
7
8
void TextEditor::initialisationMenuTextEditor(){
	QMenu *menuFichier = menuBar()->addMenu("Fichiers");
		menuFichier->addAction(p_actionOuvrir);
		menuFichier->addAction(p_actionEnregistrer);
		menuFichier->addAction(p_actionEnregistrerSous);
		menuFichier->addSeparator();
		menuFichier->addAction(p_actionQuitter);
}

Les raccourcis ne sont pas pris en compte si la QAction n'est pas rajouté dans un menu.

La fonction qui initialise les QWidgets

1
2
3
4
5
6
7
8
9
10
11
void TextEditor::initialisationWidgetTextEditor(){
	p_textEditor = new QTextEdit;
	
	QVBoxLayout * mainLayout = new QVBoxLayout;
	mainLayout->addWidget(p_textEditor);
	
	p_mainWidget = new QWidget;
	p_mainWidget->setLayout(mainLayout);
	
	setCentralWidget(p_mainWidget);
}

C'est comme avec notre bouton.

La fonction qui enregistre un fichier :

1
2
3
4
5
6
7
void TextEditor::saveFile(const QString & fileName){
	FILE * fp = fopen(fileName.toStdString().c_str(), "w");
	if(fp == NULL) return;
	fprintf(fp, "%s", p_textEditor->toPlainText().toStdString().c_str());
	fclose(fp);
	p_lastFileOpen = fileName;
}

La fonction qui ouvre un fichier :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void TextEditor::openFile(const QString & fileName){
	FILE * fp = fopen(fileName.toStdString().c_str(), "r");
	if(fp == NULL) return;
	std::string fileContent("");
	int currentChar;
	while(!feof(fp)){
		currentChar = fgetc(fp);
		if(currentChar != EOF){
			fileContent += (char)currentChar;
		}
	}
	fclose(fp);
	p_lastFileOpen = fileName;
	p_textEditor->setText(fileContent.c_str());
}

Vous voyer l'utilité de la std::string ?

Si vous n'êtes pas convaincus, changer la std::string en QString et ouvrez un fichier en utf-8 contenant des caractères accentués.

Enfin nos trois slots privés :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void TextEditor::ouvrir(){
	QString fichier(QFileDialog::getOpenFileName(this, "Ouvrir un fichier", p_lastFileOpen, "Text (*)"));
	if(fichier == "") return;
	openFile(fichier);
}

void TextEditor::enregistrer(){
	if(p_lastFileOpen == ""){
		QString fileName(QFileDialog::getSaveFileName(this, "Enregistrer un fichier", QString(), "Text (*)"));
		if(fileName == "") return;
		p_lastFileOpen = fileName;
	}
	saveFile(p_lastFileOpen);
}

void TextEditor::enregistrerSous(){
	QString fileName(QFileDialog::getSaveFileName(this, "Enregistrer un fichier sous", p_lastFileOpen, "Text (*)"));
	if(fileName == "") return;
	saveFile(fileName);
}

Et l'inclusion du fichier .moc :

1
#include "TextEditor.moc"

Et voilà ce que ça donne en entier :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "TextEditor.h"

#include <QtGui/QFileDialog>

//////////////////////////////////////////////////////////
//                                                      //
//         Fonctions publiques de  TextEditor           //
//                                                      //
//////////////////////////////////////////////////////////

TextEditor::TextEditor()
	:QMainWindow()
{
	initialisationTextEditor();
}

TextEditor::~TextEditor(){
	
}

//////////////////////////////////////////////////////////
//                                                      //
//          Fonctions privées de  TextEditor            //
//                                                      //
//////////////////////////////////////////////////////////

void TextEditor::initialisationTextEditor(){
	QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
        QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
	
	initialisationActionTextEditor();
	initialisationMenuTextEditor();
	initialisationWidgetTextEditor();
	p_lastFileOpen = "";
}

void TextEditor::initialisationActionTextEditor(){
	p_actionQuitter = new QAction("Quitter", this);
	connect(p_actionQuitter, SIGNAL(triggered()), SLOT(close()));
	
	p_actionOuvrir = new QAction("Ouvrir", this);
	p_actionOuvrir->setShortcut(tr("Ctrl+O"));
	connect(p_actionOuvrir, SIGNAL(triggered()), this, SLOT(ouvrir()));
	
	p_actionEnregistrer = new QAction("Enregistrer", this);
	p_actionEnregistrer->setShortcut(tr("Ctrl+S"));
	connect(p_actionEnregistrer, SIGNAL(triggered()), this, SLOT(enregistrer()));
	
	p_actionEnregistrerSous = new QAction("Enregistrer-sous", this);
	connect(p_actionEnregistrerSous, SIGNAL(triggered()), this, SLOT(enregistrerSous()));
}

void TextEditor::initialisationMenuTextEditor(){
	QMenu *menuFichier = menuBar()->addMenu("Fichiers");
		menuFichier->addAction(p_actionOuvrir);
		menuFichier->addAction(p_actionEnregistrer);
		menuFichier->addAction(p_actionEnregistrerSous);
		menuFichier->addSeparator();
		menuFichier->addAction(p_actionQuitter);
}

void TextEditor::initialisationWidgetTextEditor(){
	p_textEditor = new QTextEdit;
	
	QVBoxLayout * mainLayout = new QVBoxLayout;
	mainLayout->addWidget(p_textEditor);
	
	p_mainWidget = new QWidget;
	p_mainWidget->setLayout(mainLayout);
	
	setCentralWidget(p_mainWidget);
}

void TextEditor::saveFile(const QString & fileName){
	FILE * fp = fopen(fileName.toStdString().c_str(), "w");
	if(fp == NULL) return;
	fprintf(fp, "%s", p_textEditor->toPlainText().toStdString().c_str());
	fclose(fp);
	p_lastFileOpen = fileName;
}

void TextEditor::openFile(const QString & fileName){
	FILE * fp = fopen(fileName.toStdString().c_str(), "r");
	if(fp == NULL) return;
	std::string fileContent("");
	int currentChar;
	while(!feof(fp)){
		currentChar = fgetc(fp);
		if(currentChar != EOF){
			fileContent += (char)currentChar;
		}
	}
	fclose(fp);
	p_lastFileOpen = fileName;
	p_textEditor->setText(fileContent.c_str());
}

//////////////////////////////////////////////////////////
//                                                      //
//             Slots privés de  TextEditor              //
//                                                      //
//////////////////////////////////////////////////////////


void TextEditor::ouvrir(){
	QString fichier(QFileDialog::getOpenFileName(this, "Ouvrir un fichier", p_lastFileOpen, "Text (*)"));
	if(fichier == "") return;
	openFile(fichier);
}

void TextEditor::enregistrer(){
	if(p_lastFileOpen == ""){
		QString fileName(QFileDialog::getSaveFileName(this, "Enregistrer un fichier", QString(), "Text (*)"));
		if(fileName == "") return;
		p_lastFileOpen = fileName;
	}
	saveFile(p_lastFileOpen);
}

void TextEditor::enregistrerSous(){
	QString fileName(QFileDialog::getSaveFileName(this, "Enregistrer un fichier sous", p_lastFileOpen, "Text (*)"));
	if(fileName == "") return;
	saveFile(fileName);
}



#include "TextEditor.moc"

Bien, passons au fichier main.cpp.