// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "common.h" #include "tile_edit_dlg.h" #include "items_edit_dlg.h" #include "tile_browser_dlg.h" using namespace std; using namespace NL3D; using namespace NLMISC; CTileBank tileBank; CTileBank tileBankBrowser; bool tileSetSelectionChanging = false; bool CheckPath (const std::string& path, const char* absolutePathToRemplace) { // Look for absolute path in path if (strnicmp (path.c_str(), absolutePathToRemplace, strlen (absolutePathToRemplace))==0) return true; else return false; } bool RemovePath (std::string& path, const char* absolutePathToRemplace) { // Look for absolute path in path if (strnicmp (path.c_str(), absolutePathToRemplace, strlen (absolutePathToRemplace))==0) { // New path std::string toto=path; path=toto.c_str()+strlen (absolutePathToRemplace); return true; } else return false; } CTile_edit_dlg::CTile_edit_dlg(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); initDialog(); } void CTile_edit_dlg::initDialog() { ui.surfaceDataLineEdit->setValidator( new QIntValidator( ui.surfaceDataLineEdit ) ); } void CTile_edit_dlg::on_landListWidget_itemSelectionChanged() { int nindex = ui.landListWidget->currentRow(); if (nindex != -1) { ui.editLandPushButton->setEnabled(true); ui.deleteLandPushButton->setEnabled(true); } else { ui.editLandPushButton->setEnabled(false); ui.deleteLandPushButton->setEnabled(false); } } void CTile_edit_dlg::on_addLandPushButton_clicked() { bool ok; QString text = QInputDialog::getText(this, tr("Add Land"), tr("Enter land name:"), QLineEdit::Normal, "", &ok); if (ok && !text.isEmpty()) { if (ui.landListWidget->findItems(text, Qt::MatchExactly).count() > 0) { QMessageBox::information( this, tr("Error Adding Land"), tr("This name already exists") ); } else { tileBank.addLand( text.toUtf8().constData() ); ui.landListWidget->addItem(text); ui.landListWidget->setCurrentRow(ui.landListWidget->count() - 1); } } } void CTile_edit_dlg::on_editLandPushButton_clicked() { int nindex = ui.landListWidget->currentRow(); if (nindex != -1) { QStringList availableTileSetList; QStringList landTileSetList; for (int i=0; iisTileSet (tileBank.getTileSet(i)->getName())) landTileSetList.append( QString( tileBank.getTileSet(i)->getName().c_str() ) ); else availableTileSetList.append( QString( tileBank.getTileSet(i)->getName().c_str() ) ); } bool ok = false; QStringList items = CItems_edit_dlg::getItems(this, tr("Edit Land"), ui.landListWidget->item(nindex)->text(), availableTileSetList, landTileSetList, &ok); if (ok) { for (int i=0; iremoveTileSet (tileBank.getTileSet(i)->getName()); } for (int i=0; iaddTileSet( rString.toUtf8().constData() ); } } } else { QMessageBox::information( this, tr("No Land Selected"), tr("Please, select the Land to edit first ...") ); } } void CTile_edit_dlg::on_deleteLandPushButton_clicked() { int nindex = ui.landListWidget->currentRow(); if (nindex != -1) { tileBank.removeLand (nindex); QListWidgetItem* item = ui.landListWidget->takeItem(nindex); delete item; } else { QMessageBox::information( this, tr("No Land Selected"), tr("Please, select the Land to delete first ...") ); } } void CTile_edit_dlg::on_addTileSetPushButton_clicked() { bool ok; QString text = QInputDialog::getText(this, tr("Add Tile Set"), tr("Enter Tile Set name:"), QLineEdit::Normal, "", &ok); if (ok && !text.isEmpty()) { if (ui.tileSetListWidget->findItems(text, Qt::MatchExactly).count() > 0) { QMessageBox::information( this, tr("Error Adding Tile Set"), tr("This name already exists") ); } else { tileBank.addTileSet( text.toUtf8().constData() ); ui.tileSetListWidget->addItem(text); ui.tileSetListWidget->setCurrentRow(ui.tileSetListWidget->count() - 1); } } } void CTile_edit_dlg::on_editTileSetPushButton_clicked() { int nindex = ui.tileSetListWidget->currentRow(); if (nindex != -1) { tileBankBrowser=tileBank; CTile_browser_dlg *tileBrowser = new CTile_browser_dlg((QWidget*)this,(Qt::WindowFlags)0); tileBrowser->initDialog(nindex); if ( tileBrowser->exec() ) { tileBank = tileBankBrowser; } } else { QMessageBox::information( this, tr("No Tile Set Selected"), tr("Please, select a Tile Set to edit first ...") ); } } void CTile_edit_dlg::on_deleteTileSetPushButton_clicked() { int nindex = ui.tileSetListWidget->currentRow(); if (nindex != -1) { //WORKAROUND : Qt 4.4 Behaviour (when removing at row 0 and currentRow equals to 0, currentRow is set to 1, it mess with the selectionChanged event if (nindex == 0) { if ( ui.tileSetListWidget->count() > 1) ui.tileSetListWidget->setCurrentRow(1); else ui.tileSetListWidget->setCurrentRow(-1); } // tileBank.removeTileSet( nindex ); QListWidgetItem* item = ui.tileSetListWidget->takeItem(nindex); delete item; } else { QMessageBox::information( this, tr("No Tile Set Selected"), tr("Please, select a Tile Set to delete first ...") ); } } void CTile_edit_dlg::on_chooseVegetPushButton_clicked() { int nindex = ui.tileSetListWidget->currentRow(); if (nindex != -1) { QFileDialog::Options options; QString selectedFilter; QString fileName = QFileDialog::getOpenFileName(this, tr("Choose Veget Set"), ui.chooseVegetPushButton->text() , tr("NeL VegetSet Files (*.vegetset);;All Files (*.*);;"), &selectedFilter, options); if (!fileName.isEmpty()) { QFileInfo fi(fileName); tileBank.getTileSet (nindex)->setTileVegetableDescFileName (fi.fileName().toUtf8().constData()); ui.chooseVegetPushButton->setText(fi.fileName()); } } else { QMessageBox::information( this, tr("No Tile Set Selected"), tr("Please, select a Tile Set first ...") ); } } void CTile_edit_dlg::on_resetVegetPushButton_clicked() { int nindex = ui.tileSetListWidget->currentRow(); if (nindex != -1) { tileBank.getTileSet (nindex)->setTileVegetableDescFileName (""); ui.chooseVegetPushButton->setText("..."); } else { QMessageBox::information( this, tr("No Tile Set Selected"), tr("Please, select a Tile Set first ...") ); } } void CTile_edit_dlg::on_surfaceDataLineEdit_textChanged() { if (!tileSetSelectionChanging) { int nindex = ui.tileSetListWidget->currentRow(); if (nindex != -1) { bool ok; uint intValue = ui.surfaceDataLineEdit->text().toUInt( &ok, 10 ); if (ok) { tileBank.getTileSet (nindex)->SurfaceData = (uint32)intValue; } } else { QMessageBox::information( this, tr("No Tile Set Selected"), tr("Please, select a Tile Set first ...") ); } } } void CTile_edit_dlg::on_orientedCheckBox_stateChanged ( int state ) { if (!tileSetSelectionChanging) { int nindex = ui.tileSetListWidget->currentRow(); if (nindex != -1) { tileBank.getTileSet (nindex)->setOriented(ui.orientedCheckBox->isChecked()); } else { QMessageBox::information( this, tr("No Tile Set Selected"), tr("Please, select a Tile Set first ...") ); } } } void CTile_edit_dlg::on_tileSetListWidget_itemSelectionChanged() { tileSetSelectionChanging = true; int nindex = ui.tileSetListWidget->currentRow(); if (nindex != -1) { if ( !tileBank.getTileSet(nindex)->getTileVegetableDescFileName().empty() ) ui.chooseVegetPushButton->setText( QString( tileBank.getTileSet(nindex)->getTileVegetableDescFileName().c_str() ) ); else ui.chooseVegetPushButton->setText("..."); ui.surfaceDataLineEdit->setText( QString::number( tileBank.getTileSet(nindex)->SurfaceData) ); ui.orientedCheckBox->setChecked( tileBank.getTileSet(nindex)->getOriented() ); ui.selectedTileSetGroupBox->setEnabled(true); ui.editTileSetPushButton->setEnabled(true); ui.deleteTileSetPushButton->setEnabled(true); } else { //TODO titegus: Init DetailFrame Method ui.chooseVegetPushButton->setText("..."); ui.surfaceDataLineEdit->clear(); ui.orientedCheckBox->setChecked(false); ui.selectedTileSetGroupBox->setEnabled(false); ui.editTileSetPushButton->setEnabled(false); ui.deleteTileSetPushButton->setEnabled(false); } tileSetSelectionChanging = false; } void CTile_edit_dlg::on_quitPushButton_clicked() { close(); } void CTile_edit_dlg::on_loadPushButton_clicked() { QFileDialog::Options options; QString selectedFilter; QString fileName = QFileDialog::getOpenFileName(this, tr("Open Bank"), ui.absolutePathPushButton->text() , tr("NeL tile bank files (*.bank);;All Files (*.*);;"), &selectedFilter, options); if (!fileName.isEmpty()) { CIFile stream; if ( stream.open( fileName.toUtf8().constData() ) ) { ui.landListWidget->clear(); ui.tileSetListWidget->clear(); tileBank.clear(); tileBank.serial (stream); } int i; QStringList lands; for (i=0; igetName().c_str()) ); } ui.landListWidget->addItems(lands); QStringList tileSets; for (i=0; igetName().c_str() ) ); } ui.tileSetListWidget->addItems(tileSets); // Set MainFile mainFile = QFileInfo(fileName); ui.savePushButton->setEnabled(true); ui.absolutePathPushButton->setText( QString( tileBank.getAbsPath().c_str() ) ); } } void CTile_edit_dlg::on_savePushButton_clicked() { string fullPath = this->mainFile.absoluteFilePath().toUtf8().constData(); if ( !fullPath.empty() ) { COFile stream; if ( stream.open( fullPath.c_str() ) ) { tileBank.serial (stream); QString s = tr("Bank %1 saved").arg( QString( fullPath.c_str() ) ); QMessageBox::information(this, tr("Bank Saved"), s); return; } } QMessageBox::information(this, tr("Error"), tr("Can't Save Bank, check the path")); } void CTile_edit_dlg::on_saveAsPushButton_clicked() { QFileDialog::Options options; QString selectedFilter; QString fileName = QFileDialog::getSaveFileName(this, tr("Save Bank"), this->mainFile.absoluteFilePath(), tr("NeL tile bank files (*.bank);;All Files (*.*);;"), &selectedFilter, options); if (!fileName.isEmpty()) { // Set MainFile mainFile = QFileInfo(fileName); ui.savePushButton->setEnabled(true); string fullPath = this->mainFile.absoluteFilePath().toUtf8().constData(); if ( !fullPath.empty() ) { COFile stream; if ( stream.open( fullPath.c_str() ) ) { tileBank.serial (stream); QString s = tr("Bank %1 saved").arg( QString( fullPath.c_str() ) ); QMessageBox::information(this, tr("Bank Saved"), s); return; } } QMessageBox::information(this, tr("Error"), tr("Can't Save Bank, check the path")); } } void CTile_edit_dlg::on_exportPushButton_clicked() { QFileDialog::Options options; QString selectedFilter; QString fileName = QFileDialog::getSaveFileName(this, tr("Export Bank"), this->mainFile.absolutePath() + QDir::separator() + tr("*.smallbank"), tr("NeL tile small bank files (*.smallbank);;All Files (*.*);;"), &selectedFilter, options); if (!fileName.isEmpty()) { // Copy the bank CTileBank copy=tileBank; // Remove unused data copy.cleanUnusedData (); QFileInfo fileInfo(fileName); string fullPath = fileInfo.absoluteFilePath().toUtf8().constData(); if ( !fullPath.empty() ) { COFile stream; if ( stream.open( fullPath.c_str() ) ) { copy.serial (stream); QString s = tr("Bank %1 exported").arg( QString( fullPath.c_str() ) ); QMessageBox::information(this, tr("Bank Saved"), s); return; } } QMessageBox::information(this, tr("Error"), tr("Can't Export the Bank, check the path")); } } void CTile_edit_dlg::on_absolutePathPushButton_clicked() { // Build the struct QFileDialog::Options options = QFileDialog::DontResolveSymlinks | QFileDialog::ShowDirsOnly; QString directory = QFileDialog::getExistingDirectory(this, tr("Select the absolute base path of the bank"), ui.absolutePathPushButton->text(), options); // Select the path if (!directory.isEmpty()) { // Convert item into path string QString path = QDir::toNativeSeparators(directory); // Add a final back slash if (!path.endsWith(QDir::separator())) { // Add a '\' at the end path.append(QDir::separator()); } //// Last check QMessageBox::StandardButton reply; QString confirmMessage = tr("Do you really want to set %1 as base path of the bank?").arg(path); reply = QMessageBox::question(this, tr("Confirm Path"), confirmMessage, QMessageBox::Yes | QMessageBox::No); if (reply == QMessageBox::Yes) { // Set as default path.. // Old path const char* oldPath=tileBank.getAbsPath ().c_str(); // Path are good bool goodPath=true; // If no absolute path, must check before use it if ((*oldPath)==0) { // Compute xref tileBank.computeXRef(); // For all tiles, check we can change the path for (int tiles=0; tilesgetRelativeFileName ((CTile::TBitmap)type); // not empty ? if (bitmapPath!="") { // Check the path if ( CheckPath( bitmapPath, path.toUtf8() ) == false ) { // Bad path goodPath=false; // Message QString continueMessage = tr("Path '%1' can't be found in bitmap '%2'. Continue ?").arg(path).arg(QString(bitmapPath.c_str())); reply = QMessageBox::question(this, tr("Continue"), continueMessage, QMessageBox::Yes | QMessageBox::No); if (reply == QMessageBox::No) break; } } } if (type!=CTile::bitmapCount) break; } } // For all tiles, check we can change the path for (uint noise=1; noisegetRelativeFileName ((CTile::TBitmap)type); // not empty ? if (bitmapPath!="") { // Remove the absolute path bool res=RemovePath (bitmapPath, path.toUtf8()); nlassert (res); // Set the bitmap tileBank.getTile(tiles)->setFileName ((CTile::TBitmap)type, bitmapPath); } } } } // For all tiles, check we can change the path for (uint noise=1; noisesetText(path); } } // Remove path from all tiles //tileBank } } void CTile_edit_dlg::on_downPushButton_clicked() { int nindex = ui.tileSetListWidget->currentRow(); if (nindex != -1) { if (nindex < (ui.tileSetListWidget->count() - 1) ) { tileBank.xchgTileset (nindex, nindex+1); QListWidgetItem* item = ui.tileSetListWidget->takeItem(nindex); ui.tileSetListWidget->insertItem(nindex + 1, item); ui.tileSetListWidget->setCurrentRow(nindex + 1); } } else { QMessageBox::information( this, tr("No Tile Set Selected"), tr("Please, select a Tile Set first ...") ); } } void CTile_edit_dlg::on_upPushButton_clicked() { int nindex = ui.tileSetListWidget->currentRow(); if (nindex != -1) { if (nindex > 0 ) { tileBank.xchgTileset (nindex, nindex-1); QListWidgetItem* item = ui.tileSetListWidget->takeItem(nindex); ui.tileSetListWidget->insertItem(nindex - 1, item); ui.tileSetListWidget->setCurrentRow(nindex - 1); } } else { QMessageBox::information( this, tr("No Tile Set Selected"), tr("Please, select a Tile Set first ...") ); } } void CTile_edit_dlg::closeEvent(QCloseEvent *event) { int reply = QMessageBox::question(this, tr("Quit"), tr("Are you sure you want to quit?"), QMessageBox::Yes | QMessageBox::No); if (reply == QMessageBox::Yes) { event->accept(); } else { event->ignore(); } }