1 /*
2 SPDX-FileCopyrightText: 1997 Mathias Mueller <in5y158@public.uni-hamburg.de>
3 SPDX-FileCopyrightText: 2006 Mauricio Piacentini <mauricio@tabuleiro.com>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 // own
9 #include "editor.h"
10
11 // Qt
12 #include <QAction>
13 #include <QFileDialog>
14 #include <QFileInfo>
15 #include <QGridLayout>
16 #include <QIcon>
17 #include <QLabel>
18 #include <QPainter>
19 #include <QResizeEvent>
20
21 // KF
22 #include <KActionCollection>
23 #include <KLocalizedString>
24 #include <KMessageBox>
25 #include <KStandardAction>
26 #include <KToggleAction>
27
28 // KMahjongg
29 #include "prefs.h"
30
Editor(QWidget * parent)31 Editor::Editor(QWidget * parent)
32 : QDialog(parent)
33 , m_mode(EditMode::insert)
34 , m_borderLeft(0)
35 , m_borderTop(0)
36 , m_numTiles(0)
37 , m_clean(true)
38 , m_drawFrame(nullptr)
39 , m_tiles()
40 , m_theLabel(nullptr)
41 , m_topToolbar(nullptr)
42 , m_actionCollection(nullptr)
43 {
44 setModal(true);
45
46 QWidget * mainWidget = new QWidget(this);
47
48 QVBoxLayout * mainLayout = new QVBoxLayout(this);
49 mainLayout->addWidget(mainWidget);
50
51 resize(QSize(800, 400));
52
53 QGridLayout * gridLayout = new QGridLayout(mainWidget);
54 QVBoxLayout * layout = new QVBoxLayout();
55
56 setupToolbar();
57 layout->addWidget(m_topToolbar);
58
59 m_drawFrame = new FrameImage(this, QSize(0, 0));
60 m_drawFrame->setFocusPolicy(Qt::NoFocus);
61 m_drawFrame->setMouseTracking(true);
62
63 layout->addWidget(m_drawFrame);
64 gridLayout->addLayout(layout, 0, 0, 1, 1);
65
66 //toolbar will set our minimum height
67 setMinimumHeight(120);
68
69 // tell the user what we do
70 setWindowTitle(i18nc("@title:window", "Edit Board Layout"));
71
72 connect(m_drawFrame, &FrameImage::mousePressed, this, &Editor::drawFrameMousePressEvent);
73 connect(m_drawFrame, &FrameImage::mouseMoved, this, &Editor::drawFrameMouseMovedEvent);
74
75 statusChanged();
76
77 update();
78 }
79
~Editor()80 Editor::~Editor()
81 {
82 }
83
updateTileSize(const QSize size)84 void Editor::updateTileSize(const QSize size)
85 {
86 const int width = m_theBoard.getWidth();
87 const int height = m_theBoard.getHeight();
88 const QSize tileSize = m_tiles.preferredTileSize(size, width / 2, height / 2);
89
90 m_tiles.reloadTileset(tileSize);
91 m_borderLeft = (m_drawFrame->size().width() - (width * m_tiles.qWidth())) / 2;
92 m_borderTop = (m_drawFrame->size().height() - (height * m_tiles.qHeight())) / 2;
93 }
94
resizeEvent(QResizeEvent * event)95 void Editor::resizeEvent(QResizeEvent * event)
96 {
97 updateTileSize(event->size());
98 }
99
setupToolbar()100 void Editor::setupToolbar()
101 {
102 m_topToolbar = new KToolBar(QStringLiteral("editToolBar"), this);
103 m_topToolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
104
105 m_actionCollection = new KActionCollection(this);
106
107 // new game
108 QAction * newBoard = m_actionCollection->addAction(QStringLiteral("new_board"));
109 newBoard->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
110 newBoard->setText(i18n("New board"));
111 connect(newBoard, &QAction::triggered, this, &Editor::newBoard);
112 m_topToolbar->addAction(newBoard);
113
114 // open game
115 QAction * openBoard = m_actionCollection->addAction(QStringLiteral("open_board"));
116 openBoard->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
117 openBoard->setText(i18n("Open board"));
118 connect(openBoard, &QAction::triggered, this, &Editor::loadBoard);
119 m_topToolbar->addAction(openBoard);
120
121 // save game
122 QAction * saveBoard = m_actionCollection->addAction(QStringLiteral("save_board"));
123 saveBoard->setIcon(QIcon::fromTheme(QStringLiteral("document-save")));
124 saveBoard->setText(i18n("Save board"));
125 connect(saveBoard, &QAction::triggered, this, &Editor::saveBoard);
126 m_topToolbar->addAction(saveBoard);
127
128 m_topToolbar->addSeparator();
129
130 #ifdef FUTURE_OPTIONS
131 // Select
132 QAction * select = actionCollection->addAction(QLatin1String("select"));
133 select->setIcon(QIcon::fromTheme(QLatin1String("rectangle_select")));
134 select->setText(i18n("Select"));
135 topToolbar->addAction(select);
136
137 QAction * cut = actionCollection->addAction(QLatin1String("edit_cut"));
138 cut->setIcon(QIcon::fromTheme(QLatin1String("edit-cut")));
139 cut->setText(i18n("Cut"));
140 topToolbar->addAction(cut);
141
142 QAction * copy = actionCollection->addAction(QLatin1String("edit_copy"));
143 copy->setIcon(QIcon::fromTheme(QLatin1String("edit-copy")));
144 copy->setText(i18n("Copy"));
145 topToolbar->addAction(copy);
146
147 QAction * paste = actionCollection->addAction(QLatin1String("edit_paste"));
148 paste->setIcon(QIcon::fromTheme(QLatin1String("edit-paste")));
149 paste->setText(i18n("Paste"));
150 topToolbar->addAction(paste);
151
152 topToolbar->addSeparator();
153
154 QAction * moveTiles = actionCollection->addAction(QLatin1String("move_tiles"));
155 moveTiles->setIcon(QIcon::fromTheme(QLatin1String("move")));
156 moveTiles->setText(i18n("Move tiles"));
157 topToolbar->addAction(moveTiles);
158 #endif
159
160 KToggleAction * addTiles = new KToggleAction(QIcon::fromTheme(QStringLiteral("draw-freehand")), i18n("Add tiles"), this);
161 m_actionCollection->addAction(QStringLiteral("add_tiles"), addTiles);
162 m_topToolbar->addAction(addTiles);
163 KToggleAction * delTiles = new KToggleAction(QIcon::fromTheme(QStringLiteral("edit-delete")), i18n("Remove tiles"), this);
164 m_actionCollection->addAction(QStringLiteral("del_tiles"), delTiles);
165 m_topToolbar->addAction(delTiles);
166
167 QActionGroup * radioGrp = new QActionGroup(this);
168 radioGrp->setExclusive(true);
169 radioGrp->addAction(addTiles);
170 addTiles->setChecked(true);
171
172 #ifdef FUTURE_OPTIONS
173 radioGrp->addAction(moveTiles);
174 #endif
175
176 radioGrp->addAction(delTiles);
177 connect(radioGrp, &QActionGroup::triggered, this, &Editor::slotModeChanged);
178
179 // board shift
180
181 m_topToolbar->addSeparator();
182
183 // NOTE: maybe join shiftActions in QActionGroup and create one slot(QAction*) instead of 4 slots? ;)
184 // Does this makes sense? dimsuz
185 QAction * shiftLeft = m_actionCollection->addAction(QStringLiteral("shift_left"));
186 shiftLeft->setIcon(QIcon::fromTheme(QStringLiteral("go-previous")));
187 shiftLeft->setText(i18n("Shift left"));
188 connect(shiftLeft, &QAction::triggered, this, &Editor::slotShiftLeft);
189 m_topToolbar->addAction(shiftLeft);
190
191 QAction * shiftUp = m_actionCollection->addAction(QStringLiteral("shift_up"));
192 shiftUp->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
193 shiftUp->setText(i18n("Shift up"));
194 connect(shiftUp, &QAction::triggered, this, &Editor::slotShiftUp);
195 m_topToolbar->addAction(shiftUp);
196
197 QAction * shiftDown = m_actionCollection->addAction(QStringLiteral("shift_down"));
198 shiftDown->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
199 shiftDown->setText(i18n("Shift down"));
200 connect(shiftDown, &QAction::triggered, this, &Editor::slotShiftDown);
201 m_topToolbar->addAction(shiftDown);
202
203 QAction * shiftRight = m_actionCollection->addAction(QStringLiteral("shift_right"));
204 shiftRight->setIcon(QIcon::fromTheme(QStringLiteral("go-next")));
205 shiftRight->setText(i18n("Shift right"));
206 connect(shiftRight, &QAction::triggered, this, &Editor::slotShiftRight);
207 m_topToolbar->addAction(shiftRight);
208
209 m_topToolbar->addSeparator();
210 QAction * quit = m_actionCollection->addAction(KStandardAction::Quit, QStringLiteral("quit"));
211 connect(quit, &QAction::triggered, this, &Editor::close);
212 m_topToolbar->addAction(quit);
213
214 // status in the toolbar for now (ick)
215 QWidget * hbox = new QWidget(m_topToolbar);
216 QHBoxLayout * layout = new QHBoxLayout(hbox);
217 layout->setContentsMargins(0, 0, 0, 0);
218 layout->setSpacing(0);
219 layout->addStretch();
220
221 m_theLabel = new QLabel(statusText(), hbox);
222 layout->addWidget(m_theLabel);
223 m_topToolbar->addWidget(hbox);
224
225 m_topToolbar->adjustSize();
226 setMinimumWidth(m_topToolbar->width());
227 }
228
statusChanged() const229 void Editor::statusChanged() const
230 {
231 const bool canSave = ((m_numTiles != 0) && ((m_numTiles & 1) == 0));
232 m_theLabel->setText(statusText());
233 m_actionCollection->action(QStringLiteral("save_board"))->setEnabled(canSave);
234 }
235
slotShiftLeft()236 void Editor::slotShiftLeft()
237 {
238 m_theBoard.shiftLeft();
239 update();
240 }
241
slotShiftRight()242 void Editor::slotShiftRight()
243 {
244 m_theBoard.shiftRight();
245 update();
246 }
247
slotShiftUp()248 void Editor::slotShiftUp()
249 {
250 m_theBoard.shiftUp();
251 update();
252 }
253
slotShiftDown()254 void Editor::slotShiftDown()
255 {
256 m_theBoard.shiftDown();
257 update();
258 }
259
slotModeChanged(QAction * act)260 void Editor::slotModeChanged(QAction * act)
261 {
262 if (act == m_actionCollection->action(QStringLiteral("move_tiles"))) {
263 m_mode = EditMode::move;
264 } else if (act == m_actionCollection->action(QStringLiteral("del_tiles"))) {
265 m_mode = EditMode::remove;
266 } else if (act == m_actionCollection->action(QStringLiteral("add_tiles"))) {
267 m_mode = EditMode::insert;
268 }
269 }
270
statusText() const271 QString Editor::statusText() const
272 {
273 int x = m_curPos.x;
274 int y = m_curPos.y;
275 int z = m_curPos.z;
276
277 if (z == 100) {
278 z = 0;
279 } else {
280 z = z + 1;
281 }
282
283 if (x >= m_theBoard.getWidth() || x < 0 || y >= m_theBoard.getHeight() || y < 0) {
284 x = y = z = 0;
285 }
286
287 return i18n("Tiles: %1 Pos: %2,%3,%4", m_numTiles, x, y, z);
288 }
289
loadBoard()290 void Editor::loadBoard()
291 {
292 if (!testSave()) {
293 return;
294 }
295
296 const QString filename = QFileDialog::getOpenFileName(this, i18n("Open Board Layout"), QString(),
297 i18n("Board Layout (*.layout);;All Files (*)"));
298
299 if (filename.isEmpty()) {
300 return;
301 }
302
303 m_theBoard.loadBoardLayout(filename);
304 update();
305 }
306
newBoard()307 void Editor::newBoard()
308 {
309 // Clear out the contents of the board. Repaint the screen
310 // set values to their defaults.
311
312 if (!testSave()) {
313 return;
314 }
315
316 m_theBoard.clearBoardLayout();
317
318 m_clean = true;
319 m_numTiles = 0;
320
321 statusChanged();
322 update();
323 }
324
saveBoard()325 bool Editor::saveBoard()
326 {
327 if (!((m_numTiles != 0) && ((m_numTiles & 1) == 0))) {
328 KMessageBox::sorry(this, i18n("You can only save with a even number of tiles."));
329
330 return false;
331 }
332
333 // get a save file name
334 const QString filename = QFileDialog::getSaveFileName(this, i18n("Save Board Layout"), QString(),
335 i18n("Board Layout (*.layout);;All Files (*)"));
336
337 if (filename.isEmpty()) {
338 return false;
339 }
340
341 const QFileInfo f(filename);
342 if (f.exists()) {
343 // if it already exists, query the user for replacement
344 int res = KMessageBox::warningContinueCancel(this,
345 i18n("A file with that name already exists. Do you wish to overwrite it?"),
346 i18n("Save Board Layout"), KStandardGuiItem::save());
347
348 if (res != KMessageBox::Continue) {
349 return false;
350 }
351 }
352
353 bool result = m_theBoard.saveBoardLayout(filename);
354
355 if (result == true) {
356 m_clean = true;
357
358 return true;
359 } else {
360 return false;
361 }
362 }
363
testSave()364 bool Editor::testSave()
365 {
366 // test if a save is required and return true if the app is to continue
367 // false if cancel is selected. (if ok then call out to save the board
368
369 if (m_clean) {
370 return true;
371 }
372
373 const int res = KMessageBox::warningYesNoCancel(this,
374 i18n("The board has been modified. Would you like to save the changes?"),
375 QString(), KStandardGuiItem::save(), KStandardGuiItem::dontSave());
376
377 if (res == KMessageBox::Yes) {
378 // yes to save
379 if (saveBoard()) {
380 return true;
381 } else {
382 KMessageBox::sorry(this, i18n("Save failed. Aborting operation."));
383
384 return false;
385 }
386 } else {
387 return (res != KMessageBox::Cancel);
388 }
389 return true;
390 }
391
paintEvent(QPaintEvent *)392 void Editor::paintEvent(QPaintEvent *)
393 {
394 // The main paint event, draw in the grid and blit in
395 // the tiles as specified by the layout.
396
397 // first we layer on a background grid
398 QPixmap buff;
399 QPixmap * dest = m_drawFrame->getPreviewPixmap();
400 buff = QPixmap(dest->width(), dest->height());
401 drawBackground(&buff);
402 drawTiles(&buff);
403 QPainter p(dest);
404 p.drawPixmap(0, 0, buff);
405 p.end();
406
407 m_drawFrame->update();
408 }
409
drawBackground(QPixmap * pixmap) const410 void Editor::drawBackground(QPixmap * pixmap) const
411 {
412 const int width = m_theBoard.getWidth();
413 const int height = m_theBoard.getHeight();
414 QPainter p(pixmap);
415
416 // blast in a white background
417 p.fillRect(0, 0, pixmap->width(), pixmap->height(), Qt::white);
418
419 // now put in a grid of tile quarter width squares
420 for (int y = 0; y <= height; ++y) {
421 int nextY = m_borderTop + (y * m_tiles.qHeight());
422 p.drawLine(m_borderLeft, nextY, m_borderLeft + (width * m_tiles.qWidth()), nextY);
423 }
424
425 for (int x = 0; x <= width; ++x) {
426 int nextX = m_borderLeft + (x * m_tiles.qWidth());
427 p.drawLine(nextX, m_borderTop, nextX, m_borderTop + (height * m_tiles.qHeight()));
428 }
429 }
430
drawTiles(QPixmap * dest)431 void Editor::drawTiles(QPixmap * dest)
432 {
433 QPainter p(dest);
434
435 const int width = m_theBoard.getWidth();
436 const int height = m_theBoard.getHeight();
437 const int depth = m_theBoard.getDepth();
438 const int shadowX = m_tiles.width() - m_tiles.qWidth() * 2 - m_tiles.levelOffsetX();
439 const int shadowY = m_tiles.height() - m_tiles.qHeight() * 2 - m_tiles.levelOffsetY();
440 short tile = 0;
441
442 int xOffset = -shadowX;
443 int yOffset = -m_tiles.levelOffsetY();
444
445 // we iterate over the depth stacking order. Each successive level is
446 // drawn one indent up and to the right. The indent is the width
447 // of the 3d relief on the tile left (tile shadow width)
448 for (int z = 0; z < depth; ++z) {
449 // we draw down the board so the tile below over rights our border
450 for (int y = 0; y < height; ++y) {
451 // drawing right to left to prevent border overwrite
452 for (int x = width - 1; x >= 0; --x) {
453 int sx = x * m_tiles.qWidth() + xOffset + m_borderLeft;
454 int sy = y * m_tiles.qHeight() + yOffset + m_borderTop;
455
456 if (m_theBoard.getBoardData(z, y, x) != '1') {
457 continue;
458 }
459
460 QPixmap t;
461 tile = (z * depth) + (y * height) + (x * width);
462 t = m_tiles.unselectedTile(0);
463
464 // Only one complication. Since we render top to bottom , left
465 // to right situations arise where...:
466 // there exists a tile one q height above and to the left
467 // in this situation we would draw our top left border over it
468 // we simply split the tile draw so the top half is drawn
469 // minus border
470 if ((x > 1) && (y > 0) && m_theBoard.getBoardData(z, y - 1, x - 2) == '1') {
471 p.drawPixmap(sx, sy, t, 0, 0, t.width(), t.height());
472
473 p.drawPixmap(sx - m_tiles.qWidth() + shadowX + m_tiles.levelOffsetX(), sy, t,
474 t.width() - m_tiles.qWidth(),
475 t.height() - m_tiles.qHeight() - m_tiles.levelOffsetX() - shadowY,
476 m_tiles.qWidth(), m_tiles.qHeight() + m_tiles.levelOffsetX());
477 } else {
478 p.drawPixmap(sx, sy, t, 0, 0, t.width(), t.height());
479 }
480
481 ++tile;
482 tile = tile % 143;
483 }
484 }
485
486 xOffset += m_tiles.levelOffsetX();
487 yOffset -= m_tiles.levelOffsetY();
488 }
489 }
490
transformPointToPosition(const QPoint & point,POSITION & mouseClickPos,bool align) const491 void Editor::transformPointToPosition(const QPoint & point, POSITION & mouseClickPos, bool align) const
492 {
493 // convert mouse position on screen to a tile z y x coord
494 // different to the one in kmahjongg.cpp since if we hit ground
495 // we return a result too.
496
497 short z = 0;
498 short y = 0;
499 short x = 0;
500 mouseClickPos.z = 100;
501
502 // iterate over z coordinate from top to bottom
503 for (z = m_theBoard.getDepth() - 1; z >= 0; --z) {
504 // calculate mouse coordinates --> position in game board
505 // the factor -theTiles.width()/2 must keep track with the
506 // offset for blitting in the print event (FIX ME)
507 x = ((point.x() - m_borderLeft) - (z + 1) * m_tiles.levelOffsetX()) / m_tiles.qWidth();
508 y = ((point.y() - m_borderTop) + z * m_tiles.levelOffsetX()) / m_tiles.qHeight();
509
510 // skip when position is illegal
511 if (x < 0 || x >= m_theBoard.getWidth() || y < 0 || y >= m_theBoard.getHeight()) {
512 continue;
513 }
514
515 switch (m_theBoard.getBoardData(z, y, x)) {
516 case static_cast<UCHAR>('3'):
517 if (align) {
518 --x;
519 --y;
520 }
521
522 break;
523
524 case static_cast<UCHAR>('2'):
525 if (align) {
526 --x;
527 }
528
529 break;
530
531 case static_cast<UCHAR>('4'):
532 if (align) {
533 --y;
534 }
535
536 break;
537
538 case static_cast<UCHAR>('1'):
539 break;
540
541 default:
542 continue;
543 }
544
545 // if gameboard is empty, skip
546 if (!m_theBoard.getBoardData(z, y, x)) {
547 continue;
548 }
549
550 // here, position is legal
551 mouseClickPos.z = z;
552 mouseClickPos.y = y;
553 mouseClickPos.x = x;
554 mouseClickPos.f = m_theBoard.getBoardData(z, y, x);
555
556 break;
557 }
558
559 if (mouseClickPos.z == 100) {
560 mouseClickPos.x = x;
561 mouseClickPos.y = y;
562 mouseClickPos.f = 0;
563 }
564 }
565
drawFrameMousePressEvent(QMouseEvent * e)566 void Editor::drawFrameMousePressEvent(QMouseEvent * e)
567 {
568 // we swallow the draw frames mouse clicks and process here
569
570 POSITION mousePos;
571 transformPointToPosition(e->pos(), mousePos, (m_mode == EditMode::remove));
572
573 switch (m_mode) {
574 case EditMode::remove:
575 if (!m_theBoard.tileAbove(mousePos) && mousePos.z < m_theBoard.getDepth() && m_theBoard.isTileAt(mousePos)) {
576 m_theBoard.deleteTile(mousePos);
577 --m_numTiles;
578 statusChanged();
579 drawFrameMouseMovedEvent(e);
580 update();
581 }
582
583 break;
584 case EditMode::insert: {
585 POSITION n = mousePos;
586
587 if (n.z == 100) {
588 n.z = 0;
589 } else {
590 n.z += 1;
591 }
592
593 if (canInsert(n)) {
594 m_theBoard.insertTile(n);
595 m_clean = false;
596 ++m_numTiles;
597 statusChanged();
598 update();
599 }
600
601 break;
602 }
603 default:
604 break;
605 }
606 }
607
drawCursor(POSITION & p,bool visible)608 void Editor::drawCursor(POSITION & p, bool visible)
609 {
610 int x = m_borderLeft + (p.z * m_tiles.levelOffsetX()) + (p.x * m_tiles.qWidth());
611 const int y = m_borderTop - ((p.z + 1) * m_tiles.levelOffsetY()) + (p.y * m_tiles.qHeight());
612 const int w = (m_tiles.qWidth() * 2) + m_tiles.levelOffsetX();
613 const int h = (m_tiles.qHeight() * 2) + m_tiles.levelOffsetY();
614
615 if (p.z == 100 || !visible) {
616 x = -1;
617 }
618
619 m_drawFrame->setRect(x, y, w, h, m_tiles.levelOffsetX(), static_cast<int>(m_mode) - static_cast<int>(EditMode::remove));
620 m_drawFrame->update();
621 }
622
drawFrameMouseMovedEvent(QMouseEvent * e)623 void Editor::drawFrameMouseMovedEvent(QMouseEvent * e)
624 {
625 // we swallow the draw frames mouse moves and process here
626
627 POSITION mousePos;
628 transformPointToPosition(e->pos(), mousePos, (m_mode == EditMode::remove));
629
630 if ((mousePos.x == m_curPos.x) && (mousePos.y == m_curPos.y) && (mousePos.z == m_curPos.z)) {
631 return;
632 }
633
634 m_curPos = mousePos;
635
636 statusChanged();
637
638 switch (m_mode) {
639 case EditMode::insert: {
640 POSITION next;
641 next = m_curPos;
642
643 if (next.z == 100) {
644 next.z = 0;
645 } else {
646 next.z += 1;
647 }
648
649 drawCursor(next, canInsert(next));
650
651 break;
652 }
653 case EditMode::remove:
654 drawCursor(m_curPos, 1);
655
656 break;
657 case EditMode::move:
658 break;
659 }
660 }
661
canInsert(POSITION & p) const662 bool Editor::canInsert(POSITION & p) const
663 {
664 // can we inser a tile here. We can iff
665 // there are tiles in all positions below us (or we are a ground level)
666 // there are no tiles intersecting with us on this level
667
668 if (p.z >= m_theBoard.getDepth()) {
669 return false;
670 }
671
672 if (p.y > m_theBoard.getHeight() - 2) {
673 return false;
674 }
675
676 if (p.x > m_theBoard.getWidth() - 2) {
677 return false;
678 }
679
680 POSITION n = p;
681
682 if (p.z != 0) {
683 n.z -= 1;
684 if (!m_theBoard.allFilled(n)) {
685 return false;
686 }
687 }
688
689 return !m_theBoard.anyFilled(p);
690 }
691
closeEvent(QCloseEvent * e)692 void Editor::closeEvent(QCloseEvent * e)
693 {
694 if (testSave()) {
695 m_theBoard.clearBoardLayout();
696 m_clean = true;
697 m_numTiles = 0;
698 statusChanged();
699 update();
700
701 // Save the window geometry.
702 Prefs::setEditorGeometry(geometry());
703 Prefs::self()->save();
704
705 e->accept();
706 } else {
707 e->ignore();
708 }
709 }
710
setTilesetFromSettings()711 void Editor::setTilesetFromSettings()
712 {
713 const QString tileset(Prefs::tileSet());
714
715 // Exit if the tileset is already set.
716 if (tileset == m_tileset) {
717 return;
718 }
719
720 // Try to load the new tileset.
721 if (!m_tiles.loadTileset(tileset)) {
722 // Try to load the old one.
723 if (!m_tiles.loadTileset(m_tileset)) {
724 m_tiles.loadDefault();
725 }
726 } else {
727 // If loading the new tileset was ok, set the new tileset name.
728 m_tileset = tileset;
729 }
730
731 // Must be called to load the graphics and its information.
732 m_tiles.loadGraphics();
733
734 updateTileSize(size());
735 }
736