Merge branch 'master' into ci/use-ninja-win

This commit is contained in:
Bruno Alexandre Rosa 2026-03-14 11:18:01 -03:00
commit bde03fa1be
12 changed files with 252 additions and 64 deletions

View file

@ -204,12 +204,12 @@ jobs:
--ccache "$CCACHE_SIZE" $NO_CLIENT --ccache "$CCACHE_SIZE" $NO_CLIENT
.ci/name_build.sh .ci/name_build.sh
- name: Delete stale ccache # Delete used cache to emulate a cache update. See https://github.com/actions/cache/issues/342.
if: github.ref == 'refs/heads/master' - name: Delete old compiler cache (ccache)
if: github.ref == 'refs/heads/master' && steps.ccache_restore.outputs.cache-hit && steps.build.outcome == 'success'
env: env:
GH_TOKEN: ${{github.token}} GH_TOKEN: ${{ github.token }}
run: | run: gh cache delete --repo ${{ github.repository }} ${{ steps.ccache_restore.outputs.cache-primary-key }}
gh cache delete "${{ steps.ccache_restore.outputs.cache-primary-key }}" || true
- name: Save compiler cache (ccache) - name: Save compiler cache (ccache)
if: github.ref == 'refs/heads/master' if: github.ref == 'refs/heads/master'
@ -446,13 +446,12 @@ jobs:
TARGET_MACOS_VERSION: ${{ matrix.override_target }} TARGET_MACOS_VERSION: ${{ matrix.override_target }}
run: .ci/compile.sh --server --test --vcpkg run: .ci/compile.sh --server --test --vcpkg
# github does not overwrite GHA cache entries when the key is the same, so we need to delete the stale ones before saving # Delete used cache to emulate a cache update. See https://github.com/actions/cache/issues/342.
- name: Delete stale ccache - name: Delete old compiler cache (ccache)
if: github.ref == 'refs/heads/master' if: github.ref == 'refs/heads/master' && steps.ccache_restore.outputs.cache-hit && steps.build.outcome == 'success'
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
run: | run: gh cache delete --repo ${{ github.repository }} ${{ steps.ccache_restore.outputs.cache-primary-key }}
gh cache delete "${{ steps.ccache_restore.outputs.cache-primary-key }}" || true
- name: Save compiler cache (ccache) - name: Save compiler cache (ccache)
if: github.ref == 'refs/heads/master' && steps.build.outcome == 'success' if: github.ref == 'refs/heads/master' && steps.build.outcome == 'success'

View file

