11
11
#include < iostream>
12
12
#include < fstream>
13
13
14
+
14
15
FileManager::FileManager (CodeEditor *editor, MainWindow *mainWindow)
15
16
: m_editor(editor), m_mainWindow(mainWindow)
16
17
{
@@ -23,6 +24,8 @@ void FileManager::initialize(CodeEditor *editor, MainWindow *mainWindow)
23
24
{
24
25
m_editor = editor;
25
26
m_mainWindow = mainWindow;
27
+
28
+ connect (m_editor, &QPlainTextEdit::textChanged, this , [this ](){m_isDirty = true ;});
26
29
}
27
30
28
31
QString FileManager::getCurrentFileName () const
@@ -35,65 +38,102 @@ void FileManager::setCurrentFileName(const QString fileName)
35
38
m_currentFileName = fileName;
36
39
}
37
40
38
- void FileManager::newFile ( )
41
+ QString getLastSaved ( const QFileInfo& file )
39
42
{
40
- QString currentFileName = getCurrentFileName ();
41
- bool isFileSaved = !currentFileName.isEmpty ();
42
- bool isTextEditorEmpty = this ->m_editor ->toPlainText ().isEmpty ();
43
- // File has not been saved and the text editor is not empty
44
- if (!isFileSaved && !isTextEditorEmpty)
45
- {
46
- // Create box to prompt user to save changes to file
47
- QMessageBox promptBox;
48
- promptBox.setWindowTitle (" Save Current File" );
49
- promptBox.setText (" Would you like to save the file?" );
50
- promptBox.setStandardButtons (QMessageBox::Save | QMessageBox::Cancel);
51
- promptBox.setDefaultButton (QMessageBox::Save);
52
-
53
- int option = promptBox.exec ();
54
- // return if the user hit Cancel button
55
- if (option == QMessageBox::Cancel)
56
- {
57
- return ;
58
- }
43
+ const auto lastSaved = file.lastModified ();
44
+ const auto now = QDateTime::currentDateTime ();
45
+ const auto seconds = lastSaved.secsTo (now);
46
+
47
+ const int days = seconds / (60 * 60 * 24 );
48
+ if (days == 0 )
49
+ return " today" ;
50
+ if (days == 1 )
51
+ return " yesterday" ;
52
+
53
+ return QString::number (days) + " days ago" ;
54
+ }
59
55
60
- saveFile ();
56
+ bool FileManager::hasUnsavedChanges ()
57
+ {
58
+ if (!m_isDirty)
59
+ {
60
+ return false ;
61
61
}
62
- // File has been previously saved
63
- else if (isFileSaved)
62
+
63
+ // Additional safeguard if content still matches file on disk
64
+ if (!m_currentFileName.isEmpty ())
64
65
{
65
- // Read from saved file and compare to current file
66
- QFile file (currentFileName);
67
- if (!file.open (QIODevice::ReadOnly | QIODevice::Text))
68
- return ;
69
- QTextStream in (&file);
70
- QString savedFileContents = in.readAll ();
71
- file.close ();
72
- if (savedFileContents != this ->m_editor ->toPlainText ().trimmed ())
66
+ QFile file (m_currentFileName);
67
+ if (file.open (QIODevice::ReadOnly | QIODevice::Text))
73
68
{
74
- // Create box to prompt user to save changes to file
75
- QMessageBox promptBox;
76
- promptBox.setWindowTitle (" Changes Detected" );
77
- promptBox.setText (" Would you like to save the current changes to the file?" );
78
- promptBox.setStandardButtons (QMessageBox::Save | QMessageBox::Cancel);
79
- promptBox.setDefaultButton (QMessageBox::Save);
80
- int option = promptBox.exec ();
81
- // return if the user hit Cancel button
82
- if (option == QMessageBox::Cancel)
69
+ QTextStream in (&file);
70
+ QString diskContents = in.readAll ();
71
+ if (diskContents == m_editor->toPlainText ())
83
72
{
84
- return ;
73
+ m_isDirty = false ;
74
+ return false ;
85
75
}
86
- saveFile ();
87
76
}
88
77
}
89
78
79
+ return true ; // nothing changed
80
+ }
81
+
82
+ int FileManager::buildUnsavedChangesMessage () const
83
+ {
84
+ QString infoText = " Your changes will be lost if you don't save." ;
90
85
if (!m_currentFileName.isEmpty ())
91
86
{
92
- setCurrentFileName (" " );
93
- m_editor->clear ();
94
- m_mainWindow->setWindowTitle (" Code Astra ~ untitled" );
87
+ QFileInfo file (m_currentFileName);
88
+ if (file.exists ())
89
+ {
90
+ QString timeSinceSave = getLastSaved (file);
91
+ infoText = " The document has been modified. It was last edited " + timeSinceSave + " ." ;
92
+ }
95
93
}
96
-
94
+
95
+ QMessageBox promptBox;
96
+ promptBox.setWindowTitle (" Unsaved changes" );
97
+ promptBox.setText (" Would you like to save your changes?" );
98
+ promptBox.setInformativeText (infoText);
99
+ promptBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
100
+ promptBox.setDefaultButton (QMessageBox::Save);
101
+
102
+ return promptBox.exec ();
103
+ }
104
+
105
+ bool FileManager::promptUnsavedChanges ()
106
+ {
107
+ if (!hasUnsavedChanges ())
108
+ {
109
+ return true ;
110
+ }
111
+
112
+ int option = buildUnsavedChangesMessage ();
113
+ if (option == QMessageBox::Save)
114
+ {
115
+ saveFile ();
116
+ }
117
+ else if (option == QMessageBox::Cancel)
118
+ {
119
+ return false ;
120
+ }
121
+
122
+ // if discard selected, continue without saving.
123
+ return true ;
124
+ }
125
+
126
+ void FileManager::newFile ()
127
+ {
128
+ if (!promptUnsavedChanges ())
129
+ {
130
+ return ;
131
+ }
132
+
133
+ m_currentFileName = " " ;
134
+ m_editor->clear ();
135
+ m_mainWindow->setWindowTitle (" Untitle ~ Code Astra" );
136
+ m_isDirty = false ;
97
137
}
98
138
99
139
void FileManager::saveFile ()
@@ -104,7 +144,7 @@ void FileManager::saveFile()
104
144
return ;
105
145
}
106
146
107
- qDebug () << " Saving file:" << m_currentFileName;
147
+ // qDebug() << "Saving file:" << m_currentFileName;
108
148
109
149
QFile file (m_currentFileName);
110
150
if (!file.open (QFile::WriteOnly | QFile::Text))
@@ -125,6 +165,16 @@ void FileManager::saveFile()
125
165
}
126
166
file.close ();
127
167
168
+ if (m_mainWindow)
169
+ {
170
+ m_mainWindow->setWindowTitle (" CodeAstra ~ " + QFileInfo (m_currentFileName).fileName ());
171
+ }
172
+ else
173
+ {
174
+ qWarning () << " MainWindow is not initialized in FileManager." ;
175
+ }
176
+
177
+ m_isDirty = false ;
128
178
emit m_editor->statusMessageChanged (" File saved successfully." );
129
179
}
130
180
@@ -152,7 +202,7 @@ void FileManager::openFile()
152
202
" All Files (*);;C++ Files (*.cpp *.h);;Text Files (*.txt)" );
153
203
if (!fileName.isEmpty ())
154
204
{
155
- qDebug () << " Opening file: " << fileName;
205
+ // qDebug() << "Opening file: " << fileName;
156
206
m_currentFileName = fileName;
157
207
loadFileInEditor (fileName);
158
208
}
@@ -164,7 +214,8 @@ void FileManager::openFile()
164
214
165
215
void FileManager::loadFileInEditor (const QString &filePath)
166
216
{
167
- qDebug () << " Loading file:" << filePath;
217
+ // qDebug() << "Loading file:" << filePath;
218
+
168
219
QFile file (filePath);
169
220
if (!file.open (QIODevice::ReadOnly | QIODevice::Text))
170
221
{
@@ -175,7 +226,9 @@ void FileManager::loadFileInEditor(const QString &filePath)
175
226
QTextStream in (&file);
176
227
if (m_editor)
177
228
{
229
+ m_editor->blockSignals (true );
178
230
m_editor->setPlainText (in.readAll ());
231
+ m_editor->blockSignals (false );
179
232
180
233
delete m_currentHighlighter;
181
234
@@ -197,6 +250,8 @@ void FileManager::loadFileInEditor(const QString &filePath)
197
250
{
198
251
qWarning () << " MainWindow is not initialized in FileManager." ;
199
252
}
253
+
254
+ m_isDirty = false ;
200
255
}
201
256
202
257
QString FileManager::getFileExtension () const
@@ -296,6 +351,7 @@ OperationResult FileManager::deletePath(const QFileInfo &pathInfo)
296
351
{
297
352
return {false , " ERROR: invalid file path." + pathToDelete.filename ().string ()};
298
353
}
354
+
299
355
QString qPathToDelete = QString::fromStdString (pathToDelete.string ());
300
356
if (!QFile::moveToTrash (qPathToDelete))
301
357
{
@@ -330,7 +386,6 @@ OperationResult FileManager::newFile(const QFileInfo &pathInfo, QString newFileP
330
386
{
331
387
file.close ();
332
388
}
333
- qDebug () << " New file created." ;
334
389
335
390
FileManager::getInstance ().setCurrentFileName (QString::fromStdString (filePath.string ()));
336
391
return {true , filePath.filename ().string () + " created successfully." };
0 commit comments