21 connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::openModel); |
21 connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::openModel); |
22 connect(ui->actionQuit, &QAction::triggered, this, &QMainWindow::close); |
22 connect(ui->actionQuit, &QAction::triggered, this, &QMainWindow::close); |
23 connect(ui->actionSettingsEditor, &QAction::triggered, this, &MainWindow::runSettingsEditor); |
23 connect(ui->actionSettingsEditor, &QAction::triggered, this, &MainWindow::runSettingsEditor); |
24 this->updateTitle(); |
24 this->updateTitle(); |
25 this->restoreSettings(); |
25 this->restoreSettings(); |
|
26 this->newModel(); |
26 } |
27 } |
27 |
28 |
28 MainWindow::~MainWindow() |
29 MainWindow::~MainWindow() |
29 { |
30 { |
30 } |
31 } |
31 |
32 |
32 void MainWindow::newModel() |
33 void MainWindow::newModel() |
33 { |
34 { |
34 documents.newModel(); |
35 this->openModelForEditing(documents.newModel()); |
35 this->updateTabs(); |
|
36 } |
36 } |
37 |
37 |
38 void MainWindow::openModel() |
38 void MainWindow::openModel() |
39 { |
39 { |
40 const QString path = QFileDialog::getOpenFileName( |
40 const QString path = QFileDialog::getOpenFileName( |
42 tr("Open model"), |
42 tr("Open model"), |
43 "", |
43 "", |
44 tr("LDraw models (*.ldr *.dat)")); |
44 tr("LDraw models (*.ldr *.dat)")); |
45 if (not path.isEmpty()) |
45 if (not path.isEmpty()) |
46 { |
46 { |
47 QString errorString; |
47 this->openModelFromPath(path); |
48 QTextStream errorStream{&errorString}; |
48 } |
49 QString modelName = this->documents.openModel(path, errorStream); |
49 } |
50 if (not modelName.isEmpty()) |
50 |
51 { |
51 void MainWindow::openModelFromPath(const QString& path) |
52 Document* document = new Document{this->documents.findModelByName(modelName)}; |
52 { |
53 this->ui->tabs->addTab(document, modelName); |
53 QString errorString; |
54 } |
54 QTextStream errorStream{&errorString}; |
55 else |
55 QString modelName = this->documents.openModel(path, errorStream); |
56 { |
56 if (not modelName.isEmpty()) |
57 const QString errorMessage = utility::format( |
57 { |
|
58 this->openModelForEditing(modelName); |
|
59 this->addRecentlyOpenedFile(path); |
|
60 } |
|
61 else |
|
62 { |
|
63 QMessageBox::critical( |
|
64 this, |
|
65 tr("Problem opening file"), |
|
66 utility::format( |
58 tr("Could not open %1: %2"), |
67 tr("Could not open %1: %2"), |
59 path, |
68 path, |
60 errorString); |
69 errorString)); |
61 QMessageBox::critical(this, tr("Problem opening file"), errorMessage); |
|
62 } |
|
63 } |
70 } |
64 } |
71 } |
65 |
72 |
66 /** |
73 /** |
67 * @brief Changes the application language to the specified language |
74 * @brief Changes the application language to the specified language |
84 qApp->installTranslator(&this->translator); |
91 qApp->installTranslator(&this->translator); |
85 } |
92 } |
86 } |
93 } |
87 } |
94 } |
88 |
95 |
|
96 void MainWindow::addRecentlyOpenedFile(const QString& path) |
|
97 { |
|
98 this->recentlyOpenedFiles.removeAll(path); |
|
99 this->recentlyOpenedFiles.insert(0, path); |
|
100 while (this->recentlyOpenedFiles.size() > maxRecentlyOpenedFiles) |
|
101 { |
|
102 this->recentlyOpenedFiles.removeLast(); |
|
103 } |
|
104 this->saveSettings(); |
|
105 this->updateRecentlyOpenedDocumentsMenu(); |
|
106 } |
|
107 |
|
108 void MainWindow::openModelForEditing(const QString& modelName) |
|
109 { |
|
110 Document* document = new Document{this->documents.findModelByName(modelName)}; |
|
111 this->ui->tabs->addTab(document, modelName); |
|
112 this->ui->tabs->setCurrentWidget(document); |
|
113 document->restoreSplitterState(this->documentSplitterState); |
|
114 connect(document, &Document::splitterChanged, this, &MainWindow::handleDocumentSplitterChange); |
|
115 } |
|
116 |
89 void MainWindow::runSettingsEditor() |
117 void MainWindow::runSettingsEditor() |
90 { |
118 { |
91 SettingsEditor settingsEditor{&this->settings, this}; |
119 SettingsEditor settingsEditor{&this->settings, this}; |
92 const int result = settingsEditor.exec(); |
120 const int result = settingsEditor.exec(); |
93 if (result == QDialog::Accepted) |
121 if (result == QDialog::Accepted) |
94 { |
122 { |
95 this->restoreSettings(); |
123 this->restoreSettings(); |
|
124 } |
|
125 } |
|
126 |
|
127 void MainWindow::handleDocumentSplitterChange() |
|
128 { |
|
129 Document* currentDocument = qobject_cast<Document*>(this->ui->tabs->currentWidget()); |
|
130 if (currentDocument != nullptr) |
|
131 { |
|
132 this->documentSplitterState = currentDocument->saveSplitterState(); |
|
133 for (int i = 0; i < this->ui->tabs->count(); i += 1) |
|
134 { |
|
135 Document* document = qobject_cast<Document*>(this->ui->tabs->widget(i)); |
|
136 if (document != nullptr and document != currentDocument) |
|
137 { |
|
138 document->restoreSplitterState(this->documentSplitterState); |
|
139 } |
|
140 } |
|
141 this->settings.setValue("MainWindow/DocumentSplitterState", this->documentSplitterState); |
|
142 } |
|
143 } |
|
144 |
|
145 void MainWindow::updateRecentlyOpenedDocumentsMenu() |
|
146 { |
|
147 this->ui->menuRecentFiles->clear(); |
|
148 for (const QString& path : this->recentlyOpenedFiles) |
|
149 { |
|
150 QAction* action = new QAction{path, this}; |
|
151 action->setData(path); |
|
152 this->ui->menuRecentFiles->addAction(action); |
|
153 connect(action, &QAction::triggered, this, &MainWindow::openRecentFile); |
|
154 } |
|
155 } |
|
156 |
|
157 void MainWindow::openRecentFile() |
|
158 { |
|
159 QAction* action = qobject_cast<QAction*>(this->sender()); |
|
160 if (action != nullptr) |
|
161 { |
|
162 const QString path = action->data().toString(); |
|
163 this->openModelFromPath(path); |
96 } |
164 } |
97 } |
165 } |
98 |
166 |
99 void MainWindow::changeEvent(QEvent* event) |
167 void MainWindow::changeEvent(QEvent* event) |
100 { |
168 { |
121 saveSettings(); |
189 saveSettings(); |
122 event->accept(); |
190 event->accept(); |
123 } |
191 } |
124 |
192 |
125 /** |
193 /** |
126 * @brief Creates a new tab widget for the specified model. |
|
127 * @param model Model to get a new tab widget for |
|
128 * @return widget |
|
129 */ |
|
130 QWidget* MainWindow::createWidgetForModel(Model* model) |
|
131 { |
|
132 Q_UNUSED(model); |
|
133 QWidget* widget = new QWidget(ui->tabs); |
|
134 QLabel* label = new QLabel("asdf", widget); |
|
135 QVBoxLayout* layout = new QVBoxLayout; |
|
136 layout->addWidget(label); |
|
137 widget->setLayout(layout); |
|
138 return widget; |
|
139 } |
|
140 |
|
141 /** |
|
142 * @brief Gets a tab widget for the specified model. If it does not exist, |
|
143 * it will be created. |
|
144 * @param model Model to get a tab widget for |
|
145 * @return widget |
|
146 */ |
|
147 QWidget* MainWindow::getWidgetForModel(Model* model) |
|
148 { |
|
149 QWidget* widget = this->modelWidgets.value(model); |
|
150 if (widget == nullptr) |
|
151 { |
|
152 QWidget* const new_widget = createWidgetForModel(model); |
|
153 this->modelWidgets[model] = new_widget; |
|
154 return new_widget; |
|
155 } |
|
156 else |
|
157 { |
|
158 return widget; |
|
159 } |
|
160 } |
|
161 |
|
162 /** |
|
163 * @brief Updates the tab widget |
|
164 */ |
|
165 void MainWindow::updateTabs() |
|
166 { |
|
167 |
|
168 } |
|
169 |
|
170 /** |
|
171 * @brief Updates the title of the main window so to contain the app's name |
194 * @brief Updates the title of the main window so to contain the app's name |
172 * and version as well as the open document name. |
195 * and version as well as the open document name. |
173 */ |
196 */ |
174 void MainWindow::updateTitle() |
197 void MainWindow::updateTitle() |
175 { |
198 { |
182 /** |
205 /** |
183 * @brief Stores the settings of the main window, storing geometry, etc |
206 * @brief Stores the settings of the main window, storing geometry, etc |
184 */ |
207 */ |
185 void MainWindow::saveSettings() |
208 void MainWindow::saveSettings() |
186 { |
209 { |
187 this->settings.setValue("mainwindow/geometry", this->saveGeometry()); |
210 this->settings.setValue("MainWindow/Geometry", this->saveGeometry()); |
|
211 this->settings.setValue("MainWindow/RecentlyOpened", this->recentlyOpenedFiles); |
|
212 this->settings.setValue("MainWindow/DocumentSplitterState", this->documentSplitterState); |
188 this->libraries.storeToSettings(&this->settings); |
213 this->libraries.storeToSettings(&this->settings); |
189 } |
214 } |
190 |
215 |
191 /** |
216 /** |
192 * @brief Restores saved settings relating to the main window |
217 * @brief Restores saved settings relating to the main window |
193 */ |
218 */ |
194 void MainWindow::restoreSettings() |
219 void MainWindow::restoreSettings() |
195 { |
220 { |
196 this->restoreGeometry(this->settings.value("mainwindow/geometry").toByteArray()); |
221 this->restoreGeometry(this->settings.value("MainWindow/Geometry").toByteArray()); |
|
222 this->recentlyOpenedFiles = this->settings.value("MainWindow/RecentlyOpened").toStringList(); |
|
223 this->documentSplitterState = this->settings.value("MainWindow/DocumentSplitterState").toByteArray(); |
197 const QString systemLocale = QLocale::system().name(); |
224 const QString systemLocale = QLocale::system().name(); |
198 const QVariant defaultLocale = this->settings.value("locale", systemLocale); |
225 const QVariant defaultLocale = this->settings.value("locale", systemLocale); |
199 changeLanguage(defaultLocale.toString()); |
226 changeLanguage(defaultLocale.toString()); |
200 this->libraries.restoreFromSettings(&this->settings); |
227 this->libraries.restoreFromSettings(&this->settings); |
|
228 this->updateRecentlyOpenedDocumentsMenu(); |
201 } |
229 } |
202 |
230 |
203 QString MainWindow::pathToTranslation(const QString& localeCode) |
231 QString MainWindow::pathToTranslation(const QString& localeCode) |
204 { |
232 { |
205 QDir dir {":/locale"}; |
233 QDir dir {":/locale"}; |