1 #include <QDebug>
2 #include <QFileInfo>
3 #include <QFileDialog>
4 #include <QMessageBox>
5 #include "polfileeditorwindow.h"
6 #include "ui_polfileeditorwindow.h"
7 #include "mainwindow.h"
8 
9 using namespace xmpsolve;
10 
PolFileEditorWindow(QWidget * parent)11 PolFileEditorWindow::PolFileEditorWindow(QWidget *parent) :
12     QMainWindow(parent),
13     ui(new Ui::PolFileEditorWindow)
14 {
15     ui->setupUi(this);
16     setAttribute(Qt::WA_DeleteOnClose, true);
17 }
18 
19 void
showEvent(QShowEvent * event)20 PolFileEditorWindow::showEvent(QShowEvent *event)
21 {
22     Q_UNUSED(event);
23 
24     if (ui->tabWidget->count() == 0)
25         loadPolFile("");
26 }
27 
28 void
loadPolFile(QString path)29 PolFileEditorWindow::loadPolFile(QString path)
30 {
31     PolFileEditor * editor = NULL;
32     int currentIndex = 0;
33 
34     // We have 2 possibilities here:
35     // - path is a path to a file, and we open it
36     // - path is empty, and we have to create a new file
37     if (! path.isEmpty()) {
38         // Get the absolute path of the file to ensure an unique representation of each one.
39         QFileInfo info(path);
40         path = info.absoluteFilePath();
41         editor =  m_polFileEditors.value(path, NULL);
42     }
43 
44     if (editor == NULL) {
45         editor = new PolFileEditor(this, path);
46 
47         QObject::connect(editor, SIGNAL(filenameChanged(QString)),
48                          this, SLOT(onEditorFilenameChanged(QString)));
49 
50         if (! path.isEmpty())
51             m_polFileEditors.insert(path, editor);
52 
53         ui->tabWidget->insertTab(0, editor, QIcon::fromTheme("text"),
54                                  path.isEmpty() ? "New file" : path.split("/").last());
55         QObject::connect(editor, SIGNAL(stateChanged(PolFileEditor::State)),
56                          this, SLOT(onEditorStateChanged(PolFileEditor::State)));
57     }
58     else {
59         currentIndex = ui->tabWidget->indexOf(editor);
60     }
61 
62     ui->tabWidget->setCurrentIndex(currentIndex);
63 }
64 
65 void
savePolFile()66 PolFileEditorWindow::savePolFile()
67 {
68     PolFileEditor * editor = currentEditor();
69     editor->savePolFile();
70 }
71 
72 void
closePolFile(QString path)73 PolFileEditorWindow::closePolFile(QString path)
74 {
75     PolFileEditor * editor = m_polFileEditors.value(path, NULL);
76 
77     if (editor != NULL)
78         closeEditor(editor);
79 }
80 
81 void
closeEditor(PolFileEditor * editor)82 PolFileEditorWindow::closeEditor(PolFileEditor *editor)
83 {
84     QString filename = editor->currentPolFile();
85     if (filename.isEmpty())
86         filename = tr("this unsaved file");
87     else
88         m_polFileEditors.remove(filename);
89 
90 
91     if (editor->state() == PolFileEditor::MODIFIED) {
92         QMessageBox::StandardButton reply = QMessageBox::question(this,
93             tr("Save changes to %1 before closing?").arg(filename),
94             tr("%1 has been edited but no saved. Do you want to save it before closing it?").arg(
95                 filename),
96             QMessageBox::Yes|QMessageBox::No);
97 
98         if (reply == QMessageBox::Yes) {
99             editor->savePolFile();
100         }
101     }
102 
103     int editorIndex = ui->tabWidget->indexOf(editor);
104     ui->tabWidget->removeTab(editorIndex);
105 
106     delete editor;
107 
108     if (ui->tabWidget->count() == 0) {
109         loadPolFile();
110     }
111 }
112 
~PolFileEditorWindow()113 PolFileEditorWindow::~PolFileEditorWindow()
114 {
115     // Fake a close button press.
116     on_actionClose_editor_triggered();
117 
118     delete ui;
119 }
120 
onEditorFilenameChanged(QString newName)121 void PolFileEditorWindow::onEditorFilenameChanged(QString newName)
122 {
123     PolFileEditor *editor = static_cast<PolFileEditor*> (sender());
124     int editorIndex = ui->tabWidget->indexOf(editor);
125 
126     ui->tabWidget->setTabText(editorIndex, newName.split("/").last());
127 
128     // Find the old key and remove it. Then insert the new one.
129     QString oldKey = m_polFileEditors.key(editor, "");
130     if (! oldKey.isEmpty()) {
131         m_polFileEditors.remove(oldKey);
132     }
133 
134     m_polFileEditors.insert(newName, editor);
135 }
136 
onEditorStateChanged(PolFileEditor::State state)137 void PolFileEditorWindow::onEditorStateChanged(PolFileEditor::State state)
138 {
139     PolFileEditor *editor = static_cast<PolFileEditor*> (sender());
140     QString path = editor->currentPolFile();
141 
142     if (path.isEmpty()) {
143         path = "New file";
144     }
145     else {
146         path = path.split("/").last();
147     }
148 
149     int currentIndex = ui->tabWidget->indexOf(editor);
150 
151     switch (state) {
152         case PolFileEditor::SAVED:
153             ui->tabWidget->setTabText(currentIndex, path);
154             break;
155          case PolFileEditor::MODIFIED:
156             ui->tabWidget->setTabText(currentIndex, path + "*");
157             break;
158     }
159 }
160 
currentEditor()161 PolFileEditor* PolFileEditorWindow::currentEditor()
162 {
163     PolFileEditor * editor = static_cast<PolFileEditor*> (ui->tabWidget->currentWidget());
164     return editor;
165 }
166 
currentPolFile()167 QString PolFileEditorWindow::currentPolFile()
168 {
169     PolFileEditor * editor = currentEditor();
170     if (editor != NULL)
171         return editor->currentPolFile();
172     else
173         return QString();
174 }
175 
on_actionOpen_pol_file_triggered()176 void PolFileEditorWindow::on_actionOpen_pol_file_triggered()
177 {
178     QString path = QFileDialog::getOpenFileName(this, "Select .pol file", "", "Pol files (*.pol)");
179     loadPolFile(path);
180 }
181 
on_actionSave_triggered()182 void PolFileEditorWindow::on_actionSave_triggered()
183 {
184     savePolFile();
185 }
186 
on_actionSolve_triggered()187 void PolFileEditorWindow::on_actionSolve_triggered()
188 {
189     solvePoly(currentEditor()->content());
190 }
191 
on_actionClose_triggered()192 void PolFileEditorWindow::on_actionClose_triggered()
193 {
194     closeEditor(currentEditor());
195 }
196 
on_actionNew_triggered()197 void PolFileEditorWindow::on_actionNew_triggered()
198 {
199     loadPolFile();
200 }
201 
closeOpenedTabs()202 void PolFileEditorWindow::closeOpenedTabs()
203 {
204     // Close the pol files before so we can get notifications about
205     // unsaved files and so.
206     foreach (PolFileEditor* editor, m_polFileEditors) {
207         closePolFile(editor->currentPolFile());
208     }
209 
210     // We need to handle the opened tabs that have not been
211     // saved yet.
212     while (ui->tabWidget->count() > 0) {
213 
214         ui->tabWidget->setCurrentIndex(0);
215         PolFileEditor *editor = static_cast<PolFileEditor*>(ui->tabWidget->widget(0));
216 
217         if (editor->state() == PolFileEditor::MODIFIED) {
218 
219             int reply = QMessageBox::question(this, tr("Save changes to this file?"),
220                                               tr("This file has not been saved. Do you want to do it now?"),
221                                               QMessageBox::No, QMessageBox::Yes);
222             if (reply == QMessageBox::Yes) {
223                 QString path = QFileDialog::getSaveFileName(this, "Save .pol file", "", "Pol files (*.pol)");
224                 if (! path.isEmpty()) {
225                     editor->savePolFile(path);
226                 }
227             }
228 
229         }
230 
231         ui->tabWidget->removeTab(0);
232         delete editor;
233     }
234 }
235 
on_actionClose_editor_triggered()236 void PolFileEditorWindow::on_actionClose_editor_triggered()
237 {
238     closeOpenedTabs();
239     close();
240 }
241 
closeEvent(QCloseEvent * event)242 void PolFileEditorWindow::closeEvent(QCloseEvent *event)
243 {
244     Q_UNUSED(event);
245 
246     closeOpenedTabs();
247     close();
248 
249     this->destroy();
250 }
251