@ -39,6 +39,7 @@ set(cockatrice_SOURCES
src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp src/interface/widgets/dialogs/dlg_load_deck_from_clipboard.cpp
src/interface/widgets/dialogs/dlg_load_deck_from_website.cpp src/interface/widgets/dialogs/dlg_load_deck_from_website.cpp
src/interface/widgets/dialogs/dlg_load_remote_deck.cpp src/interface/widgets/dialogs/dlg_load_remote_deck.cpp
src/interface/widgets/dialogs/dlg_local_game_options.cpp
src/interface/widgets/dialogs/dlg_manage_sets.cpp src/interface/widgets/dialogs/dlg_manage_sets.cpp
src/interface/widgets/dialogs/dlg_register.cpp src/interface/widgets/dialogs/dlg_register.cpp
src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp

View file

@ -385,6 +385,13 @@ SettingsCache::SettingsCache()
defaultStartingLifeTotal = settings->value("game/defaultstartinglifetotal", 20).toInt(); defaultStartingLifeTotal = settings->value("game/defaultstartinglifetotal", 20).toInt();
shareDecklistsOnLoad = settings->value("game/sharedecklistsonload", false).toBool(); shareDecklistsOnLoad = settings->value("game/sharedecklistsonload", false).toBool();
rememberGameSettings = settings->value("game/remembergamesettings", true).toBool(); rememberGameSettings = settings->value("game/remembergamesettings", true).toBool();
// Local game settings use "localgameoptions/" prefix to keep them separate
// from server game settings which use "game/" prefix
localGameRememberSettings = settings->value("localgameoptions/remembersettings", false).toBool();
localGameMaxPlayers = settings->value("localgameoptions/maxplayers", 1).toInt();
localGameStartingLifeTotal = settings->value("localgameoptions/startinglifetotal", 20).toInt();
clientID = settings->value("personal/clientid", CLIENT_INFO_NOT_SET).toString(); clientID = settings->value("personal/clientid", CLIENT_INFO_NOT_SET).toString();
clientVersion = settings->value("personal/clientversion", CLIENT_INFO_NOT_SET).toString(); clientVersion = settings->value("personal/clientversion", CLIENT_INFO_NOT_SET).toString();
} }
@ -1242,6 +1249,24 @@ void SettingsCache::setRememberGameSettings(const bool _rememberGameSettings)
settings->setValue("game/remembergamesettings", rememberGameSettings); settings->setValue("game/remembergamesettings", rememberGameSettings);
} }
void SettingsCache::setLocalGameRememberSettings(bool value)
{
localGameRememberSettings = value;
settings->setValue("localgameoptions/remembersettings", value);
}
void SettingsCache::setLocalGameMaxPlayers(int value)
{
localGameMaxPlayers = value;
settings->setValue("localgameoptions/maxplayers", value);
}
void SettingsCache::setLocalGameStartingLifeTotal(int value)
{
localGameStartingLifeTotal = value;
settings->setValue("localgameoptions/startinglifetotal", value);
}
void SettingsCache::setNotifyAboutUpdate(QT_STATE_CHANGED_T _notifyaboutupdate) void SettingsCache::setNotifyAboutUpdate(QT_STATE_CHANGED_T _notifyaboutupdate)
{ {
notifyAboutUpdates = static_cast<bool>(_notifyaboutupdate); notifyAboutUpdates = static_cast<bool>(_notifyaboutupdate);

View file

@ -330,6 +330,12 @@ private:
[[nodiscard]] QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const; [[nodiscard]] QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const;
void loadPaths(); void loadPaths();
bool rememberGameSettings; bool rememberGameSettings;
// Local game settings (separate from server game settings in game/*)
bool localGameRememberSettings;
int localGameMaxPlayers;
int localGameStartingLifeTotal;
QList<ReleaseChannel *> releaseChannels; QList<ReleaseChannel *> releaseChannels;
bool isPortableBuild; bool isPortableBuild;
bool roundCardCorners; bool roundCardCorners;
@ -862,6 +868,18 @@ public:
{ {
return rememberGameSettings; return rememberGameSettings;
} }
[[nodiscard]] bool getLocalGameRememberSettings() const
{
return localGameRememberSettings;
}
[[nodiscard]] int getLocalGameMaxPlayers() const
{
return localGameMaxPlayers;
}
[[nodiscard]] int getLocalGameStartingLifeTotal() const
{
return localGameStartingLifeTotal;
}
[[nodiscard]] int getKeepAlive() const override [[nodiscard]] int getKeepAlive() const override
{ {
return keepalive; return keepalive;
@ -1089,6 +1107,9 @@ public slots:
void setDefaultStartingLifeTotal(const int _defaultStartingLifeTotal); void setDefaultStartingLifeTotal(const int _defaultStartingLifeTotal);
void setShareDecklistsOnLoad(const bool _shareDecklistsOnLoad); void setShareDecklistsOnLoad(const bool _shareDecklistsOnLoad);
void setRememberGameSettings(const bool _rememberGameSettings); void setRememberGameSettings(const bool _rememberGameSettings);
void setLocalGameRememberSettings(bool value);
void setLocalGameMaxPlayers(int value);
void setLocalGameStartingLifeTotal(int value);
void setCheckUpdatesOnStartup(QT_STATE_CHANGED_T value); void setCheckUpdatesOnStartup(QT_STATE_CHANGED_T value);
void setStartupCardUpdateCheckPromptForUpdate(bool value); void setStartupCardUpdateCheckPromptForUpdate(bool value);
void setStartupCardUpdateCheckAlwaysUpdate(bool value); void setStartupCardUpdateCheckAlwaysUpdate(bool value);

View file

@ -113,32 +113,20 @@ CardMenu::CardMenu(Player *_player, const CardItem *_card, bool _shortcutsActive
addAction(aSelectAll); addAction(aSelectAll);
addAction(aSelectColumn); addAction(aSelectColumn);
addRelatedCardView(); addRelatedCardView();
} else if (writeableCard) { } else {
if (card->getZone()) { if (card->getZone()) {
if (card->getZone()->getName() == ZoneNames::TABLE) { if (card->getZone()->getName() == ZoneNames::TABLE) {
createTableMenu(); createTableMenu(writeableCard);
} else if (card->getZone()->getName() == ZoneNames::STACK) { } else if (card->getZone()->getName() == ZoneNames::STACK) {
createStackMenu(); createStackMenu(writeableCard);
} else if (card->getZone()->getName() == ZoneNames::EXILE || } else if (card->getZone()->getName() == ZoneNames::EXILE ||
card->getZone()->getName() == ZoneNames::GRAVE) { card->getZone()->getName() == ZoneNames::GRAVE) {
createGraveyardOrExileMenu(); createGraveyardOrExileMenu(writeableCard);
} else { } else {
createHandOrCustomZoneMenu(); createHandOrCustomZoneMenu(writeableCard);
} }
} else { } else {
addMenu(new MoveMenu(player)); createZonelessMenu(writeableCard);
}
} else {
if (card->getZone() && card->getZone()->getName() != ZoneNames::HAND) {
addAction(aDrawArrow);
addSeparator();
addRelatedCardView();
addRelatedCardActions();
addSeparator();
addAction(aClone);
addSeparator();
addAction(aSelectAll);
} }
} }
} }
@ -154,11 +142,9 @@ void CardMenu::removePlayer(Player *playerToRemove)
} }
} }
void CardMenu::createTableMenu() void CardMenu::createTableMenu(bool canModifyCard)
{ {
// Card is on the battlefield // Card is on the battlefield
bool canModifyCard = player->getPlayerInfo()->judge || card->getOwner() == player;
if (!canModifyCard) { if (!canModifyCard) {
addRelatedCardView(); addRelatedCardView();
addRelatedCardActions(); addRelatedCardActions();
@ -213,10 +199,8 @@ void CardMenu::createTableMenu()
addMenu(mCardCounters); addMenu(mCardCounters);
} }
void CardMenu::createStackMenu() void CardMenu::createStackMenu(bool canModifyCard)
{ {
bool canModifyCard = player->getPlayerInfo()->judge || card->getOwner() == player;
// Card is on the stack // Card is on the stack
if (canModifyCard) { if (canModifyCard) {
addAction(aAttach); addAction(aAttach);
@ -238,10 +222,8 @@ void CardMenu::createStackMenu()
addRelatedCardActions(); addRelatedCardActions();
} }
void CardMenu::createGraveyardOrExileMenu() void CardMenu::createGraveyardOrExileMenu(bool canModifyCard)
{ {
bool canModifyCard = player->getPlayerInfo()->judge || card->getOwner() == player;
// Card is in the graveyard or exile // Card is in the graveyard or exile
if (canModifyCard) { if (canModifyCard) {
addAction(aPlay); addAction(aPlay);
@ -270,8 +252,20 @@ void CardMenu::createGraveyardOrExileMenu()
addRelatedCardActions(); addRelatedCardActions();
} }
void CardMenu::createHandOrCustomZoneMenu() void CardMenu::createHandOrCustomZoneMenu(bool canModifyCard)
{ {
if (!canModifyCard) {
addAction(aDrawArrow);
addSeparator();
addRelatedCardView();
addRelatedCardActions();
addSeparator();
addAction(aClone);
addSeparator();
addAction(aSelectAll);
return;
}
// Card is in hand or a custom zone specified by server // Card is in hand or a custom zone specified by server
addAction(aPlay); addAction(aPlay);
addAction(aPlayFacedown); addAction(aPlayFacedown);
@ -305,6 +299,13 @@ void CardMenu::createHandOrCustomZoneMenu()
} }
} }
void CardMenu::createZonelessMenu(bool canModifyCard)
{
if (canModifyCard) {
addMenu(new MoveMenu(player));
}
}
/** /**
* @brief Populates the menu with an action for each active player. * @brief Populates the menu with an action for each active player.
* *

View file

@ -18,10 +18,11 @@ class CardMenu : public QMenu
public: public:
explicit CardMenu(Player *player, const CardItem *card, bool shortcutsActive); explicit CardMenu(Player *player, const CardItem *card, bool shortcutsActive);
void removePlayer(Player *playerToRemove); void removePlayer(Player *playerToRemove);
void createTableMenu(); void createTableMenu(bool canModifyCard);
void createStackMenu(); void createStackMenu(bool canModifyCard);
void createGraveyardOrExileMenu(); void createGraveyardOrExileMenu(bool canModifyCard);
void createHandOrCustomZoneMenu(); void createHandOrCustomZoneMenu(bool canModifyCard);
void createZonelessMenu(bool canModifyCard);
QMenu *mCardCounters; QMenu *mCardCounters;

View file

@ -0,0 +1,83 @@
#include "dlg_local_game_options.h"
#include "../../../client/settings/cache_settings.h"
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QSpinBox>
#include <QVBoxLayout>
DlgLocalGameOptions::DlgLocalGameOptions(QWidget *parent) : QDialog(parent)
{
numberPlayersLabel = new QLabel(tr("Players:"), this);
numberPlayersEdit = new QSpinBox(this);
numberPlayersEdit->setMinimum(1);
numberPlayersEdit->setMaximum(8);
numberPlayersEdit->setValue(1);
numberPlayersLabel->setBuddy(numberPlayersEdit);
auto *generalGrid = new QGridLayout;
generalGrid->addWidget(numberPlayersLabel, 0, 0);
generalGrid->addWidget(numberPlayersEdit, 0, 1);
generalGroupBox = new QGroupBox(tr("General"), this);
generalGroupBox->setLayout(generalGrid);
startingLifeTotalLabel = new QLabel(tr("Starting life total:"), this);
startingLifeTotalEdit = new QSpinBox(this);
startingLifeTotalEdit->setMinimum(1);
startingLifeTotalEdit->setMaximum(99999);
startingLifeTotalEdit->setValue(20);
startingLifeTotalLabel->setBuddy(startingLifeTotalEdit);
auto *gameSetupGrid = new QGridLayout;
gameSetupGrid->addWidget(startingLifeTotalLabel, 0, 0);
gameSetupGrid->addWidget(startingLifeTotalEdit, 0, 1);
gameSetupOptionsGroupBox = new QGroupBox(tr("Game setup options"), this);
gameSetupOptionsGroupBox->setLayout(gameSetupGrid);
rememberSettingsCheckBox = new QCheckBox(tr("Remember settings"), this);
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgLocalGameOptions::actOK);
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgLocalGameOptions::reject);
auto *mainLayout = new QVBoxLayout;
mainLayout->addWidget(generalGroupBox);
mainLayout->addWidget(gameSetupOptionsGroupBox);
mainLayout->addWidget(rememberSettingsCheckBox);
mainLayout->addWidget(buttonBox);
setLayout(mainLayout);
rememberSettingsCheckBox->setChecked(SettingsCache::instance().getLocalGameRememberSettings());
if (rememberSettingsCheckBox->isChecked()) {
numberPlayersEdit->setValue(SettingsCache::instance().getLocalGameMaxPlayers());
startingLifeTotalEdit->setValue(SettingsCache::instance().getLocalGameStartingLifeTotal());
}
setWindowTitle(tr("Local game options"));
setFixedHeight(sizeHint().height());
numberPlayersEdit->setFocus();
}
void DlgLocalGameOptions::actOK()
{
SettingsCache::instance().setLocalGameRememberSettings(rememberSettingsCheckBox->isChecked());
if (rememberSettingsCheckBox->isChecked()) {
SettingsCache::instance().setLocalGameMaxPlayers(numberPlayersEdit->value());
SettingsCache::instance().setLocalGameStartingLifeTotal(startingLifeTotalEdit->value());
}
accept();
}
LocalGameOptions DlgLocalGameOptions::getOptions() const
{
return LocalGameOptions{
.numberPlayers = numberPlayersEdit->value(),
.startingLifeTotal = startingLifeTotalEdit->value(),
};
}

View file

@ -0,0 +1,53 @@
/**
* @file dlg_local_game_options.h
* @ingroup RoomDialogs
* @brief Dialog for configuring local game options.
*
* Provides a user interface for setting up local games with configurable
* number of players and starting life total.
*/
#ifndef DLG_LOCAL_GAME_OPTIONS_H
#define DLG_LOCAL_GAME_OPTIONS_H
#include <QDialog>
struct LocalGameOptions
{
int numberPlayers = 1;
int startingLifeTotal = 20;
};
class QCheckBox;
class QDialogButtonBox;
class QGroupBox;
class QLabel;
class QSpinBox;
class DlgLocalGameOptions : public QDialog
{
Q_OBJECT
public:
explicit DlgLocalGameOptions(QWidget *parent = nullptr);
[[nodiscard]] LocalGameOptions getOptions() const;
private slots:
void actOK();
private:
QGroupBox *generalGroupBox;
QGroupBox *gameSetupOptionsGroupBox;
QLabel *numberPlayersLabel;
QSpinBox *numberPlayersEdit;
QLabel *startingLifeTotalLabel;
QSpinBox *startingLifeTotalEdit;
QCheckBox *rememberSettingsCheckBox;
QDialogButtonBox *buttonBox;
};
#endif // DLG_LOCAL_GAME_OPTIONS_H

View file

@ -27,6 +27,7 @@
#include "../interface/widgets/dialogs/dlg_forgot_password_challenge.h" #include "../interface/widgets/dialogs/dlg_forgot_password_challenge.h"
#include "../interface/widgets/dialogs/dlg_forgot_password_request.h" #include "../interface/widgets/dialogs/dlg_forgot_password_request.h"
#include "../interface/widgets/dialogs/dlg_forgot_password_reset.h" #include "../interface/widgets/dialogs/dlg_forgot_password_reset.h"
#include "../interface/widgets/dialogs/dlg_local_game_options.h"
#include "../interface/widgets/dialogs/dlg_manage_sets.h" #include "../interface/widgets/dialogs/dlg_manage_sets.h"
#include "../interface/widgets/dialogs/dlg_register.h" #include "../interface/widgets/dialogs/dlg_register.h"
#include "../interface/widgets/dialogs/dlg_settings.h" #include "../interface/widgets/dialogs/dlg_settings.h"
@ -49,7 +50,6 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QFile> #include <QFile>
#include <QFileDialog> #include <QFileDialog>
#include <QInputDialog>
#include <QMenu> #include <QMenu>
#include <QMenuBar> #include <QMenuBar>
#include <QMessageBox> #include <QMessageBox>
@ -225,16 +225,15 @@ void MainWindow::actDisconnect()
void MainWindow::actSinglePlayer() void MainWindow::actSinglePlayer()
{ {
bool ok; DlgLocalGameOptions dlg(this);
int numberPlayers = if (dlg.exec() != QDialog::Accepted) {
QInputDialog::getInt(this, tr("Number of players"), tr("Please enter the number of players."), 1, 1, 8, 1, &ok);
if (!ok)
return; return;
}
startLocalGame(numberPlayers); startLocalGame(dlg.getOptions());
} }
void MainWindow::startLocalGame(int numberPlayers) void MainWindow::startLocalGame(const LocalGameOptions &options)
{ {
aConnect->setEnabled(false); aConnect->setEnabled(false);
aRegister->setEnabled(false); aRegister->setEnabled(false);
@ -248,7 +247,7 @@ void MainWindow::startLocalGame(int numberPlayers)
QList<AbstractClient *> localClients; QList<AbstractClient *> localClients;
localClients.append(mainClient); localClients.append(mainClient);
for (int i = 0; i < numberPlayers - 1; ++i) { for (int i = 0; i < options.numberPlayers - 1; ++i) {
LocalServerInterface *slaveLsi = localServer->newConnection(); LocalServerInterface *slaveLsi = localServer->newConnection();
LocalClient *slaveClient = LocalClient *slaveClient =
new LocalClient(slaveLsi, tr("Player %1").arg(i + 2), SettingsCache::instance().getClientID(), this); new LocalClient(slaveLsi, tr("Player %1").arg(i + 2), SettingsCache::instance().getClientID(), this);
@ -257,7 +256,8 @@ void MainWindow::startLocalGame(int numberPlayers)
tabSupervisor->startLocal(localClients); tabSupervisor->startLocal(localClients);
Command_CreateGame createCommand; Command_CreateGame createCommand;
createCommand.set_max_players(static_cast<google::protobuf::uint32>(numberPlayers)); createCommand.set_max_players(static_cast<google::protobuf::uint32>(options.numberPlayers));
createCommand.set_starting_life_total(options.startingLifeTotal);
mainClient->sendCommand(LocalClient::prepareRoomCommand(createCommand, 0)); mainClient->sendCommand(LocalClient::prepareRoomCommand(createCommand, 0));
} }
@ -913,7 +913,9 @@ MainWindow::MainWindow(QWidget *parent)
void MainWindow::startupConfigCheck() void MainWindow::startupConfigCheck()
{ {
if (SettingsCache::instance().debug().getLocalGameOnStartup()) { if (SettingsCache::instance().debug().getLocalGameOnStartup()) {
startLocalGame(SettingsCache::instance().debug().getLocalGamePlayerCount()); LocalGameOptions options;
options.numberPlayers = SettingsCache::instance().debug().getLocalGamePlayerCount();
startLocalGame(options);
} }
if (SettingsCache::instance().getCheckUpdatesOnStartup()) { if (SettingsCache::instance().getCheckUpdatesOnStartup()) {

View file

@ -25,6 +25,8 @@
#ifndef WINDOW_H #ifndef WINDOW_H
#define WINDOW_H #define WINDOW_H
#include "widgets/dialogs/dlg_local_game_options.h"
#include <QList> #include <QList>
#include <QMainWindow> #include <QMainWindow>
#include <QMessageBox> #include <QMessageBox>
@ -137,7 +139,7 @@ private:
void createCardUpdateProcess(bool background = false); void createCardUpdateProcess(bool background = false);
void exitCardDatabaseUpdate(); void exitCardDatabaseUpdate();
void startLocalGame(int numberPlayers); void startLocalGame(const LocalGameOptions &options);
QList<QMenu *> tabMenus; QList<QMenu *> tabMenus;
QMenu *cockatriceMenu, *dbMenu, *tabsMenu, *helpMenu, *trayIconMenu; QMenu *cockatriceMenu, *dbMenu, *tabsMenu, *helpMenu, *trayIconMenu;

View file

@ -173,7 +173,7 @@ e pedine che verranno usate da Cockatrice.</translation>
<message> <message>
<location filename="src/pages.cpp" line="726"/> <location filename="src/pages.cpp" line="726"/>
<source>spoiler</source> <source>spoiler</source>
<translation type="unfinished"/> <translation>spoiler</translation>
</message> </message>
<message> <message>
<location filename="src/pages.cpp" line="731"/> <location filename="src/pages.cpp" line="731"/>
@ -193,7 +193,7 @@ e pedine che verranno usate da Cockatrice.</translation>
<message> <message>
<location filename="src/pages.cpp" line="735"/> <location filename="src/pages.cpp" line="735"/>
<source>Local file:</source> <source>Local file:</source>
<translation type="unfinished"/> <translation>File nel pc:</translation>
</message> </message>
<message> <message>
<location filename="src/pages.cpp" line="736"/> <location filename="src/pages.cpp" line="736"/>
@ -203,7 +203,7 @@ e pedine che verranno usate da Cockatrice.</translation>
<message> <message>
<location filename="src/pages.cpp" line="737"/> <location filename="src/pages.cpp" line="737"/>
<source>Choose file...</source> <source>Choose file...</source>
<translation type="unfinished"/> <translation>Scegli file...</translation>
</message> </message>
<message> <message>
<location filename="src/pages.cpp" line="739"/> <location filename="src/pages.cpp" line="739"/>
@ -231,7 +231,7 @@ e pedine che verranno usate da Cockatrice.</translation>
<message> <message>
<location filename="src/pages.cpp" line="681"/> <location filename="src/pages.cpp" line="681"/>
<source>tokens</source> <source>tokens</source>
<translation type="unfinished"/> <translation>pedine</translation>
</message> </message>
<message> <message>
<location filename="src/pages.cpp" line="686"/> <location filename="src/pages.cpp" line="686"/>
@ -251,7 +251,7 @@ e pedine che verranno usate da Cockatrice.</translation>
<message> <message>
<location filename="src/pages.cpp" line="690"/> <location filename="src/pages.cpp" line="690"/>
<source>Local file:</source> <source>Local file:</source>
<translation type="unfinished"/> <translation>File nel pc:</translation>
</message> </message>
<message> <message>
<location filename="src/pages.cpp" line="691"/> <location filename="src/pages.cpp" line="691"/>
@ -261,7 +261,7 @@ e pedine che verranno usate da Cockatrice.</translation>
<message> <message>
<location filename="src/pages.cpp" line="692"/> <location filename="src/pages.cpp" line="692"/>
<source>Choose file...</source> <source>Choose file...</source>
<translation type="unfinished"/> <translation>Scegli file...</translation>
</message> </message>
<message> <message>
<location filename="src/pages.cpp" line="694"/> <location filename="src/pages.cpp" line="694"/>
@ -392,12 +392,12 @@ e pedine che verranno usate da Cockatrice.</translation>
<message> <message>
<location filename="src/pagetemplates.cpp" line="72"/> <location filename="src/pagetemplates.cpp" line="72"/>
<source>Load %1 file</source> <source>Load %1 file</source>
<translation type="unfinished"/> <translation>Carica %1 file</translation>
</message> </message>
<message> <message>
<location filename="src/pagetemplates.cpp" line="82"/> <location filename="src/pagetemplates.cpp" line="82"/>
<source>%1 file (%1)</source> <source>%1 file (%1)</source>
<translation type="unfinished"/> <translation>%1 file (%1)</translation>
</message> </message>
<message> <message>
<location filename="src/pagetemplates.cpp" line="111"/> <location filename="src/pagetemplates.cpp" line="111"/>
@ -421,12 +421,12 @@ e pedine che verranno usate da Cockatrice.</translation>
<message> <message>
<location filename="src/pagetemplates.cpp" line="129"/> <location filename="src/pagetemplates.cpp" line="129"/>
<source>Please choose a file.</source> <source>Please choose a file.</source>
<translation type="unfinished"/> <translation>Seleziona un file.</translation>
</message> </message>
<message> <message>
<location filename="src/pagetemplates.cpp" line="134"/> <location filename="src/pagetemplates.cpp" line="134"/>
<source>Cannot open file &apos;%1&apos;.</source> <source>Cannot open file &apos;%1&apos;.</source>
<translation type="unfinished"/> <translation>Impossibile aprire il file &apos;%1&apos;.</translation>
</message> </message>
<message> <message>
<location filename="src/pagetemplates.cpp" line="159"/> <location filename="src/pagetemplates.cpp" line="159"/>