27 #include <QtCore/QPointer>
30 #include <KGameRenderer>
31 #include <KStandardDirs>
32 #include <KConfigSkeleton>
33 #include <KNS3/DownloadDialog>
36 #include <KComponentData>
38 #include "ui_arenaselector.h"
41 class ArenaSelector::Private
50 QMap<QString, ArenaSettings*> arenaMap;
51 Ui::ArenaSelectorBase ui;
52 QString lookupDirectory;
56 KGameRenderer* m_renderer;
58 QList <KGameRenderedItem*> m_arenaItems;
59 qreal m_svgScaleFactor;
61 QStringList* m_randomArenaModeArenaList;
62 QStringList m_tempRandomArenaModeArenaList;
65 void findArenas(
const QString &initialSelection);
66 QSize calculateSvgSize();
69 void _k_updatePreview(QListWidgetItem* currentItem = NULL);
70 void _k_updateArenaList(
const QString& strArena);
71 void _k_openKNewStuffDialog();
72 void _k_importArenasDialog();
73 void _k_setRandomArenaMode(
bool randomModeEnabled);
74 void _k_updateRandomArenaModeArenaList(QListWidgetItem* item);
78 :
QWidget(parent), d(new Private(this, options))
80 d->m_randomArenaModeArenaList = randomArenaModeArenaList;
81 d->lookupDirectory = directory;
82 d->groupName = groupName;
83 d->setupData(aconfig);
93 d->_k_updatePreview();
98 d->_k_updatePreview();
101 ArenaSelector::Private::Private(
ArenaSelector* parent, Options options) : q(parent), m_options(options), m_arena(NULL), m_graphicsScene(NULL), m_svgScaleFactor(1)
103 KgTheme* theme =
new KgTheme(QByteArray());
104 theme->setGraphicsPath(KStandardDirs::locate(
"appdata", QString(
"themes/granatier.svgz")));
105 m_renderer =
new KGameRenderer(theme);
108 ArenaSelector::Private::~Private()
110 qDeleteAll(arenaMap);
113 qDeleteAll(m_arenaItems);
114 delete m_graphicsScene;
125 if (m_options & EnableNewStuffDownload)
127 ui.getNewButton->setIcon(KIcon( QLatin1String(
"get-hot-new-stuff" )));
128 connect(ui.getNewButton, SIGNAL(clicked()), q, SLOT(_k_openKNewStuffDialog()));
132 ui.getNewButton->hide();
138 ui.kcfg_Arena->hide();
139 connect(ui.kcfg_Arena, SIGNAL(textChanged(QString)), q, SLOT(_k_updateArenaList(QString)));
143 ui.arenaPreview->setScene(m_graphicsScene);
144 ui.arenaPreview->setBackgroundBrush(Qt::black);
147 KConfigSkeletonItem * configItem = aconfig->findItem(
"Arena");
148 QString lastUsedArena = configItem->property().toString();
150 configItem = aconfig->findItem(
"RandomArenaModeArenaList");
151 m_tempRandomArenaModeArenaList = configItem->property().toStringList();
152 m_tempRandomArenaModeArenaList.removeDuplicates();
155 KGlobal::dirs()->addResourceType(
"arenaselector",
"data", KGlobal::mainComponent().componentName() +
'/' + lookupDirectory +
'/');
156 findArenas(lastUsedArena);
158 connect(ui.importArenas, SIGNAL(clicked()), q, SLOT(_k_importArenasDialog()));
159 connect(ui.kcfg_RandomArenaMode, SIGNAL(toggled(
bool)), q, SLOT(_k_setRandomArenaMode(
bool)));
162 void ArenaSelector::Private::findArenas(
const QString &initialSelection)
164 qDeleteAll(arenaMap);
168 ui.arenaList->disconnect();
169 ui.arenaList->clear();
170 ui.arenaList->setSortingEnabled(
true);
172 QStringList arenasAvailable;
173 KGlobal::dirs()->findAllResources(
"arenaselector",
"*.desktop", KStandardDirs::Recursive, arenasAvailable);
175 QStringList::Iterator i = m_tempRandomArenaModeArenaList.begin();
176 while(i != m_tempRandomArenaModeArenaList.end())
178 if(arenasAvailable.contains(*i))
184 i = m_tempRandomArenaModeArenaList.erase(i);
188 if(m_tempRandomArenaModeArenaList.isEmpty())
190 m_tempRandomArenaModeArenaList = arenasAvailable;
193 bool initialFound =
false;
194 foreach (
const QString &file, arenasAvailable)
196 QString arenaPath = lookupDirectory +
'/' + file;
199 if (arenaSettings->
load(arenaPath)) {
202 while (arenaMap.contains(arenaName))
204 arenaMap.insert(arenaName, arenaSettings);
205 QListWidgetItem * item =
new QListWidgetItem(arenaName, ui.arenaList);
206 if(ui.kcfg_RandomArenaMode->isChecked())
208 if(m_tempRandomArenaModeArenaList.contains(file))
210 item->setCheckState(Qt::Checked);
214 item->setCheckState(Qt::Unchecked);
216 item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
220 item->setCheckState(Qt::PartiallyChecked);
221 item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
225 if (arenaPath==initialSelection) {
227 ui.arenaList->setCurrentItem(item);
228 _k_updatePreview(item);
231 delete arenaSettings;
238 QString defaultPath =
"arenas/granatier.desktop";
241 if (arenaSettings->
path().endsWith(defaultPath))
243 const QList<QListWidgetItem *> itemList = ui.arenaList->findItems(arenaSettings->
arenaProperty(
"Name"), Qt::MatchExactly);
245 if (itemList.count() == 1)
247 ui.arenaList->setCurrentItem(itemList.first());
248 _k_updatePreview(itemList.first());
255 connect(ui.arenaList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), q, SLOT(_k_updatePreview(QListWidgetItem*)));
256 if(ui.kcfg_RandomArenaMode->isChecked())
258 connect(ui.arenaList, SIGNAL(itemChanged(QListWidgetItem*)), q, SLOT(_k_updateRandomArenaModeArenaList(QListWidgetItem*)));
262 void ArenaSelector::Private::_k_updatePreview(QListWidgetItem* currentItem)
264 if(currentItem != NULL)
266 ArenaSettings * selArena = arenaMap.value(ui.arenaList->currentItem()->text());
268 if (!selArena)
return;
269 if (selArena->
path() == ui.kcfg_Arena->text()) {
272 ui.kcfg_Arena->setText(selArena->
fileName());
274 QString authstr(
"Author");
275 QString contactstr(
"AuthorEmail");
276 QString descstr(
"Description");
278 if(emailstr.compare(
"-") == 0)
282 if (!emailstr.isEmpty())
284 emailstr = QString(
"<a href=\"mailto:%1\">%1</a>").arg(selArena->
arenaProperty(contactstr));
287 ui.arenaAuthor->setText(i18nc(
"Author attribution, e.g. \"by Jack\"",
"by %1", selArena->
arenaProperty(authstr)));
288 ui.arenaContact->setText(emailstr);
289 ui.arenaDescription->setText(selArena->
arenaProperty(descstr));
295 QFile arenaXmlFile(selArena->
graphics());
296 QXmlInputSource source(&arenaXmlFile);
298 QXmlSimpleReader reader;
299 reader.setContentHandler(&mapParser);
301 reader.parse(source);
303 while(!m_arenaItems.isEmpty())
305 if(m_graphicsScene->items().contains(m_arenaItems.last()))
307 m_graphicsScene->removeItem(m_arenaItems.last());
309 delete m_arenaItems.takeLast();
313 ui.arenaPreview->fitInView(ui.arenaPreview->sceneRect(), Qt::KeepAspectRatio);
316 qreal svgScaleFactor;
317 QRectF minSize = ui.arenaPreview->sceneRect();
319 if(minSize.width() == 0)
323 if(minSize.height() == 0)
325 minSize.setHeight(1);
329 int horizontalPixelsPerCell = (ui.arenaPreview->size().width() - 4) / (minSize.width()/
Granatier::CellSize);
330 int verticalPixelsPerCell = (ui.arenaPreview->size().height() - 4) / (minSize.height()/
Granatier::CellSize);
331 if(horizontalPixelsPerCell < verticalPixelsPerCell)
340 QTransform transform;
341 transform.scale(1/svgScaleFactor, 1/svgScaleFactor);
342 m_graphicsScene->views().first()->setTransform(transform);
343 m_graphicsScene->views().first()->centerOn( ui.arenaPreview->sceneRect().center());
345 if(currentItem == NULL)
347 if(m_svgScaleFactor != svgScaleFactor)
349 m_svgScaleFactor = svgScaleFactor;
352 arenaItem->setRenderSize(calculateSvgSize());
353 arenaItem->setScale(m_svgScaleFactor);
359 m_svgScaleFactor = svgScaleFactor;
360 for (
int i = 0; i < m_arena->getNbRows(); ++i)
362 for (
int j = 0; j < m_arena->getNbColumns(); ++j)
367 switch(m_arena->getCell(i,j).getType())
370 arenaItem->setSpriteKey(
"arena_wall");
371 arenaItem->setZValue(-2);
374 arenaItem->setSpriteKey(
"arena_block");
375 arenaItem->setZValue(0);
382 arenaItem->setSpriteKey(
"arena_ice");
383 arenaItem->setZValue(0);
386 arenaItem->setSpriteKey(
"arena_bomb_mortar");
387 arenaItem->setZValue(0);
390 arenaItem->setSpriteKey(
"arena_arrow_up");
391 arenaItem->setZValue(0);
394 arenaItem->setSpriteKey(
"arena_arrow_right");
395 arenaItem->setZValue(0);
398 arenaItem->setSpriteKey(
"arena_arrow_down");
399 arenaItem->setZValue(0);
402 arenaItem->setSpriteKey(
"arena_arrow_left");
403 arenaItem->setZValue(0);
407 arenaItem->setSpriteKey(
"arena_ground");
408 arenaItem->setZValue(-1);
412 arenaItem->setRenderSize(calculateSvgSize());
413 arenaItem->setScale(m_svgScaleFactor);
415 m_arenaItems.append(arenaItem);
416 m_graphicsScene->addItem(arenaItem);
423 QSize ArenaSelector::Private::calculateSvgSize()
425 if(m_graphicsScene->views().isEmpty())
430 QPoint topLeft(0, 0);
431 topLeft = m_graphicsScene->views().first()->mapFromScene(topLeft);
434 bottomRight = m_graphicsScene->views().first()->mapFromScene(bottomRight);
437 svgSize.setHeight(bottomRight.y() - topLeft.y());
438 svgSize.setWidth(bottomRight.x() - topLeft.x());
443 void ArenaSelector::Private::_k_updateArenaList(
const QString& strArena)
446 if(arenaMap.value(ui.arenaList->currentItem()->text())->fileName() != strArena)
448 for(
int i = 0; i < ui.arenaList->count(); i++)
450 if(arenaMap.value(ui.arenaList->item(i)->text())->fileName() == strArena)
452 ui.arenaList->setCurrentItem(ui.arenaList->item(i));
459 void ArenaSelector::Private::_k_openKNewStuffDialog()
461 QPointer<KNS3::DownloadDialog> dialog =
new KNS3::DownloadDialog (q);
462 if(dialog->exec() == QDialog::Accepted)
464 if(!(dialog->changedEntries().isEmpty()))
472 void ArenaSelector::Private::_k_importArenasDialog()
475 QStringList listClanbomberPaths;
476 listClanbomberPaths.append(QDir::homePath() +
"/.clanbomber/maps/");
477 for(
int i = 0; i < listClanbomberPaths.count(); i++)
479 QDir clanbomberDir(listClanbomberPaths[i]);
480 if(!clanbomberDir.exists())
485 QStringList listMaps;
486 listMaps = clanbomberDir.entryList(QStringList(
"*.map"));
487 for(
int j = 0; j < listMaps.count(); j++)
489 QFile mapFile(listClanbomberPaths[i] + listMaps[j]);
490 mapFile.open(QIODevice::ReadOnly | QIODevice::Text);
491 QTextStream readStream(&mapFile);
493 QString strAuthor = readStream.readLine();
494 int nNumberOfPlayers = readStream.readLine().toInt();
496 KSaveFile desktopFile;
497 QString strName = listMaps[j].left(listMaps[j].count()-4);
498 desktopFile.setFileName(QString(
"%1clanbomber_%2.desktop").arg(KStandardDirs::locateLocal(
"appdata",
"arenas/")).arg(strName));
500 QTextStream streamDesktopFile(&desktopFile);
502 streamDesktopFile <<
"[Arena]\n";
503 streamDesktopFile <<
"Name=" << strName <<
"\n";
504 streamDesktopFile <<
"Description=Clanbomber Import\n";
505 streamDesktopFile <<
"Type=XML\n";
506 streamDesktopFile <<
"FileName=clanbomber_" << strName <<
".xml\n";
507 streamDesktopFile <<
"Author=" << strAuthor <<
"\n";
508 streamDesktopFile <<
"AuthorEmail=-\n";
510 streamDesktopFile.flush();
511 desktopFile.finalize();
517 arena.append(readStream.readLine());
519 while(!readStream.atEnd());
520 arena.replaceInStrings(
"*",
"=");
521 arena.replaceInStrings(
" ",
"_");
522 arena.replaceInStrings(
"-",
" ");
523 arena.replaceInStrings(
"S",
"-");
524 arena.replaceInStrings(
"R",
"x");
525 arena.replaceInStrings(
"^",
"u");
526 arena.replaceInStrings(
">",
"r");
527 arena.replaceInStrings(
"v",
"d");
528 arena.replaceInStrings(
"<",
"l");
529 arena.replaceInStrings(
"0",
"p");
530 arena.replaceInStrings(
"1",
"p");
531 arena.replaceInStrings(
"2",
"p");
532 arena.replaceInStrings(
"3",
"p");
533 arena.replaceInStrings(
"4",
"p");
534 arena.replaceInStrings(
"5",
"p");
535 arena.replaceInStrings(
"6",
"p");
536 arena.replaceInStrings(
"7",
"p");
537 arena.replaceInStrings(
"8",
"p");
538 arena.replaceInStrings(
"9",
"p");
541 arenaFile.setFileName(QString(
"%1clanbomber_%2.xml").arg(KStandardDirs::locateLocal(
"appdata",
"arenas/")).arg(strName));
544 QTextStream streamArenaFile(&arenaFile);
546 streamArenaFile <<
"<?xml version=\"1.0\"?>\n";
547 streamArenaFile <<
"<Arena arenaFileVersion=\"1\" rowCount=\"" << arena.count() <<
"\" colCount=\"" << arena[0].count() <<
"\">\n";
548 for(
int j = 0; j < arena.count(); j++)
550 streamArenaFile <<
" <Row>" << arena[j] <<
"</Row>\n";
552 streamArenaFile <<
"</Arena>\n";
556 ArenaSettings* selArena = arenaMap.value(ui.arenaList->currentItem()->text());
560 void ArenaSelector::Private::_k_setRandomArenaMode(
bool randomModeEnabled)
562 if(!randomModeEnabled)
564 disconnect(ui.arenaList, SIGNAL(itemChanged(QListWidgetItem*)), q, SLOT(_k_updateRandomArenaModeArenaList(QListWidgetItem*)));
567 m_randomArenaModeArenaList->clear();
569 int numberOfItems = ui.arenaList->count();
570 for(
int i = 0; i < numberOfItems; i++)
572 QListWidgetItem* item = ui.arenaList->item(i);
573 if(randomModeEnabled)
575 QString arenaName = arenaMap.value(item->text())->fileName();
576 arenaName.remove(0, 7);
577 if(m_tempRandomArenaModeArenaList.contains(arenaName))
579 item->setCheckState(Qt::Checked);
583 item->setCheckState(Qt::Unchecked);
585 item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
589 item->setCheckState(Qt::PartiallyChecked);
590 item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
594 if(randomModeEnabled)
596 *m_randomArenaModeArenaList = m_tempRandomArenaModeArenaList;
597 connect(ui.arenaList, SIGNAL(itemChanged(QListWidgetItem*)), q, SLOT(_k_updateRandomArenaModeArenaList(QListWidgetItem*)));
601 void ArenaSelector::Private::_k_updateRandomArenaModeArenaList(QListWidgetItem* item)
603 QString arenaName = arenaMap.value(item->text())->fileName();
604 arenaName.remove(0, 7);
605 if(item->checkState() == Qt::Checked)
607 m_tempRandomArenaModeArenaList.append(arenaName);
611 int index = m_tempRandomArenaModeArenaList.indexOf(arenaName);
614 m_tempRandomArenaModeArenaList.removeAt(index);
617 m_tempRandomArenaModeArenaList.removeDuplicates();
618 *m_randomArenaModeArenaList = m_tempRandomArenaModeArenaList;
621 #include "arenaselector.moc"
virtual bool load(const QString &file)
Load a specific arena file.
This class handles XML reader events in order to initialize the Arena properties. ...
virtual QString graphics() const
const qreal CellSize
The Cell size.
ArenaSelector(QWidget *parent, KConfigSkeleton *aconfig, QStringList *randomArenaModeArenaList, Options options=DefaultBehavior, const QString &groupName=QLatin1String("Arena"), const QString &directory=QLatin1String("arenas"))
Load a specific arena file.
void resizeEvent(QResizeEvent *p_event)
Resizes the items when the view is resized.
This class is the graphical view of the Arena.
This class represents the Arena of the game.
void showEvent(QShowEvent *p_event)
Resizes the items when the view is showed.
virtual QString arenaProperty(const QString &key) const
Possible keys:
Class for loading arena files.
A widget used to select the game's arena.
static void setDummy(int v)
Set This is a dummy setting for player setup.