From: <ste...@us...> - 2010-07-05 18:02:20
|
Revision: 1333 http://rails.svn.sourceforge.net/rails/?rev=1333&view=rev Author: stefanfrey Date: 2010-07-05 18:02:13 +0000 (Mon, 05 Jul 2010) Log Message: ----------- Added autosave for game recovery Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/my.properties trunk/18xx/rails/game/DisplayBuffer.java trunk/18xx/rails/game/GameManager.java trunk/18xx/rails/ui/swing/GameSetupWindow.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-07-04 20:51:33 UTC (rev 1332) +++ trunk/18xx/LocalisedText.properties 2010-07-05 18:02:13 UTC (rev 1333) @@ -416,6 +416,9 @@ Pullman=Pullman-Car QUIT=Quit RandomizePlayers=Randomize Order +RecoverGame=Recover Previous Game +RecoverySaveFailed=Recovery save failed, reason: {0} +RecoverySaveSuccessAgain=Recovery save succeeded REDO=Redo ReleasedFromEscrow={0} receives {1} released from bank escrow ReleasesTrains=Makes {0}-trains available for purchasing Modified: trunk/18xx/my.properties =================================================================== --- trunk/18xx/my.properties 2010-07-04 20:51:33 UTC (rev 1332) +++ trunk/18xx/my.properties 2010-07-05 18:02:13 UTC (rev 1333) @@ -58,6 +58,12 @@ # The default extension is .rails #save.filename.extension=rails +### AutoSave for game recovery +# Activation of autosave (default is yes) +# save.recovery.active=yes +# Filepath for autosave (default is 18xx_autosave.rails in current working directory +# save.recovery.filepath=18xx_autosave.rails + ### Game report directory # If the below entry exists, is not empty, and specifies an existing # directory, a copy of the Game Report (as displayed in the Report Window) Modified: trunk/18xx/rails/game/DisplayBuffer.java =================================================================== --- trunk/18xx/rails/game/DisplayBuffer.java 2010-07-04 20:51:33 UTC (rev 1332) +++ trunk/18xx/rails/game/DisplayBuffer.java 2010-07-05 18:02:13 UTC (rev 1333) @@ -73,13 +73,26 @@ } private static DisplayBuffer getInstance() { - return GameManager.getInstance().getDisplayBuffer(); + GameManagerI gm = GameManager.getInstance(); + if (gm == null) { + return null; + } else { + return gm.getDisplayBuffer(); + } } /** Get the current message buffer, and clear it */ public static String[] get() { DisplayBuffer instance = getInstance(); - if (instance.displayBuffer.size() > 0) { + if (instance == null) { + if (initialQueue.isEmpty()) { + return null; + } else { + String[] message = initialQueue.toArray(new String[0]); + initialQueue.clear(); + return message; + } + } else if (instance.displayBuffer.size() > 0) { String[] message = instance.displayBuffer.toArray(new String[0]); instance.displayBuffer.clear(); return message; Modified: trunk/18xx/rails/game/GameManager.java =================================================================== --- trunk/18xx/rails/game/GameManager.java 2010-07-04 20:51:33 UTC (rev 1332) +++ trunk/18xx/rails/game/GameManager.java 2010-07-05 18:02:13 UTC (rev 1333) @@ -187,6 +187,9 @@ /** A List of available game options */ protected List<GameOption> availableGameOptions = new ArrayList<GameOption>(); + + /** indicates that the recoverySave already issued a warning, avoids displaying several warnings */ + protected boolean recoverySaveWarning = true; protected static Logger log = Logger.getLogger(GameManager.class.getPackage().getName()); @@ -810,6 +813,7 @@ if (action != null) { if (result && !(action instanceof GameAction) && action.hasActed()) { if (moveStack.isOpen()) moveStack.finish(); + recoverySave(); } else { if (moveStack.isOpen()) moveStack.cancel(); } @@ -929,15 +933,72 @@ return true; } + /** recoverySave method + * Uses filePath defined in save.recovery.filepath + * */ + protected void recoverySave() { + if (Config.get("save.recovery.active", "yes").equalsIgnoreCase("no")) return; + + String filePath = Config.get("save.recovery.filepath", "18xx_autosave.rails"); + // create temporary new save file + File tempFile = null; + tempFile = new File(filePath + ".tmp"); + if (!save(tempFile, recoverySaveWarning, "RecoverySaveFailed")) { + recoverySaveWarning = false; + return; + } + + // rename the temp file to the recover file + File recoveryFile = null; + boolean result; + try { + log.debug("Created temporary recovery file, path = " + tempFile.getAbsolutePath()); + // check if previous save file exists + recoveryFile = new File(filePath); + log.debug("Potential recovery filePath = " + recoveryFile.getAbsolutePath()); + if (recoveryFile.exists()) { + log.debug("Potential recovery filePath = " + recoveryFile.getAbsolutePath()); + File backupFile = new File(filePath + ".bak"); + if (recoveryFile.renameTo(backupFile)) { + result = tempFile.renameTo(recoveryFile); + } else { + result = backupFile.renameTo(recoveryFile); + } + } else { + log.debug("Tries to rename temporary file"); + result = tempFile.renameTo(recoveryFile); + } + } catch (Exception e) { + DisplayBuffer.add(LocalText.getText("RecoverySaveFailed", e.getMessage())); + recoverySaveWarning = false; + return; + } + + if (result) { + log.debug("Renamed to recovery file, path = " + recoveryFile.getAbsolutePath()); + if (!recoverySaveWarning) { + DisplayBuffer.add(LocalText.getText("RecoverySaveSuccessAgain")); + recoverySaveWarning = true; + } + } else { + if (recoverySaveWarning) { + DisplayBuffer.add(LocalText.getText("RecoverySaveFailed", "file renaming not possible")); + recoverySaveWarning = false; + } + } + } + protected boolean save(GameAction saveAction) { - - String filepath = saveAction.getFilepath(); + File file = new File(saveAction.getFilepath()); + return save(file, true, "SaveFailed"); + } + + protected boolean save(File file, boolean displayErrorMessage, String errorMessageKey) { boolean result = false; try { ObjectOutputStream oos = - new ObjectOutputStream(new FileOutputStream(new File( - filepath))); + new ObjectOutputStream(new FileOutputStream(file)); oos.writeObject(Game.version+" "+BuildInfo.buildDate); oos.writeObject(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); oos.writeObject(saveFileVersionID); @@ -949,10 +1010,11 @@ result = true; } catch (IOException e) { - log.error("Save failed", e); - DisplayBuffer.add(LocalText.getText("SaveFailed", e.getMessage())); + log.error(errorMessageKey, e); + if (displayErrorMessage) { + DisplayBuffer.add(LocalText.getText("SaveFailed", e.getMessage())); + } } - return result; } Modified: trunk/18xx/rails/ui/swing/GameSetupWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/GameSetupWindow.java 2010-07-04 20:51:33 UTC (rev 1332) +++ trunk/18xx/rails/ui/swing/GameSetupWindow.java 2010-07-05 18:02:13 UTC (rev 1333) @@ -25,7 +25,7 @@ private static final long serialVersionUID = 1L; GridBagConstraints gc; JPanel gameListPane, playersPane, buttonPane, optionsPane; - JButton newButton, loadButton, quitButton, optionButton, infoButton; + JButton newButton, loadButton, recoveryButton, quitButton, optionButton, infoButton; JButton creditsButton, randomizeButton; JComboBox gameNameBox = new JComboBox(); JComboBox[] playerBoxes = new JComboBox[Player.MAX_PLAYERS]; @@ -66,6 +66,7 @@ newButton = new JButton(LocalText.getText("NewGame")); loadButton = new JButton(LocalText.getText("LoadGame")); + recoveryButton = new JButton(LocalText.getText("RecoverGame")); quitButton = new JButton(LocalText.getText("QUIT")); optionButton = new JButton(LocalText.getText("OPTIONS")); infoButton = new JButton(LocalText.getText("INFO")); @@ -73,6 +74,7 @@ newButton.setMnemonic(KeyEvent.VK_N); loadButton.setMnemonic(KeyEvent.VK_L); + recoveryButton.setMnemonic(KeyEvent.VK_R); quitButton.setMnemonic(KeyEvent.VK_Q); optionButton.setMnemonic(KeyEvent.VK_O); infoButton.setMnemonic(KeyEvent.VK_G); @@ -85,12 +87,15 @@ populateGameList(GamesInfo.getGameNames(), gameNameBox); gameListPane.add(new JLabel("Available Games:")); + gameListPane.add(new JLabel("")); // empty slot gameListPane.add(gameNameBox); + gameListPane.add(optionButton); gameListPane.setLayout(new GridLayout(2, 2)); gameListPane.setBorder(BorderFactory.createLoweredBevelBorder()); newButton.addActionListener(this); loadButton.addActionListener(this); + recoveryButton.addActionListener(this); quitButton.addActionListener(this); optionButton.addActionListener(this); infoButton.addActionListener(this); @@ -99,7 +104,9 @@ buttonPane.add(newButton); buttonPane.add(loadButton); - buttonPane.add(optionButton); + if (!Config.get("save.recovery.active", "yes").equalsIgnoreCase("no")) { + buttonPane.add(recoveryButton); + } buttonPane.add(infoButton); buttonPane.add(quitButton); buttonPane.add(creditsButton); @@ -187,6 +194,26 @@ } } + /* + * loads and start the game given a filename + */ + private void loadAndStartGame(String filePath, String saveDirectory) { + if ((game = Game.load(filePath)) == null) { + JOptionPane.showMessageDialog(this, + DisplayBuffer.get(), "", JOptionPane.ERROR_MESSAGE); + return; + } else if (DisplayBuffer.getSize() > 0) { + JOptionPane.showMessageDialog(this, + DisplayBuffer.get(), "", JOptionPane.ERROR_MESSAGE); + } + startGameUIManager(game); + if (saveDirectory != null) { + gameUIManager.setSaveDirectory (saveDirectory); + } + gameUIManager.startLoadedGame(); + setVisible(false); + } + public void actionPerformed(ActionEvent arg0) { if (arg0.getSource().equals(newButton)) { startNewGame(); @@ -200,24 +227,13 @@ if (jfc.showOpenDialog(getContentPane()) == JFileChooser.APPROVE_OPTION) { File selectedFile = jfc.getSelectedFile(); - String filepath = selectedFile.getPath(); - saveDirectory = selectedFile.getParent(); - if ((game = Game.load(filepath)) == null) { - JOptionPane.showMessageDialog(this, - DisplayBuffer.get(), "", JOptionPane.ERROR_MESSAGE); - return; - } else if (DisplayBuffer.getSize() > 0) { - JOptionPane.showMessageDialog(this, - DisplayBuffer.get(), "", JOptionPane.ERROR_MESSAGE); - } + loadAndStartGame(selectedFile.getPath(), selectedFile.getParent()); } else { // cancel pressed return; } - - startGameUIManager(game); - gameUIManager.setSaveDirectory (saveDirectory); - gameUIManager.startLoadedGame(); - setVisible(false); + } else if (arg0.getSource().equals(recoveryButton)) { + String filePath = Config.get("save.recovery.filepath", "18xx_autosave.rails"); + loadAndStartGame(filePath, null); } else if (arg0.getSource().equals(infoButton)) { JOptionPane.showMessageDialog(this, GamesInfo.getDescription(gameName), "Information about " This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-07-10 17:02:45
|
Revision: 1334 http://rails.svn.sourceforge.net/rails/?rev=1334&view=rev Author: stefanfrey Date: 2010-07-10 17:02:39 +0000 (Sat, 10 Jul 2010) Log Message: ----------- Fixed the following bugs/requests: 18EU minor company initial sale problem - ID: 3021157 - Renamed pass to decline to bid Autopass during minor auction in 18EU - ID: 2899354 - General autopass in GameManager if only Pass Action is available Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/rails/game/GameManager.java trunk/18xx/rails/game/action/NullAction.java trunk/18xx/rails/game/action/PossibleActions.java trunk/18xx/rails/game/specific/_18EU/StartRound_18EU.java trunk/18xx/rails/ui/swing/StartRoundWindow.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-07-05 18:02:13 UTC (rev 1333) +++ trunk/18xx/LocalisedText.properties 2010-07-10 17:02:39 UTC (rev 1334) @@ -157,6 +157,7 @@ CorrectionModeActivate={1} activated by {0} CorrectionModeDeactivate={1} deactivated by {0} CREDITS=Credits +DeclineToBid=Decline to Bid DestinationReachedByToken={0} gains {1} by laying a token on its destination {2} DestinationReached={0} has reached its destination hex {1} DestinationsReached=Destinations reached @@ -385,6 +386,7 @@ PRICE_STAYS_LOG={0} price stays at {1}({2}). PRIVATES=Privates PaysLoanInterest={0} pays {1} interest for outstanding loans +Pass=Pass PhaseClosesAllPrivates=Close all privates PhaseNumberOfORs=Number of ORs: {0} PhaseOffBoardStep=Off-board revenue step: {0} Modified: trunk/18xx/rails/game/GameManager.java =================================================================== --- trunk/18xx/rails/game/GameManager.java 2010-07-05 18:02:13 UTC (rev 1333) +++ trunk/18xx/rails/game/GameManager.java 2010-07-10 17:02:39 UTC (rev 1334) @@ -808,6 +808,11 @@ possibleActions.clear(); getCurrentRound().setPossibleActions(); + // only pass available => execute automatically + if (!isGameOver() && possibleActions.containsOnlyPass()) { + result = process(possibleActions.getList().get(0)); + } + // moveStack closing is done here to allow state changes to occur // when setting possible actions if (action != null) { Modified: trunk/18xx/rails/game/action/NullAction.java =================================================================== --- trunk/18xx/rails/game/action/NullAction.java 2010-07-05 18:02:13 UTC (rev 1333) +++ trunk/18xx/rails/game/action/NullAction.java 2010-07-10 17:02:39 UTC (rev 1334) @@ -10,9 +10,12 @@ public static final int START_GAME = 4; // For use after loading public static final int MAX_MODE = 4; + // optional label that is returned on toString instead of the standard labels defined below + private String optionalLabel = null; + + // standard labels defined private static String[] name = new String[] { "Done", "Pass", "Skip", "Autopass", "StartGame" }; - protected int mode = -1; public static final long serialVersionUID = 2L; @@ -26,6 +29,12 @@ public int getMode() { return mode; } + + /** returns the NullAction itself */ + public NullAction setLabel(String label) { + this.optionalLabel = label; + return this; + } @Override public boolean equals(PossibleAction action) { @@ -36,6 +45,8 @@ @Override public String toString() { + if (optionalLabel != null) return optionalLabel; return name[mode]; } + } Modified: trunk/18xx/rails/game/action/PossibleActions.java =================================================================== --- trunk/18xx/rails/game/action/PossibleActions.java 2010-07-05 18:02:13 UTC (rev 1333) +++ trunk/18xx/rails/game/action/PossibleActions.java 2010-07-10 17:02:39 UTC (rev 1334) @@ -82,6 +82,16 @@ public boolean isEmpty() { return possibleActions.isEmpty(); } + + public boolean containsOnlyPass() { + if (possibleActions.size() != 1) return false; + PossibleAction action = possibleActions.get(0); + if (action instanceof NullAction && ((NullAction)action).getMode() == NullAction.PASS) { + return true; + } else { + return false; + } + } /** Check if a given action exists in the current list of possible actions */ public boolean validate(PossibleAction checkedAction) { Modified: trunk/18xx/rails/game/specific/_18EU/StartRound_18EU.java =================================================================== --- trunk/18xx/rails/game/specific/_18EU/StartRound_18EU.java 2010-07-05 18:02:13 UTC (rev 1333) +++ trunk/18xx/rails/game/specific/_18EU/StartRound_18EU.java 2010-07-10 17:02:39 UTC (rev 1334) @@ -56,7 +56,6 @@ public boolean setPossibleActions() { possibleActions.clear(); - boolean passAllowed = false; // Refresh player, may have been reset by Undo/Redo currentPlayer = getCurrentPlayer(); @@ -81,31 +80,33 @@ } } break; - case BUY_STEP: - - possibleActions.add(new BuyStartItem( - (StartItem) currentAuctionItem.getObject(), - currentBuyPrice.intValue(), true)); - passAllowed = true; - + // only offer buy if enough money + if (currentBuyPrice.intValue() <= currentPlayer.getFreeCash()) { + possibleActions.add(new BuyStartItem( + (StartItem) currentAuctionItem.getObject(), + currentBuyPrice.intValue(), true)); + } + possibleActions.add(new NullAction(NullAction.PASS)); break; - case OPEN_STEP: case BID_STEP: - StartItem item = (StartItem) currentAuctionItem.getObject(); - BidStartItem possibleAction = + // only offer if enough money + if (item.getMinimumBid() <= currentPlayer.getFreeCash()) { + BidStartItem possibleAction = new BidStartItem(item, item.getMinimumBid(), startPacket.getModulus(), true); - possibleActions.add(possibleAction); - passAllowed = true; - + possibleActions.add(possibleAction); + } + if (getStep() == OPEN_STEP) { + possibleActions.add(new NullAction(NullAction.PASS).setLabel("DeclineToBid")); + } else { + possibleActions.add(new NullAction(NullAction.PASS)); + } break; } - if (passAllowed) possibleActions.add(new NullAction(NullAction.PASS)); - return true; } Modified: trunk/18xx/rails/ui/swing/StartRoundWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/StartRoundWindow.java 2010-07-05 18:02:13 UTC (rev 1333) +++ trunk/18xx/rails/ui/swing/StartRoundWindow.java 2010-07-10 17:02:39 UTC (rev 1334) @@ -103,7 +103,7 @@ private final boolean includeBidding; private final boolean showBasePrices; - private boolean repacked = false; +// private boolean repacked = false; protected static Logger log = Logger.getLogger(StartRoundWindow.class.getPackage().getName()); @@ -464,18 +464,14 @@ List<NullAction> inactiveItems = possibleActions.getType(NullAction.class); - if (inactiveItems != null) { - - for (NullAction na : inactiveItems) { - switch (na.getMode()) { - case NullAction.PASS: - passButton.setText(LocalText.getText("PASS")); - passAllowed = true; - passButton.setPossibleAction(na); - passButton.setMnemonic(KeyEvent.VK_P); - break; - } - } + if (inactiveItems != null && !inactiveItems.isEmpty()) { + // only one NullAction is allowed + NullAction na = inactiveItems.get(0); + // nullActions differ in text to display + passButton.setText(LocalText.getText(na.toString())); + passAllowed = true; + passButton.setPossibleAction(na); + passButton.setMnemonic(KeyEvent.VK_P); } buyButton.setEnabled(buyAllowed); @@ -485,6 +481,7 @@ } passButton.setEnabled(passAllowed); + pack(); // to avoid not displaying after label size changes requestFocus(); } @@ -538,10 +535,10 @@ passButton.setEnabled(true); passButton.setText(LocalText.getText("SelectNoBid")); passButton.setVisible(true); - if (!repacked) { +// if (!repacked) { pack(); - repacked = true; - } +// repacked = true; +// } } if (includeBidding) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-07-10 22:25:16
|
Revision: 1335 http://rails.svn.sourceforge.net/rails/?rev=1335&view=rev Author: stefanfrey Date: 2010-07-10 22:25:10 +0000 (Sat, 10 Jul 2010) Log Message: ----------- Fixed bug 18AL delayed obsolecence in report window - ID: 3026083 - Added report text after obsoletion and delayed rusting. Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/rails/game/Portfolio.java trunk/18xx/rails/game/TrainManager.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-07-10 17:02:39 UTC (rev 1334) +++ trunk/18xx/LocalisedText.properties 2010-07-10 22:25:10 UTC (rev 1335) @@ -534,6 +534,8 @@ TRADE_TREASURY_SHARES_TITLE=Rails: Game Status - TRADING TREASURY SHARES OF COMPANY {0} TrainInfo={0}-train, price: {1}, quantity: {2} TrainsAvailable={0}-trains are now available. +TrainsObsolete=All {0}-trains are obsolete and will be removed after the next run. +TrainsObsoleteRusted=Obsolete Train {0} of company {1} rusted. TrainsRusted=All {0}-trains have rusted and have been removed. TREASURY_SHARES=<html>Treasury<br>shares TreasuryOverHoldLimit=Treasury would get over the {0}% hold limit Modified: trunk/18xx/rails/game/Portfolio.java =================================================================== --- trunk/18xx/rails/game/Portfolio.java 2010-07-10 17:02:39 UTC (rev 1334) +++ trunk/18xx/rails/game/Portfolio.java 2010-07-10 22:25:10 UTC (rev 1335) @@ -721,6 +721,8 @@ // Need to separate selection and execution, // otherwise we get a ConcurrentModificationException on trains. for (TrainI train : trainsToRust) { + ReportBuffer.add(LocalText.getText("TrainsObsoleteRusted", + train.getName(), name)); log.debug("Obsolete train " + train.getUniqueId() + " (owned by " + name + ") rusted"); train.setRusted(); Modified: trunk/18xx/rails/game/TrainManager.java =================================================================== --- trunk/18xx/rails/game/TrainManager.java 2010-07-10 17:02:39 UTC (rev 1334) +++ trunk/18xx/rails/game/TrainManager.java 2010-07-10 22:25:10 UTC (rev 1335) @@ -161,9 +161,14 @@ TrainTypeI rustedType = boughtType.getRustedTrainType(); if (rustedType != null && !rustedType.hasRusted()) { rustedType.setRusted(train.getHolder()); // Or obsolete, - // where applicable - ReportBuffer.add(LocalText.getText("TrainsRusted", + // where applicable + if (rustedType.isObsoleting()) { + ReportBuffer.add(LocalText.getText("TrainsObsolete", + rustedType.getName())); + } else { + ReportBuffer.add(LocalText.getText("TrainsRusted", rustedType.getName())); + } trainsHaveRusted = true; trainAvailabilityChanged = true; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-07-16 20:37:39
|
Revision: 1338 http://rails.svn.sourceforge.net/rails/?rev=1338&view=rev Author: stefanfrey Date: 2010-07-16 20:37:33 +0000 (Fri, 16 Jul 2010) Log Message: ----------- Started configuration window/item implementation Modified Paths: -------------- trunk/18xx/rails/test/GameTest.java trunk/18xx/rails/ui/swing/StatusWindow.java trunk/18xx/rails/util/Config.java trunk/18xx/rails/util/ListAndFixSavedFiles.java trunk/18xx/rails/util/RunGame.java trunk/18xx/test/TestGameBuilder.java Added Paths: ----------- trunk/18xx/default.profiles trunk/18xx/log4j.properties trunk/18xx/rails/ui/swing/ConfigWindow.java trunk/18xx/rails/util/ConfigItem.java trunk/18xx/user.profiles Added: trunk/18xx/default.profiles =================================================================== --- trunk/18xx/default.profiles (rev 0) +++ trunk/18xx/default.profiles 2010-07-16 20:37:33 UTC (rev 1338) @@ -0,0 +1,2 @@ +default=my.properties +test=test/test.properties Added: trunk/18xx/log4j.properties =================================================================== --- trunk/18xx/log4j.properties (rev 0) +++ trunk/18xx/log4j.properties 2010-07-16 20:37:33 UTC (rev 1338) @@ -0,0 +1,23 @@ +####################### Log4J properties ############################## +# For information on how to customise log4j logging, see for instance +# http://www.vipan.com/htdocs/log4jhelp.html +# It's a bit outdated: Category is now named Logger, +# and Priority is now named Level. +# But it's the best intro I know on how to configure Appenders. (EV) +####################################################################### +# Set root logger level to DEBUG and use appender F(file) +#log4j.debug=true +log4j.rootLogger=DEBUG, F +log4j.logger.rails.algorithms=INFO + +# Define the Log file appender +log4j.appender.F=org.apache.log4j.FileAppender + +# Log file properties +log4j.appender.F.File=18xx.log +log4j.appender.F.append=false + +# Log file layout +log4j.appender.F.layout=org.apache.log4j.PatternLayout +log4j.appender.F.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n +################## End of Log4J properties ############################# Modified: trunk/18xx/rails/test/GameTest.java =================================================================== --- trunk/18xx/rails/test/GameTest.java 2010-07-11 16:44:29 UTC (rev 1337) +++ trunk/18xx/rails/test/GameTest.java 2010-07-16 20:37:33 UTC (rev 1338) @@ -2,35 +2,14 @@ import rails.ui.swing.GameSetupWindow; import rails.util.Config; -import rails.util.Util; public class GameTest { - /** The default properties file name */ - private static String DEFAULT_CONFIG_FILE = "my.properties"; public static void main(String[] args) { - /* - * Check if the property file has been set on the command line. The way - * to do this is adding an option to the java command: -Dconfigfile=<property-filename> - */ - String myConfigFile = System.getProperty("configfile"); - System.out.println("Cmdline configfile setting = " + myConfigFile); - - /* If not, use the default configuration file name */ - if (!Util.hasValue(myConfigFile)) { - myConfigFile = DEFAULT_CONFIG_FILE; - } - - /* - * Set the system property that tells log4j to use this file. (Note: - * this MUST be done before updating Config) - */ - System.setProperty("log4j.configuration", myConfigFile); - /* Tell the properties loader to read this file. */ - Config.setConfigFile(myConfigFile); - System.out.println("Configuration file = " + myConfigFile); - + // intialize configuration + Config.setConfigSelection(); + int nargs = 0; if (args != null && args.length > 0) { for (String arg : args) { Added: trunk/18xx/rails/ui/swing/ConfigWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ConfigWindow.java (rev 0) +++ trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-16 20:37:33 UTC (rev 1338) @@ -0,0 +1,144 @@ +package rails.ui.swing; + +import java.awt.Color; +import java.awt.Component; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Map; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JColorChooser; +import javax.swing.JComponent; +import javax.swing.JFormattedTextField; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; + +import rails.util.Config; +import rails.util.ConfigItem; +import rails.util.LocalText; + +class ConfigWindow extends JFrame { + private static final long serialVersionUID = 1L; + + private JTabbedPane pane; + + ConfigWindow() { + // JFrame properties + setTitle(LocalText.getText("ConfigWindowTitle")); +// setSize(400,300); + + // add profile panel + add(setupProfilePanel(), "North"); + + // configSetup pane + setupConfigPane(); + add(pane, "Center"); + + // buttons + JPanel buttonPanel = new JPanel(); + + JButton saveButton = new JButton(LocalText.getText("Save")); + saveButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + ConfigWindow.this.saveConfig(); + } + } + ); + buttonPanel.add(saveButton); + + JButton cancelButton = new JButton(LocalText.getText("Cancel")); + cancelButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + ConfigWindow.this.cancelConfig(); + } + } + ); + buttonPanel.add(cancelButton); + + add(buttonPanel, "South"); + + this.pack(); + } + + + private JComponent setupProfilePanel() { + JComponent panel = new JPanel(); + panel.setLayout(new GridLayout(0,4)); + + // default profile + + + return panel; + } + + private void setupConfigPane() { + // create pane + pane = new JTabbedPane(); + + Map<String, List<ConfigItem>> configPanels = Config.getConfigPanels(); + + for (String panelName:configPanels.keySet()) { + JPanel newPanel = new JPanel(); + newPanel.setLayout(new GridLayout(0,3)); + for (ConfigItem item:configPanels.get(panelName)) { + defineElement(newPanel, item); + } + pane.addTab(panelName, newPanel); + } + } + + private void defineElement(JPanel panel, ConfigItem item) { + + panel.add(new JLabel(LocalText.getText("Config." + item.name))); + + final String configValue = Config.get(item.name); + switch (item.type) { + case COLOR: { + final JLabel label = new JLabel(configValue); + Color selectedColor; + try { + selectedColor = Color.decode(configValue); + } catch (NumberFormatException e) { + selectedColor = Color.WHITE; + } + label.setOpaque(true); + label.setBackground(selectedColor); + panel.add(label); + JButton button = new JButton("Color"); + final Color oldColor = selectedColor; + button.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + Color selectedColor=JColorChooser.showDialog(ConfigWindow.this, "", oldColor); + label.setText(Integer.toHexString(selectedColor.getRGB()).substring(2)); + label.setBackground(selectedColor); + } + } + ); + panel.add(button); + break; + } + case STRING: + default: { + JFormattedTextField textField = new JFormattedTextField(); + textField.setValue(configValue); + panel.add(textField); + } + } + } + + private void saveConfig() { + this.dispose(); + } + + private void cancelConfig() { + this.dispose(); + } + +} Modified: trunk/18xx/rails/ui/swing/StatusWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/StatusWindow.java 2010-07-11 16:44:29 UTC (rev 1337) +++ trunk/18xx/rails/ui/swing/StatusWindow.java 2010-07-16 20:37:33 UTC (rev 1338) @@ -3,6 +3,8 @@ import java.awt.BorderLayout; import java.awt.Color; +//import java.awt.GraphicsConfiguration; +//import java.awt.Rectangle; import java.awt.event.*; import java.util.ArrayList; import java.util.Collections; @@ -48,6 +50,8 @@ protected static final String REPORT_CMD = "Report"; + protected static final String CONFIG_CMD = "Config"; + protected static final String BUY_CMD = "Buy"; protected static final String SELL_CMD = "Sell"; @@ -80,13 +84,21 @@ private JMenuItem menuItem; - private ActionMenuItem saveItem, exportItem; + private ActionMenuItem saveItem; +// private ActionMenuItem exportItem; private ActionMenuItem undoItem, forcedUndoItem, redoItem, redoItem2; protected static Logger log = Logger.getLogger(StatusWindow.class.getPackage().getName()); +// GraphicsConfiguration graphicsConfiguration; + +// public StatusWindow(GraphicsConfiguration gc) { +// super(gc); +// this.graphicsConfiguration = gc; +// } + public void initMenu() { menuBar = new JMenuBar(); fileMenu = new JMenu(LocalText.getText("FILE")); @@ -163,6 +175,13 @@ menuItem.setMnemonic(KeyEvent.VK_R); menuItem.addActionListener(this); optMenu.add(menuItem); + + menuItem = new JCheckBoxMenuItem(LocalText.getText("CONFIG")); + menuItem.setName(CONFIG_CMD); + menuItem.setActionCommand(CONFIG_CMD); + menuItem.setMnemonic(KeyEvent.VK_C); + menuItem.addActionListener(this); + optMenu.add(menuItem); menuBar.add(optMenu); @@ -257,8 +276,10 @@ autopassButton.addActionListener(this); setSize(800, 300); - setLocation(25, 450); +// Rectangle bounds = graphicsConfiguration.getBounds(); +// setLocation(bounds.x+ 25, bounds.y + 450); + buttonPanel.setBorder(BorderFactory.createEtchedBorder()); buttonPanel.setOpaque(false); @@ -583,6 +604,10 @@ gameUIManager.stockChart.setVisible(((JMenuItem) actor.getSource()).isSelected()); } else if (command.equals(MAP_CMD)) { gameUIManager.orWindow.setVisible(((JMenuItem) actor.getSource()).isSelected()); + } else if (command.equals(CONFIG_CMD)) { + JFrame configWindow = new ConfigWindow(); + configWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + configWindow.setVisible(true); } else if (executedAction == null) { ; } else if (executedAction instanceof GameAction) { Modified: trunk/18xx/rails/util/Config.java =================================================================== --- trunk/18xx/rails/util/Config.java 2010-07-11 16:44:29 UTC (rev 1337) +++ trunk/18xx/rails/util/Config.java 2010-07-16 20:37:33 UTC (rev 1338) @@ -1,11 +1,21 @@ /* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/util/Config.java,v 1.13 2010/06/24 21:48:08 stefanfrey Exp $*/ package rails.util; +import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Properties; import org.apache.log4j.Logger; +import rails.game.ConfigurationException; import rails.game.GameManager; /** @@ -18,28 +28,102 @@ */ public final class Config { - /** Default property file name. */ - /* It will be reset from GameTest. */ - private static String myConfigFile = "my.properties"; - //private static String gamesConfigFile = "games.properties"; + protected static Logger log = + Logger.getLogger(Config.class.getPackage().getName()); - /** One Properties object for all properties */ - private static Properties prop = new Properties(); - private static boolean loaded = false; + + /** + * Defines possible types (Java classes used as types in ConfigItem below + */ + public static enum ConfigType { + INTEGER, FLOAT, STRING, BOOLEAN, DIRECTORY, COLOR; + } - protected static Logger log = - Logger.getLogger(Config.class.getPackage().getName()); + /** XML setup */ + private static final String CONFIG_XML_DIR = "data"; + private static final String CONFIG_XML_FILE = "Properties.xml"; + private static final String CONFIG_TAG = "Properties"; + private static final String PANEL_TAG = "Panel"; + private static final String ITEM_TAG = "Property"; + /** Log 4j configuration */ + private static final String LOG4J_CONFIG_FILE = "log4j.properties"; + + + /** Rails profile configurations */ + private static String defaultProfilesFile = "default.profiles"; + private static Properties defaultProfiles = new Properties(); + private static String userProfilesFile = "user.profiles"; + private static Properties userProfiles = new Properties(); + private static boolean profilesLoaded = false; + private static final String TEST_PROFILE_SELECTION = "test"; + private static final String DEFAULT_PROFILE_SELECTION = "default"; + private static final String DEFAULT_PROFILE_PROPERTY = "default.profile"; + private static final String STANDARD_PROFILE_PROPERTY = "standard.profile"; + + /** selected profile */ + private static String selectedProfile; + private static boolean legacyConfigFile; + private static boolean standardProfile; + + /** properties storage. */ + private static Properties defaultProperties = new Properties(); + private static Properties userProperties = new Properties(); + private static boolean propertiesLoaded = false; + + /** Map that holds the panel, which contains config items */ + private static Map<String, List<ConfigItem>> configPanels = null; + /** - * Hidden contructor, the class is never instantiated. + * Hidden constructor, the class is never instantiated, everything is static */ private Config() {} - public static void setConfigFile(String myConfigFile) { - Config.myConfigFile = myConfigFile; - load(); + /** + * Reads the config.xml file that defines all config items + */ + public static void readConfigSetupXML() { + List<String> directories = new ArrayList<String>(); + directories.add(CONFIG_XML_DIR); + try { + // Find the <Config> tag + Tag configTag = + Tag.findTopTagInFile(CONFIG_XML_FILE, directories, CONFIG_TAG); + log.debug("Opened config xml, filename = " + CONFIG_XML_FILE); + + configPanels = new LinkedHashMap<String, List<ConfigItem>>(); + // find panels + List<Tag> panelTags = configTag.getChildren(PANEL_TAG); + if (panelTags != null) { + for (Tag panelTag:panelTags) { + // find name attribute + String panelName = panelTag.getAttributeAsString("name"); + if (!Util.hasValue(panelName)) continue; + + // find items + List<Tag> itemTags = panelTag.getChildren(ITEM_TAG); + if (itemTags == null || itemTags.size() == 0) continue; + List<ConfigItem> panelItems = new ArrayList<ConfigItem>(); + for (Tag itemTag:itemTags) { + panelItems.add(new ConfigItem(itemTag)); + } + configPanels.put(panelName, panelItems); + } + } + + } catch (ConfigurationException e) { + log.error("Configuration error in setup of "); + } } - + + public static Map<String, List<ConfigItem>> getConfigPanels() { + if (configPanels == null) { + readConfigSetupXML(); + } + log.debug("Configuration setup = " + configPanels); + return configPanels; + } + /** * First tries to return {key}.{gameName}, if undefined returns {key} */ @@ -59,55 +143,238 @@ } public static String get(String key) { - - if (prop.isEmpty() || !loaded) { - load(); + return get(key, ""); + } + + public static String get(String key, String defaultValue) { + if (defaultProperties.isEmpty() || !propertiesLoaded) { + initialLoad(); } - if (prop.containsKey(key)) return prop.getProperty(key).trim(); + if (userProperties.containsKey(key)) return userProperties.getProperty(key).trim(); + if (defaultProperties.containsKey(key)) return defaultProperties.getProperty(key).trim(); - return ""; + return defaultValue; } - public static String get(String key, String defaultValue) { - if (prop.isEmpty() || !loaded) { - load(); +// /** +// * store user config file +// */ +// public static boolean saveUserConfig() { +// } +// +// /** +// * @return if user location is defined +// */ +// public static boolean hasUserLocation() { +// return userConfigFile != null; +// } + + + private static boolean storePropertyFile(Properties properties, String filepath) { + File outFile = new File(filepath); + boolean result = true; + try { + properties.store(new FileOutputStream(outFile), "Automatically generated, do not edit"); + } catch (IOException e) { + result = false; } - if (prop.containsKey(key)) return prop.getProperty(key).trim(); + return result; + } + + /** + * save active Profile + */ + public static boolean saveActiveProfile(String filepath) { + return storePropertyFile(userProperties, filepath); + } + + /** + * change active Profile + */ + public static boolean setActiveProfile(String profileName) { + boolean result = loadPropertyProfile(profileName); + if (result) selectedProfile = profileName; + return result; + } + + /** + * returns name of (active) default profile + */ + public static String getDefaultProfileName() { + String defaultProfileName = null; + if (isUserProfileActive()) { + defaultProfileName = userProfiles.getProperty(DEFAULT_PROFILE_PROPERTY); + if (defaultProfileName == null) { +// return + } + } + return defaultProfileName; + } + + /** + * returns name of active profile + */ + public static String getActiveProfileName() { + return selectedProfile; + } + + /** + * sets filename for an active profile (and store list of profiles) + */ + public static boolean setActiveFilepath(String filepath) { + userProfiles.setProperty(selectedProfile, filepath); + return storePropertyFile(userProfiles, userProfilesFile); + } + + /** + * returns filename of active profile, (null if undefined or default profile) + */ + public static String getActiveFilepath() { + return userProfiles.getProperty(selectedProfile); + } + + /** + * returns true if active profile is a user profile + */ + public static boolean isUserProfileActive() { + return userProfiles.getProperty(selectedProfile) != null; + } + + /** + * activates settings used for testing + */ + public static void setConfigTest() { + /* + * Set the system property that tells log4j to use this file. (Note: + * this MUST be done before updating Config) + */ + System.setProperty("log4j.configuration", LOG4J_CONFIG_FILE); + legacyConfigFile = false; + selectedProfile = TEST_PROFILE_SELECTION; + initialLoad(); + } - return defaultValue; + + /** + * activates configuration settings based on default settings + */ + public static void setConfigSelection() { + /* + * Set the system property that tells log4j to use this file. (Note: + * this MUST be done before updating Config) + */ + System.setProperty("log4j.configuration", LOG4J_CONFIG_FILE); + + /* + * Check if the profile has been set from the command line + * to do this is adding an option to the java command: -Dprofile=<profile-name> + */ + String configSelection = System.getProperty("profile"); + System.out.println("Cmdline profile selection = " + configSelection); + + legacyConfigFile = false; + if (configSelection == null) { + /* + * Check if the property file has been set on the command line. The way + * to do this is adding an option to the java command: -Dconfigfile=<property-filename> + * + * This is for legacy reasons only + */ + configSelection = System.getProperty("configfile"); + + if (configSelection != null) { + System.out.println("Cmdline configfile selection (legacy!) = " + configSelection); + legacyConfigFile = true; + } + } + + /* if nothing has selected so far, choose standardProfile */ + standardProfile = false; + if (!Util.hasValue(configSelection)) { + standardProfile = true; + } + + selectedProfile = configSelection; + initialLoad(); } + - private static void load() { + private static void initialLoad() { + if (legacyConfigFile) { + if (!propertiesLoaded) { + loadPropertyFile(defaultProperties, selectedProfile, true, false); + propertiesLoaded = true; + setSaveDirDefaults(); + } + return; + } - if (prop.isEmpty() || !loaded) { - /* List the property files to read here */ - load(myConfigFile, false); - //load(gamesConfigFile, false); - setDefaults(); - loaded = true; + if (!profilesLoaded) { + loadPropertyFile(defaultProfiles, defaultProfilesFile, true, false); + loadPropertyFile(userProfiles, userProfilesFile, false, false); + profilesLoaded = true; } + + if (standardProfile) { + selectedProfile = userProfiles.getProperty(STANDARD_PROFILE_PROPERTY); + if (selectedProfile == null) { + selectedProfile = defaultProfiles.getProperty(STANDARD_PROFILE_PROPERTY); + } + if (selectedProfile == null) { + selectedProfile = DEFAULT_PROFILE_SELECTION; + } + } + + /* Tell the properties loader to read this file. */ + log.info("Selected profile = " + selectedProfile); + + if (!propertiesLoaded) { + propertiesLoaded = loadPropertyProfile(selectedProfile); + } } + + private static boolean loadPropertyProfile(String profileName) { + + /* first check if it is a default profile */ + String defaultConfigFile = defaultProfiles.getProperty(profileName); + if (defaultConfigFile == null) { + String userConfigFile = userProfiles.getProperty(profileName); + if (userConfigFile == null) return false; + loadPropertyFile(userProperties, userConfigFile, false, false); + defaultConfigFile = userProperties.getProperty(DEFAULT_PROFILE_PROPERTY); + if (defaultConfigFile == null) { + defaultConfigFile = defaultProfiles.getProperty(DEFAULT_PROFILE_SELECTION); + } + } + loadPropertyFile(defaultProperties, defaultConfigFile, true, false); + setSaveDirDefaults(); + return true; + } /** * This method loads a property file. * * @param filename - file key name as a String. + * @param resource - if TRUE, loaded from jar (via classloader), otherwise from filesystem * @param required - if TRUE, an exception will be logged if the file does * not exist. */ - private static void load(String filename, boolean required) { - + private static void loadPropertyFile(Properties properties, String filename, boolean resource, boolean required) { + try { log.info("Loading properties from file " + filename); - prop.load(Config.class.getClassLoader().getResourceAsStream( - filename)); - + InputStream inFile; + if (resource) { + inFile = Config.class.getClassLoader().getResourceAsStream(filename); + } else { + inFile = new FileInputStream(filename); + } + properties.load(inFile); } catch (FileNotFoundException FNFE) { if (required) { System.err.println("File not found: " + filename); } - } catch (Exception e) { System.err.println(e + " whilst loading properties file " + filename); @@ -115,10 +382,10 @@ } } - private static void setDefaults() { - if (!Util.hasValue(prop.getProperty("save.directory"))) { + private static void setSaveDirDefaults() { + if (!Util.hasValue(defaultProperties.getProperty("save.directory"))) { log.debug("Setting save directory to "+System.getProperty("user.dir")); - prop.put("save.directory", System.getProperty("user.dir")); + defaultProperties.put("save.directory", System.getProperty("user.dir")); } } } Added: trunk/18xx/rails/util/ConfigItem.java =================================================================== --- trunk/18xx/rails/util/ConfigItem.java (rev 0) +++ trunk/18xx/rails/util/ConfigItem.java 2010-07-16 20:37:33 UTC (rev 1338) @@ -0,0 +1,63 @@ +package rails.util; + +import java.util.Arrays; +import java.util.List; +import rails.game.ConfigurationException; +import rails.util.Config.ConfigType; + +/** + * Defines an item used for the configuration of rails + * T represents the value type + */ + +public class ConfigItem { + public final String name; + public final ConfigType type; + public final List<String> allowedValues; + public final String formatMask; + public final String helpText; + + ConfigItem(Tag tag) throws ConfigurationException { + // check name and type (required) + String name = tag.getAttributeAsString("name"); + if (Util.hasValue(name)) { + this.name = name; + } else { + throw new ConfigurationException("Missing name for configuration item"); + } + String type = tag.getAttributeAsString("type"); + if (Util.hasValue(type)) { + this.type = ConfigType.valueOf(type); + } else { + throw new ConfigurationException("Missing or invalid type for configuration item"); + } + // optional: list of allowed values + String valueString = tag.getAttributeAsString("values"); + if (Util.hasValue(valueString)) { + allowedValues = Arrays.asList(valueString.split(",")); + } else { + allowedValues = null; + } + // optional: formatMask + formatMask = tag.getAttributeAsString("formatMask"); + + // optional: helpText + helpText = tag.getAttributeAsString("formatMask"); + } + + public String toString() { + StringBuffer s = new StringBuffer(); + s.append("Configuration Item: name = " + name + ", type = " + type); + if (allowedValues != null) { + s.append(", allowedValues = " + allowedValues); + } + if (formatMask != null) { + s.append(", formatMask = " + formatMask); + } + if (helpText != null) { + s.append(", helpText = " + helpText); + } + return s.toString(); + } + +} Modified: trunk/18xx/rails/util/ListAndFixSavedFiles.java =================================================================== --- trunk/18xx/rails/util/ListAndFixSavedFiles.java 2010-07-11 16:44:29 UTC (rev 1337) +++ trunk/18xx/rails/util/ListAndFixSavedFiles.java 2010-07-16 20:37:33 UTC (rev 1338) @@ -39,32 +39,15 @@ private String filepath; protected static Logger log; - /** * @param args */ public static void main(String[] args) { - // TODO Auto-generated method stub - - String myConfigFile = System.getProperty("configfile"); - System.out.println("Cmdline configfile setting = " + myConfigFile); - - /* If not, use the default configuration file name */ - if (!Util.hasValue(myConfigFile)) { - myConfigFile = "my.properties"; - } - - /* - * Set the system property that tells log4j to use this file. (Note: - * this MUST be done before updating Config) - */ - System.setProperty("log4j.configuration", myConfigFile); - log = Logger.getLogger(ListAndFixSavedFiles.class.getPackage().getName()); - - /* Tell the properties loader to read this file. */ - Config.setConfigFile(myConfigFile); - System.out.println("Configuration file = " + myConfigFile); + + // intialize configuration + Config.setConfigSelection(); + saveDirectory = Config.get("save.directory"); System.out.println("Save directory = " + saveDirectory); Modified: trunk/18xx/rails/util/RunGame.java =================================================================== --- trunk/18xx/rails/util/RunGame.java 2010-07-11 16:44:29 UTC (rev 1337) +++ trunk/18xx/rails/util/RunGame.java 2010-07-16 20:37:33 UTC (rev 1338) @@ -7,32 +7,12 @@ import rails.ui.swing.GameUIManager; public class RunGame { - /** The default properties file name */ - private static String DEFAULT_CONFIG_FILE = "my.properties"; public static void main(String[] args) { - /* - * Check if the property file has been set on the command line. The way - * to do this is adding an option to the java command: -Dconfigfile=<property-filename> - */ - String myConfigFile = System.getProperty("configfile"); - System.out.println("Cmdline configfile setting = " + myConfigFile); - - /* If not, use the default configuration file name */ - if (!Util.hasValue(myConfigFile)) { - myConfigFile = DEFAULT_CONFIG_FILE; - } - - /* - * Set the system property that tells log4j to use this file. (Note: - * this MUST be done before updating Config) - */ - System.setProperty("log4j.configuration", myConfigFile); - /* Tell the properties loader to read this file. */ - Config.setConfigFile(myConfigFile); - System.out.println("Configuration file = " + myConfigFile); - + // intialize configuration + Config.setConfigSelection(); + int nargs = 0; if (args != null && args.length > 0) { nargs = args.length; Modified: trunk/18xx/test/TestGameBuilder.java =================================================================== --- trunk/18xx/test/TestGameBuilder.java 2010-07-11 16:44:29 UTC (rev 1337) +++ trunk/18xx/test/TestGameBuilder.java 2010-07-16 20:37:33 UTC (rev 1338) @@ -23,7 +23,6 @@ public final class TestGameBuilder extends TestCase { - private static String configFile = "test/test.properties"; private static char extensionSeparator = '.'; private static int maxRecursionLevel = 5; @@ -147,14 +146,8 @@ public static Test suite() { - // Activate logger - System.setProperty("log4j.configuration", configFile); + Config.setConfigTest(); - /* Tell the properties loader to read this file. */ - Config.setConfigFile(configFile); - System.out.println("Configuration file = " + configFile); - - // Main test directory File testDir = new File(Config.get("save.directory")); @@ -177,13 +170,8 @@ */ public static void main(String[] args) { - // Activate logger - System.setProperty("log4j.configuration", configFile); + Config.setConfigTest(); - /* Tell the properties loader to read this file. */ - Config.setConfigFile(configFile); - System.out.println("Configuration file = " + configFile); - // Main test directory String rootPath = Config.get("save.directory"); Added: trunk/18xx/user.profiles =================================================================== --- trunk/18xx/user.profiles (rev 0) +++ trunk/18xx/user.profiles 2010-07-16 20:37:33 UTC (rev 1338) @@ -0,0 +1,2 @@ +standard.profile=sfy +sfy=sfy.my.properties This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ev...@us...> - 2010-07-17 11:08:45
|
Revision: 1342 http://rails.svn.sourceforge.net/rails/?rev=1342&view=rev Author: evos Date: 2010-07-17 11:08:38 +0000 (Sat, 17 Jul 2010) Log Message: ----------- All addObject() and related methods now take a position argument. ObjectMove has an additional fromPosition attribute. Also toPosition, but that isn't used yet. This all is used to ensure that Undo always restores the original List order for moves executed via ObjectMove. Also fixed a bug that allowed price tokens to vanish into the empty upper left corner of the 1835 stock chart. Modified Paths: -------------- trunk/18xx/rails/game/Bank.java trunk/18xx/rails/game/City.java trunk/18xx/rails/game/Company.java trunk/18xx/rails/game/GameManager.java trunk/18xx/rails/game/MapHex.java trunk/18xx/rails/game/OperatingRound.java trunk/18xx/rails/game/Portfolio.java trunk/18xx/rails/game/PrivateCompany.java trunk/18xx/rails/game/PublicCompany.java trunk/18xx/rails/game/PublicCompanyI.java trunk/18xx/rails/game/StockMarket.java trunk/18xx/rails/game/Token.java trunk/18xx/rails/game/TokenHolder.java trunk/18xx/rails/game/TrainType.java trunk/18xx/rails/game/move/MoveableHolder.java trunk/18xx/rails/game/move/ObjectMove.java Property Changed: ---------------- trunk/18xx/ Property changes on: trunk/18xx ___________________________________________________________________ Modified: svn:ignore - *.bat *.txt .cvsignore .classpath .externalToolBuilders 18xx.zip deploy.xml .project zip.xml NewUIstuff.zip COMP.WPS rails.jar rails.jardesc Rails-1.0.1.jar my_my.properties log rails-1.0.1.jar rails*.zip rails-*.jar tools rails-?.*.* jar/* classes/* + *.bat *.txt .cvsignore .classpath .externalToolBuilders 18xx.zip deploy.xml .project zip.xml NewUIstuff.zip COMP.WPS rails.jar rails.jardesc Rails-1.0.1.jar my_my.properties log rails-1.0.1.jar rails*.zip rails-*.jar tools rails-?.*.* jar/* classes/* 18xx_autosave.rails 18xx_autosave.rails.tmp Modified: trunk/18xx/rails/game/Bank.java =================================================================== --- trunk/18xx/rails/game/Bank.java 2010-07-16 21:31:11 UTC (rev 1341) +++ trunk/18xx/rails/game/Bank.java 2010-07-17 11:08:38 UTC (rev 1342) @@ -31,8 +31,8 @@ /** Is the bank broken (remains true once set) */ private BooleanState broken = new BooleanState("Bank.broken", false); -// /** Is the bank just broken (returns true exactly once) */ -// private BooleanState brokenReported = new BooleanState("Bank.brokenReported", false); + // /** Is the bank just broken (returns true exactly once) */ + // private BooleanState brokenReported = new BooleanState("Bank.brokenReported", false); /** * The money format template. '@' is replaced by the numeric amount, the @@ -41,7 +41,7 @@ private String moneyFormat = null; protected static Logger log = - Logger.getLogger(Bank.class.getPackage().getName()); + Logger.getLogger(Bank.class.getPackage().getName()); public Bank() { @@ -98,7 +98,7 @@ List<PrivateCompanyI> privates = gameManager.getCompanyManager().getAllPrivateCompanies(); for (PrivateCompanyI priv : privates) { - ipo.addPrivate(priv); + ipo.addPrivate(priv, -1); } // Add public companies @@ -107,13 +107,13 @@ for (PublicCompanyI comp : companies) { for (PublicCertificateI cert : comp.getCertificates()) { if (cert.isInitiallyAvailable()) { - ipo.addCertificate(cert); - } else { - unavailable.addCertificate(cert); - } + ipo.addCertificate(cert, -1); + } else { + unavailable.addCertificate(cert, -1); + } } } -} + } /** * @return IPO Portfolio @@ -154,11 +154,11 @@ return broken.booleanValue(); } -// public boolean isJustBroken() { -// boolean result = broken.booleanValue() && !brokenReported.booleanValue(); -// brokenReported.set(true); -// return result; -// } + // public boolean isJustBroken() { + // boolean result = broken.booleanValue() && !brokenReported.booleanValue(); + // brokenReported.set(true); + // return result; + // } /** * @return Portfolio of stock in Bank Pool Modified: trunk/18xx/rails/game/City.java =================================================================== --- trunk/18xx/rails/game/City.java 2010-07-16 21:31:11 UTC (rev 1341) +++ trunk/18xx/rails/game/City.java 2010-07-17 11:08:38 UTC (rev 1342) @@ -37,12 +37,12 @@ private String trackEdges; protected static Logger log = - Logger.getLogger(City.class.getPackage().getName()); + Logger.getLogger(City.class.getPackage().getName()); public City(MapHex mapHex, int number, Station station) { this.mapHex = mapHex; this.number = number; - + uniqueId = mapHex.getName() + "_" + number; relatedStation = new GenericState<Station>("City_"+uniqueId+"_station", station); setRelatedStation(station); @@ -53,7 +53,7 @@ public String getName() { return mapHex.getName() + "/" + number; - + } /** @@ -75,9 +75,9 @@ this.relatedStation.set(relatedStation); slots = relatedStation.getBaseSlots(); trackEdges = - mapHex.getConnectionString(mapHex.getCurrentTile(), - mapHex.getCurrentTileRotation(), - relatedStation.getNumber()); + mapHex.getConnectionString(mapHex.getCurrentTile(), + mapHex.getCurrentTileRotation(), + relatedStation.getNumber()); } public void setSlots(int slots) { @@ -91,20 +91,28 @@ return uniqueId; } - public boolean addToken(TokenI token) { + public boolean addToken(TokenI token, int position) { if (tokens.contains(token)) { return false; } else { token.setHolder(this); - boolean result = tokens.add(token); - return result; + if (position == -1) { + return tokens.add(token); + } else { + try { + tokens.add(position, token); + return true; + } catch (IndexOutOfBoundsException e) { + return false; + } + } } } - public boolean addObject(Moveable object) { + public boolean addObject(Moveable object, int position) { if (object instanceof TokenI) { - return addToken((TokenI) object); + return addToken((TokenI) object, position); } else { return false; } @@ -133,7 +141,7 @@ public boolean hasTokenSlotsLeft() { return tokens.size() < slots; } - + public int getTokenSlotsLeft () { return slots - tokens.size(); } @@ -148,13 +156,13 @@ * @param company * @return true if this City already contains an instance of the specified * company's token. Do this by calling the hasTokenOf with Company Name. - * Using a tokens.contains(company) fails since the tokens are a ArrayList + * Using a tokens.contains(company) fails since the tokens are a ArrayList * of TokenI not a ArrayList of PublicCompanyI. */ public boolean hasTokenOf(PublicCompanyI company) { return hasTokenOf (company.getName()); } - + public boolean hasTokenOf (String companyName) { for (TokenI token : tokens) { if (token instanceof BaseToken @@ -165,6 +173,14 @@ return false; } + public int getListIndex (Moveable object) { + if (object instanceof BaseToken) { + return tokens.indexOf(object); + } else { + return -1; + } + } + public void setTokens(ArrayList<TokenI> tokens) { this.tokens = tokens; } Modified: trunk/18xx/rails/game/Company.java =================================================================== --- trunk/18xx/rails/game/Company.java 2010-07-16 21:31:11 UTC (rev 1341) +++ trunk/18xx/rails/game/Company.java 2010-07-17 11:08:38 UTC (rev 1342) @@ -13,13 +13,13 @@ import rails.util.Util; public abstract class Company implements CompanyI, ConfigurableComponentI, - Cloneable, Comparable<Company> { +Cloneable, Comparable<Company> { protected String name; protected String longName; protected CompanyTypeI type; protected int companyNumber; // For internal use - + /* Note: portfolio is used in two ways: * In private companies, it is primarily the portfolio that holds this private. * In public companies, it is the portfolio of this company. @@ -42,12 +42,12 @@ /** Closed state */ protected BooleanState closedObject; - + // Moved here from PrivayeCOmpany on behalf of 1835 protected List<SpecialPropertyI> specialProperties = null; - + protected static Logger log = - Logger.getLogger(Company.class.getPackage().getName()); + Logger.getLogger(Company.class.getPackage().getName()); public Company() { } @@ -60,7 +60,7 @@ /** Only to be called from subclasses */ public void configureFromXML(Tag tag) throws ConfigurationException { - + // Special properties Tag spsTag = tag.getChild("SpecialProperties"); if (spsTag != null) { @@ -71,7 +71,7 @@ className = spTag.getAttributeAsString("class"); if (!Util.hasValue(className)) throw new ConfigurationException( - "Missing class in private special property"); + "Missing class in private special property"); SpecialPropertyI sp = null; try { sp = (SpecialPropertyI) Class.forName(className).newInstance(); @@ -87,7 +87,7 @@ } } } - + /** * @return ArrayList of all special properties we have. */ @@ -214,30 +214,30 @@ * * Use addToken(MapHex hex) method instead. */ - public boolean addToken(CompanyI company) { + public boolean addToken(CompanyI company, int position) { return false; } @Override public String toString() { return getTypeName() + ": " + getCompanyNumber() + ". " + getName() - + " $" + this.getValue(); + + " $" + this.getValue(); } public boolean equals(CompanyI company) { if (this.companyNumber == company.getCompanyNumber() - && this.name.equals(company.getName()) - && this.type.equals(company.getType())) return true; + && this.name.equals(company.getName()) + && this.type.equals(company.getType())) return true; return false; } - + public int compareTo(Company otherCompany){ int result; // compare typeNames first result = this.getTypeName().compareTo(otherCompany.getTypeName()); // if same typeName then name - if (result == 0) + if (result == 0) result = this.getName().compareTo(otherCompany.getName()); return result; Modified: trunk/18xx/rails/game/GameManager.java =================================================================== --- trunk/18xx/rails/game/GameManager.java 2010-07-16 21:31:11 UTC (rev 1341) +++ trunk/18xx/rails/game/GameManager.java 2010-07-17 11:08:38 UTC (rev 1342) @@ -187,7 +187,7 @@ /** A List of available game options */ protected List<GameOption> availableGameOptions = new ArrayList<GameOption>(); - + /** indicates that the recoverySave already issued a warning, avoids displaying several warnings */ protected boolean recoverySaveWarning = true; @@ -812,7 +812,7 @@ if (!isGameOver() && possibleActions.containsOnlyPass()) { result = process(possibleActions.getList().get(0)); } - + // moveStack closing is done here to allow state changes to occur // when setting possible actions if (action != null) { @@ -943,7 +943,7 @@ * */ protected void recoverySave() { if (Config.get("save.recovery.active", "yes").equalsIgnoreCase("no")) return; - + String filePath = Config.get("save.recovery.filepath", "18xx_autosave.rails"); // create temporary new save file File tempFile = null; @@ -978,7 +978,7 @@ recoverySaveWarning = false; return; } - + if (result) { log.debug("Renamed to recovery file, path = " + recoveryFile.getAbsolutePath()); if (!recoverySaveWarning) { @@ -992,12 +992,12 @@ } } } - + protected boolean save(GameAction saveAction) { File file = new File(saveAction.getFilepath()); return save(file, true, "SaveFailed"); } - + protected boolean save(File file, boolean displayErrorMessage, String errorMessageKey) { boolean result = false; @@ -1500,16 +1500,24 @@ * @param object The object to add. * @return True if successful. */ - public boolean addObject(Moveable object) { + public boolean addObject(Moveable object, int position) { if (object instanceof SpecialPropertyI) { SpecialPropertyI sp = (SpecialPropertyI) object; sp.setHolder(null); - return addSpecialProperty(sp); + return addSpecialProperty(sp, position); } else { return false; } } + public int getListIndex (Moveable object) { + if (object instanceof SpecialPropertyI) { + return commonSpecialProperties.indexOf(object); + } else { + return -1; + } + } + /** * Remove an object. * @@ -1524,12 +1532,21 @@ } } - public boolean addSpecialProperty(SpecialPropertyI property) { + public boolean addSpecialProperty(SpecialPropertyI property, int position) { if (commonSpecialProperties == null) { commonSpecialProperties = new ArrayList<SpecialPropertyI>(2); } - return commonSpecialProperties.add(property); + if (position == -1) { + return commonSpecialProperties.add(property); + } else { + try { + commonSpecialProperties.add(position, property); + return true; + } catch (IndexOutOfBoundsException e) { + return false; + } + } } /** Modified: trunk/18xx/rails/game/MapHex.java =================================================================== --- trunk/18xx/rails/game/MapHex.java 2010-07-16 21:31:11 UTC (rev 1341) +++ trunk/18xx/rails/game/MapHex.java 2010-07-17 11:08:38 UTC (rev 1342) @@ -38,15 +38,15 @@ * tiles the above picture should be rotated 30 degrees clockwise. */ public class MapHex extends ModelObject implements ConfigurableComponentI, - StationHolder, TokenHolder { +StationHolder, TokenHolder { public static final int EW = 0; public static final int NS = 1; private static final String[] ewOrNames = - { "SW", "W", "NW", "NE", "E", "SE" }; + { "SW", "W", "NW", "NE", "E", "SE" }; private static final String[] nsOrNames = - { "S", "SW", "NW", "N", "NE", "SE" }; + { "S", "SW", "NW", "N", "NE", "SE" }; // Coordinates as used in the rails.ui.swing.hexmap package protected int x; @@ -87,19 +87,19 @@ protected Map<Integer, City> mCities; /* - * changed to state variable to fix undo bug #2954645 + * changed to state variable to fix undo bug #2954645 * null as default implies false - see isBlocked() */ private BooleanState isBlockedForTileLays = null; - - /** + + /** * Is the hex initially blocked for token lays (e.g. when a home base * must first be laid)? <p> * NOTE:<br>null means: blocked unless there is more free space than unlaid home bases,<br> * false means: blocked unless there is any free space.<br> - * This makes a difference for 1835 Berlin, which is home to PR, but - * the absence of a PR token does not block the third slot - * when the green tile is laid. + * This makes a difference for 1835 Berlin, which is home to PR, but + * the absence of a PR token does not block the third slot + * when the green tile is laid. */ private BooleanState isBlockedForTokenLays = null; @@ -108,14 +108,14 @@ /** Tokens that are not bound to a Station (City), such as Bonus tokens */ protected List<TokenI> offStationTokens; - + /** Storage of revenueBonus that are bound to the hex */ protected List<RevenueBonusTemplate> revenueBonuses = null; protected MapManager mapManager = null; protected static Logger log = - Logger.getLogger(MapHex.class.getPackage().getName()); + Logger.getLogger(MapHex.class.getPackage().getName()); public MapHex(MapManager mapManager) { this.mapManager = mapManager; @@ -158,7 +158,7 @@ y = (row + 1) / 2; } } else - // letters go vertical (normal case) + // letters go vertical (normal case) { row = letter - '@'; column = number; @@ -190,13 +190,13 @@ // City name cityName = tag.getAttributeAsString("city", ""); if (Util.hasValue(cityName)) { - infoText += " " + cityName; + infoText += " " + cityName; } - + if (tag.getAttributeAsString("unlaidHomeBlocksTokens") != null) { setBlockedForTokenLays(tag.getAttributeAsBoolean("unlaidHomeBlocksTokens", false)); } - + // revenue bonus List<Tag> bonusTags = tag.getChildren("RevenueBonus"); if (bonusTags != null) { @@ -216,7 +216,7 @@ // stations. cities = new ArrayList<City>(4); mCities = new HashMap<Integer, City>(4); - for (Station s : currentTile.getStations()) { + for (Station s : currentTile.getStations()) { // sid, type, value, slots City c = new City(this, s.getNumber(), s); cities.add(c); @@ -251,8 +251,8 @@ */ TileI tile = neighbour.getCurrentTile(); if (!tile.isUpgradeable() - && !tile.hasTracks(3 + direction - - neighbour.getCurrentTileRotation())) + && !tile.hasTracks(3 + direction + - neighbour.getCurrentTileRotation())) return false; return true; @@ -319,7 +319,7 @@ public int getPreprintedTileId() { return preprintedTileId; } - + public int getPreprintedTileRotation() { return preprintedTileRotation; } @@ -374,7 +374,7 @@ return 0; } } - + public int[] getTileCostAsArray(){ return tileCost; } @@ -388,10 +388,10 @@ TileI newTile = action.getLaidTile(); int newRotation = action.getOrientation(); Map<String, Integer> relaidTokens = action.getRelaidBaseTokens(); - + upgrade(newTile, newRotation, relaidTokens); } - + /** * Prepare a tile upgrade. The actual tile replacement is done in * replaceTile(), via a TileMove object. @@ -427,12 +427,12 @@ if (citiesToStations.containsKey(city)) continue; Station oldStation = city.getRelatedStation(); int[] oldTrackEnds = - getTrackEndPoints(currentTile, currentTileRotation, - oldStation); + getTrackEndPoints(currentTile, currentTileRotation, + oldStation); if (oldTrackEnds.length == 0) continue; station: for (Station newStation : newTile.getStations()) { int[] newTrackEnds = - getTrackEndPoints(newTile, newRotation, newStation); + getTrackEndPoints(newTile, newRotation, newStation); for (int i = 0; i < oldTrackEnds.length; i++) { for (int j = 0; j < newTrackEnds.length; j++) { if (oldTrackEnds[i] == newTrackEnds[j]) { @@ -456,27 +456,27 @@ } - // Assign the new Stations to the existing cities - for (City city : citiesToStations.keySet()) { - Station newStation = citiesToStations.get(city); - Station oldStation = city.getRelatedStation(); - city.setRelatedStation(newStation); - city.setSlots(newStation.getBaseSlots()); - newTracks = - getConnectionString(newTile, - newRotation, - newStation.getNumber()); - city.setTrackEdges(newTracks); - log.debug("Assigned " - + city.getUniqueId() - + " from " - + oldStation.getId() - + " " - + getConnectionString(currentTile, - currentTileRotation, - oldStation.getNumber()) - + " to " + newStation.getId() + " " - + newTracks); + // Assign the new Stations to the existing cities + for (City city : citiesToStations.keySet()) { + Station newStation = citiesToStations.get(city); + Station oldStation = city.getRelatedStation(); + city.setRelatedStation(newStation); + city.setSlots(newStation.getBaseSlots()); + newTracks = + getConnectionString(newTile, + newRotation, + newStation.getNumber()); + city.setTrackEdges(newTracks); + log.debug("Assigned " + + city.getUniqueId() + + " from " + + oldStation.getId() + + " " + + getConnectionString(currentTile, + currentTileRotation, + oldStation.getNumber()) + + " to " + newStation.getId() + " " + + newTracks); } newCities = cities; @@ -490,7 +490,7 @@ Map<Integer, City> mNewCities = new HashMap<Integer, City>(4); Map<City, City> oldToNewCities = new HashMap<City, City>(); Map<Station, City> newStationsToCities = - new HashMap<Station, City>(); + new HashMap<Station, City>(); // Scan the old cities/stations, // and assign new stations where tracks correspond @@ -499,64 +499,64 @@ int cityNumber = oldCity.getNumber(); Station oldStation = oldCity.getRelatedStation(); int[] oldTrackEnds = - getTrackEndPoints(currentTile, currentTileRotation, - oldStation); + getTrackEndPoints(currentTile, currentTileRotation, + oldStation); log.debug("Old city #" - + currentTile.getId() - + " city " - + oldCity.getNumber() - + ": " - + getConnectionString(currentTile, - currentTileRotation, oldStation.getNumber())); + + currentTile.getId() + + " city " + + oldCity.getNumber() + + ": " + + getConnectionString(currentTile, + currentTileRotation, oldStation.getNumber())); station: for (Station newStation : newTile.getStations()) { int[] newTrackEnds = - getTrackEndPoints(newTile, newRotation, newStation); + getTrackEndPoints(newTile, newRotation, newStation); log.debug("New station #" - + newTile.getId() - + " station " - + newStation.getNumber() - + ": " - + getConnectionString(newTile, newRotation, - newStation.getNumber())); + + newTile.getId() + + " station " + + newStation.getNumber() + + ": " + + getConnectionString(newTile, newRotation, + newStation.getNumber())); for (int i = 0; i < oldTrackEnds.length; i++) { for (int j = 0; j < newTrackEnds.length; j++) { if (oldTrackEnds[i] == newTrackEnds[j]) { // Match found! if (!newStationsToCities.containsKey(newStation)) { newCity = - new City(this, ++newCityNumber, - newStation); + new City(this, ++newCityNumber, + newStation); newCities.add(newCity); mNewCities.put(cityNumber, newCity); newStationsToCities.put(newStation, newCity); newCity.setSlots(newStation.getBaseSlots()); } else { newCity = - newStationsToCities.get(newStation); + newStationsToCities.get(newStation); } oldToNewCities.put(oldCity, newCity); newTracks = - getConnectionString(newTile, - newRotation, - newStation.getNumber()); + getConnectionString(newTile, + newRotation, + newStation.getNumber()); newCity.setTrackEdges(newTracks); log.debug("Assigned from " - + oldCity.getUniqueId() - + " #" - + currentTile.getId() - + "/" - + currentTileRotation - + " " - + oldStation.getId() - + " " - + getConnectionString(currentTile, - currentTileRotation, - oldStation.getNumber()) - + " to " + newCity.getUniqueId() - + " #" + newTile.getId() + "/" - + newRotation + " " - + newStation.getId() + " " - + newTracks); + + oldCity.getUniqueId() + + " #" + + currentTile.getId() + + "/" + + currentTileRotation + + " " + + oldStation.getId() + + " " + + getConnectionString(currentTile, + currentTileRotation, + oldStation.getNumber()) + + " to " + newCity.getUniqueId() + + " #" + newTile.getId() + "/" + + newRotation + " " + + newStation.getId() + " " + + newTracks); break station; } } @@ -599,12 +599,12 @@ + getConnectionString(currentTile, currentTileRotation, oldStation.getNumber()) - + " to " + newCity.getUniqueId() - + " #" + newTile.getId() + "/" - + newRotation + " " - + newCity.getRelatedStation().getId() + " " - + newCity.getTrackEdges()); - break station; + + " to " + newCity.getUniqueId() + + " #" + newTile.getId() + "/" + + newRotation + " " + + newCity.getRelatedStation().getId() + " " + + newCity.getTrackEdges()); + break station; } @@ -629,17 +629,17 @@ newStationsToCities.put(newStation, newCity); newCity.setSlots(newStation.getBaseSlots()); newTracks = - getConnectionString(newTile, newRotation, - newStation.getNumber()); + getConnectionString(newTile, newRotation, + newStation.getNumber()); newCity.setTrackEdges(newTracks); log.debug("New city added " + newCity.getUniqueId() + " #" - + newTile.getId() + "/" + newRotation + " " - + newStation.getId() + " " + newTracks); + + newTile.getId() + "/" + newRotation + " " + + newStation.getId() + " " + newTracks); } // Move the tokens Map<TokenI, TokenHolder> tokenDestinations = - new HashMap<TokenI, TokenHolder>(); + new HashMap<TokenI, TokenHolder>(); for (City oldCity : cities) { newCity = oldToNewCities.get(oldCity); @@ -648,35 +648,35 @@ if (token instanceof BaseToken) { // Check if the new city already has such a token PublicCompanyI company = - ((BaseToken) token).getCompany(); + ((BaseToken) token).getCompany(); for (TokenI token2 : newCity.getTokens()) { if (token2 instanceof BaseToken - && company == ((BaseToken) token2).getCompany()) { + && company == ((BaseToken) token2).getCompany()) { // No duplicate tokens in one city! tokenDestinations.put(token, company); log.debug("Duplicate token " - + token.getUniqueId() - + " moved from " - + oldCity.getName() + " to " - + company.getName()); + + token.getUniqueId() + + " moved from " + + oldCity.getName() + " to " + + company.getName()); ReportBuffer.add(LocalText.getText( "DuplicateTokenRemoved", - company.getName(), - getName() )); + company.getName(), + getName() )); continue oldtoken; } } } tokenDestinations.put(token, newCity); log.debug("Token " + token.getUniqueId() - + " moved from " + oldCity.getName() + " to " - + newCity.getName()); + + " moved from " + oldCity.getName() + " to " + + newCity.getName()); } - if (!tokenDestinations.isEmpty()) { - for (TokenI token : tokenDestinations.keySet()) { - token.moveTo(tokenDestinations.get(token)); - } + if (!tokenDestinations.isEmpty()) { + for (TokenI token : tokenDestinations.keySet()) { + token.moveTo(tokenDestinations.get(token)); } + } } else { log.debug("No new city!?"); } @@ -705,16 +705,16 @@ if (oldTile != currentTile) { new Exception("ERROR! Hex " + name + " wants to replace tile #" - + oldTile.getId() + " but has tile #" - + currentTile.getId() + "!").printStackTrace(); + + oldTile.getId() + " but has tile #" + + currentTile.getId() + "!").printStackTrace(); } if (currentTile != null) { currentTile.remove(this); } log.debug("On hex " + name + " replacing tile " + currentTile.getId() - + "/" + currentTileRotation + " by " + newTile.getId() + "/" - + newTileOrientation); + + "/" + currentTileRotation + " by " + newTile.getId() + "/" + + newTileOrientation); newTile.lay(this); @@ -727,12 +727,12 @@ for (City city : cities) { mCities.put(city.getNumber(), city); log.debug("Tile #" - + newTile.getId() - + " station " - + city.getNumber() - + " has tracks to " - + getConnectionString(newTile, newTileOrientation, - city.getRelatedStation().getNumber())); + + newTile.getId() + + " station " + + city.getNumber() + + " has tracks to " + + getConnectionString(newTile, newTileOrientation, + city.getRelatedStation().getNumber())); } } /* TODO: Further consequences to be processed here, e.g. new routes etc. */ @@ -744,8 +744,8 @@ public boolean layBaseToken(PublicCompanyI company, int station) { if (cities == null || cities.isEmpty()) { log.error("Tile " + getName() - + " has no station for home token of company " - + company.getName()); + + " has no station for home token of company " + + company.getName()); return false; } City city = mCities.get(station); @@ -757,15 +757,15 @@ } else { token.moveTo(city); update(); - - if (isHomeFor(company) - && isBlockedForTokenLays != null + + if (isHomeFor(company) + && isBlockedForTokenLays != null && isBlockedForTokenLays.booleanValue()) { // Assume that there is only one home base on such a tile, // so we don't need to check for other ones isBlockedForTokenLays.set(false); } - + return true; } } @@ -788,7 +788,7 @@ } } - public boolean addToken(TokenI token) { + public boolean addToken(TokenI token, int position) { if (offStationTokens == null) offStationTokens = new ArrayList<TokenI>(); @@ -796,7 +796,16 @@ return false; } else { token.setHolder(this); - return offStationTokens.add(token); + if (position == -1) { + return offStationTokens.add(token); + } else { + try { + offStationTokens.add(position, token); + return true; + } catch (IndexOutOfBoundsException e) { + return false; + } + } } } @@ -826,9 +835,9 @@ return offStationTokens.remove(token); } - public boolean addObject(Moveable object) { + public boolean addObject(Moveable object, int position) { if (object instanceof TokenI) { - return addToken((TokenI) object); + return addToken((TokenI) object, position); } else { return false; } @@ -842,6 +851,16 @@ } } + public int getListIndex (Moveable object) { + if (object instanceof TokenI) { + return offStationTokens.indexOf(object); + } else { + return -1; + } + } + + + public boolean hasTokenSlotsLeft(int station) { if (station == 0) station = 1; // Temp. fix for old save files City city = mCities.get(station); @@ -849,7 +868,7 @@ return city.hasTokenSlotsLeft(); } else { log.error("Invalid station " + station + ", max is " - + (cities.size() - 1)); + + (cities.size() - 1)); return false; } } @@ -890,7 +909,7 @@ for (City city : cities) { for (TokenI token : city.getTokens()) { if (token instanceof BaseToken - && ((BaseToken) token).getCompany() == company) { + && ((BaseToken) token).getCompany() == company) { return city.getNumber(); } } @@ -905,7 +924,7 @@ public City getCity(int cityNumber) { return mCities.get(cityNumber); } - + public City getRelatedCity(Station station) { City foundCity = null; for (City city:mCities.values()) { @@ -986,7 +1005,7 @@ return true; } else { log.debug("Hex " + name + " tile #" + currentTile.getId() - + " is not upgradable now"); + + " is not upgradable now"); return false; } } @@ -1013,7 +1032,7 @@ * C) City is undecided => check all cities if there is a slot left */ public boolean isBlockedForTokenLays(PublicCompanyI company, int cityNumber) { - + if (isHomeFor(company)) // Company can always lay a home base return false; @@ -1079,16 +1098,16 @@ } public String getInfo () { - return infoText; + return infoText; } public List<RevenueBonusTemplate> getRevenueBonuses() { return revenueBonuses; } - + public boolean equals(MapHex hex) { if (hex.getName().equals(getName()) && hex.row == row - && hex.column == column) return true; + && hex.column == column) return true; return false; } @@ -1138,7 +1157,7 @@ public String getConnectionString(int cityNumber) { int stationNumber = - mCities.get(cityNumber).getRelatedStation().getNumber(); + mCities.get(cityNumber).getRelatedStation().getNumber(); return getConnectionString(currentTile, currentTileRotation, stationNumber); } Modified: trunk/18xx/rails/game/OperatingRound.java =================================================================== --- trunk/18xx/rails/game/OperatingRound.java 2010-07-16 21:31:11 UTC (rev 1341) +++ trunk/18xx/rails/game/OperatingRound.java 2010-07-17 11:08:38 UTC (rev 1342) @@ -5,7 +5,8 @@ import rails.common.GuiDef; import rails.game.action.*; -import rails.game.correct.*; +import rails.game.correct.ClosePrivate; +import rails.game.correct.OperatingCost; import rails.game.move.CashMove; import rails.game.move.MapChange; import rails.game.special.*; @@ -28,9 +29,9 @@ /* sfy: using rails without map support */ protected boolean noMapMode = false; - + protected List<PublicCompanyI> companiesOperatedThisRound - = new ArrayList<PublicCompanyI> (); + = new ArrayList<PublicCompanyI> (); protected List<PublicCompanyI> operatingCompanies; @@ -47,19 +48,19 @@ protected List<LayTile> currentNormalTileLays = new ArrayList<LayTile>(); protected Map<String, Integer> tileLaysPerColour = - new HashMap<String, Integer>(); + new HashMap<String, Integer>(); protected List<LayBaseToken> currentNormalTokenLays = - new ArrayList<LayBaseToken>(); + new ArrayList<LayBaseToken>(); protected List<LayBaseToken> currentSpecialTokenLays = - new ArrayList<LayBaseToken>(); + new ArrayList<LayBaseToken>(); /** A List per player with owned companies that have excess trains */ protected Map<Player, List<PublicCompanyI>> excessTrainCompanies = null; protected List<TrainTypeI> trainsBoughtThisTurn = - new ArrayList<TrainTypeI>(4); + new ArrayList<TrainTypeI>(4); protected Map<PublicCompanyI, Integer> loansThisRound = null; @@ -71,17 +72,17 @@ public static final int SPLIT_ROUND_DOWN = 2; // More to the treasury -// protected static GameDef.OrStep[] steps = - protected GameDef.OrStep[] steps = - new GameDef.OrStep[] { - GameDef.OrStep.INITIAL, - GameDef.OrStep.LAY_TRACK, - GameDef.OrStep.LAY_TOKEN, - GameDef.OrStep.CALC_REVENUE, - GameDef.OrStep.PAYOUT, - GameDef.OrStep.BUY_TRAIN, - GameDef.OrStep.TRADE_SHARES, - GameDef.OrStep.FINAL }; + // protected static GameDef.OrStep[] steps = + protected GameDef.OrStep[] steps = + new GameDef.OrStep[] { + GameDef.OrStep.INITIAL, + GameDef.OrStep.LAY_TRACK, + GameDef.OrStep.LAY_TOKEN, + GameDef.OrStep.CALC_REVENUE, + GameDef.OrStep.PAYOUT, + GameDef.OrStep.BUY_TRAIN, + GameDef.OrStep.TRADE_SHARES, + GameDef.OrStep.FINAL }; protected boolean doneAllowed = false; @@ -95,10 +96,10 @@ super (gameManager); operatingCompanies = setOperatingCompanies(); - + // sfy NoMapMode noMapMode = GameOption.convertValueToBoolean(getGameOption("NoMapMode")); - + guiHints.setVisibilityHint(GuiDef.Panel.STOCK_MARKET, false); guiHints.setVisibilityHint(GuiDef.Panel.STATUS, true); guiHints.setActivePanel(GuiDef.Panel.MAP); @@ -111,7 +112,7 @@ ReportBuffer.add(LocalText.getText("START_OR", thisOrNumber)); privatesPayOut(); - + if (operatingCompanies.size() > 0) { StringBuilder msg = new StringBuilder(); @@ -170,7 +171,7 @@ /*--- Common OR checks ---*/ /* Check operating company */ if (action instanceof PossibleORAction - && !(action instanceof DiscardTrain)) { + && !(action instanceof DiscardTrain)) { PublicCompanyI company = ((PossibleORAction) action).getCompany(); if (company != operatingCompany) { DisplayBuffer.add(LocalText.getText("WrongCompany", @@ -290,9 +291,9 @@ // Must be correct company. if (!companyName.equals(operatingCompany.getName())) { errMsg = - LocalText.getText("WrongCompany", - companyName, - operatingCompany.getName() ); + LocalText.getText("WrongCompany", + companyName, + operatingCompany.getName() ); break; } // Must be correct step @@ -305,14 +306,14 @@ if (!getCurrentPhase().isTileColourAllowed(tile.getColourName())) { errMsg = - LocalText.getText("TileNotYetAvailable", - tile.getExternalId()); + LocalText.getText("TileNotYetAvailable", + tile.getExternalId()); break; } if (tile.countFreeTiles() == 0) { errMsg = - LocalText.getText("TileNotAvailable", - tile.getExternalId()); + LocalText.getText("TileNotAvailable", + tile.getExternalId()); break; } @@ -325,10 +326,10 @@ List<TileI> tiles = action.getTiles(); if (tiles != null && !tiles.isEmpty() && !tiles.contains(tile)) { errMsg = - LocalText.getText( - "TileMayNotBeLaidInHex", - tile.getExternalId(), - hex.getName() ); + LocalText.getText( + "TileMayNotBeLaidInHex", + tile.getExternalId(), + hex.getName() ); break; } stl = action.getSpecialProperty(); @@ -341,8 +342,8 @@ */ if (!extra && !validateNormalTileLay(tile)) { errMsg = - LocalText.getText("NumberOfNormalTileLaysExceeded", - tile.getColourName()); + LocalText.getText("NumberOfNormalTileLaysExceeded", + tile.getColourName()); break; } @@ -356,23 +357,23 @@ // Amount must be non-negative multiple of 10 if (cost < 0) { errMsg = - LocalText.getText("NegativeAmountNotAllowed", - Bank.format(cost)); + LocalText.getText("NegativeAmountNotAllowed", + Bank.format(cost)); break; } if (cost % 10 != 0) { errMsg = - LocalText.getText("AmountMustBeMultipleOf10", - Bank.format(cost)); + LocalText.getText("AmountMustBeMultipleOf10", + Bank.format(cost)); break; } // Does the company have the money? if (cost > operatingCompany.getCash()) { errMsg = - LocalText.getText("NotEnoughMoney", - companyName, - Bank.format(operatingCompany.getCash()), - Bank.format(cost) ); + LocalText.getText("NotEnoughMoney", + companyName, + Bank.format(operatingCompany.getCash()), + Bank.format(cost) ); break; } break; @@ -416,7 +417,7 @@ stl.setExercised(); currentSpecialTileLays.remove(action); log.debug("This was a special tile lay, " - + (extra ? "" : " not") + " extra"); + + (extra ? "" : " not") + " extra"); } if (!extra) { @@ -426,11 +427,11 @@ setSpecialTileLays(); log.debug("There are now " + currentSpecialTileLays.size() - + " special tile lay objects"); + + " special tile lay objects"); } if (tile == null || currentNormalTileLays.isEmpty() - && currentSpecialTileLays.isEmpty()) { + && currentSpecialTileLays.isEmpty()) { nextStep(); } @@ -446,16 +447,16 @@ } protected boolean checkNormalTileLay(TileI tile, boolean update) { - -// Map<String,Integer> tileLaysPerColour = tileLaysPerColourState.getObject(); - -// if (tileLaysPerColour.isEmpty()) return false; + // Map<String,Integer> tileLaysPerColour = tileLaysPerColourState.getObject(); + + // if (tileLaysPerColour.isEmpty()) return false; + String colour = tile.getColourName(); Integer oldAllowedNumberObject = tileLaysPerColour.get(colour); if (oldAllowedNumberObject == null) return false; - + int oldAllowedNumber = oldAllowedNumberObject.intValue(); if (oldAllowedNumber <= 0) return false; @@ -467,29 +468,29 @@ * all normal tile lays have been consumed. 2. If any colour is laid, no * different colours may be laid. THIS MAY NOT BE TRUE FOR ALL GAMES! */ - -// Map<String,Integer> tileLaysPerColourUpdated = new HashMap<String, Integer>(); // new (empty) map - + + // Map<String,Integer> tileLaysPerColourUpdated = new HashMap<String, Integer>(); // new (empty) map + if (oldAllowedNumber <= 1) { - for (String key:tileLaysPerColour.keySet()) + for (String key:tileLaysPerColour.keySet()) new MapChange<String,Integer>(tileLaysPerColour, key, new Integer(0)); log.debug("No more normal tile lays allowed"); currentNormalTileLays.clear(); } else { -// tileLaysPerColourUpdated.put(colour, new Integer(oldAllowedNumber - 1)); - for (String key:tileLaysPerColour.keySet()) + // tileLaysPerColourUpdated.put(colour, new Integer(oldAllowedNumber - 1)); + for (String key:tileLaysPerColour.keySet()) if (colour.equals(key)) new MapChange<String,Integer> - (tileLaysPerColour, colour, new Integer(oldAllowedNumber-1)); + (tileLaysPerColour, colour, new Integer(oldAllowedNumber-1)); else new MapChange<String,Integer>(tileLaysPerColour, key, new Integer(0)); - log.debug((oldAllowedNumber - 1) + " more " + colour - + " tile lays allowed"); + log.debug((oldAllowedNumber - 1) + " more " + colour + + " tile lays allowed"); } - -// tileLaysPerColourState.set(tileLaysPerColourUpdated); + // tileLaysPerColourState.set(tileLaysPerColourUpdated); + return true; } @@ -503,7 +504,7 @@ MapHex hex = action.getChosenHex(); int station = action.getChosenStation(); String companyName = operatingCompany.getName(); - + // TEMPORARY FIX to enable fixing invalidated saved files //if ("N11".equals(hex.getName()) && station == 2) { // station = 1; @@ -515,7 +516,7 @@ // Checks // Must be correct step (exception: home base lay & some special token lay) - if (getStep() != GameDef.OrStep.LAY_TOKEN + if (getStep() != GameDef.OrStep.LAY_TOKEN && action.getType() != LayBaseToken.HOME_CITY && action.getType() != LayBaseToken.SPECIAL_PROPERTY) { errMsg = LocalText.getText("WrongActionNoTokenLay"); @@ -526,7 +527,7 @@ errMsg = LocalText.getText("HasNoTokensLeft", companyName); break; } - + if (!isTokenLayAllowed (operatingCompany, hex, station)) { errMsg = LocalText.getText("BaseTokenSlotIsReserved"); break; @@ -544,20 +545,20 @@ */ if (hex.hasTokenOfCompany(operatingCompany)) { errMsg = - LocalText.getText("TileAlreadyHasToken", - hex.getName(), - companyName ); + LocalText.getText("TileAlreadyHasToken", + hex.getName(), + companyName ); break; } - + if (action != null) { List<MapHex> locations = action.getLocations(); if (locations != null && locations.size() > 0 - && !locations.contains(hex) && !locations.contains(null)) { + && !locations.contains(hex) && !locations.contains(null)) { errMsg = - LocalText.getText("TokenLayingHexMismatch", - hex.getName(), - action.getLocationNameString() ); + LocalText.getText("TokenLayingHexMismatch", + hex.getName(), + action.getLocationNameString() ); break; } stl = action.getSpecialProperty(); @@ -573,7 +574,7 @@ companyName, Bank.format(operatingCompany.getCash()), Bank.format(cost)); - break; + break; } break; } @@ -616,18 +617,18 @@ stl.setExercised(); currentSpecialTokenLays.remove(action); log.debug("This was a special token lay, " - + (extra ? "" : " not") + " extra"); + + (extra ? "" : " not") + " extra"); } - + // Jump out if we aren't in the token laying step if (getStep() != GameDef.OrStep.LAY_TOKEN) return true; - + if (!extra) { currentNormalTokenLays.clear(); log.debug("This was a normal token lay"); } - + if (currentNormalTokenLays.isEmpty()) { log.debug("No more normal token lays are allowed"); } else if (operatingCompany.getNumberOfFreeBaseTokens() == 0) { @@ -638,9 +639,9 @@ } setSpecialTokenLays(); log.debug("There are now " + currentSpecialTokenLays.size() - + " special token lay objects"); + + " special token lay objects"); if (currentNormalTokenLays.isEmpty() - && currentSpecialTokenLays.isEmpty()) { + && currentSpecialTokenLays.isEmpty()) { nextStep(); } @@ -666,9 +667,9 @@ MapHex location = action.getChosenHex(); if (location != hex) { errMsg = - LocalText.getText("TokenLayingHexMismatch", - hex.getName(), - location.getName() ); + LocalText.getText("TokenLayingHexMismatch", + hex.getName(), + location.getName() ); break; } stl = action.getSpecialProperty(); @@ -681,8 +682,8 @@ // Does the company have the money? if (cost > operatingCompany.getCash()) { errMsg = - LocalText.getText("NotEnoughMoney", - operatingCompany.getName()); + LocalText.getText("NotEnoughMoney", + operatingCompany.getName()); break; } break; @@ -702,9 +703,9 @@ if (hex.layBonusToken(token, gameManager.getPhaseManager())) { /* TODO: the false return value must be impossible. */ - operatingCompany.addBonus(new Bonus(operatingCompany, - token.getName(), - token.getValue(), Collections.singletonList(hex))); + operatingCompany.addBonus(new Bonus(operatingCompany, + token.getName(), + token.getValue(), Collections.singletonList(hex))); token.setUser(operatingCompany); ReportBuffer.add(LocalText.getText("LaysBonusTokenOn", @@ -718,7 +719,7 @@ stl.setExercised(); currentSpecialTokenLays.remove(action); log.debug("This was a special token lay, " - + (extra ? "" : " not") + " extra"); + + (extra ? "" : " not") + " extra"); } @@ -745,10 +746,10 @@ // Does the company have the money? if (cost > operatingCompany.getCash()) { errMsg = - LocalText.getText("NotEnoughMoney", - operatingCompany.getName(), - Bank.format(operatingCompany.getCash()), - Bank.format(cost)); + LocalText.getText("NotEnoughMoney", + operatingCompany.getName(), + Bank.format(operatingCompany.getCash()), + Bank.format(cost)); break; } break; @@ -767,10 +768,10 @@ moveStack.start(true); new CashMove (operatingCompany, seller, cost); - operatingCompany.addBonus(new Bonus(operatingCompany, - sbt.getName(), - sbt.getValue(), - sbt.getLocations())); + operatingCompany.addBonus(new Bonus(operatingCompany, + sbt.getName(), + sbt.getValue(), + sbt.getLocations())); ReportBuffer.add(LocalText.getText("BuysBonusTokenFrom", operatingCompany.getName(), @@ -783,9 +784,9 @@ return true; } - - - + + + public boolean setRevenueAndDividend(SetDividend action) { String errMsg = validateSetRevenueAndDividend (action); @@ -831,9 +832,9 @@ companyName = company.getName(); if (company != operatingCompany) { errMsg = - LocalText.getText("WrongCompany", - companyName, - operatingCompa... [truncated message content] |
From: <ev...@us...> - 2010-07-17 15:06:21
|
Revision: 1343 http://rails.svn.sourceforge.net/rails/?rev=1343&view=rev Author: evos Date: 2010-07-17 15:06:13 +0000 (Sat, 17 Jul 2010) Log Message: ----------- Simplified addXxxx methods by using the new Util.addToList. Applied Phil's patch to add more private info Modified Paths: -------------- trunk/18xx/.settings/org.eclipse.jdt.core.prefs trunk/18xx/rails/game/City.java trunk/18xx/rails/game/GameManager.java trunk/18xx/rails/game/MapHex.java trunk/18xx/rails/game/Portfolio.java trunk/18xx/rails/game/PrivateCompany.java trunk/18xx/rails/game/StockRound.java trunk/18xx/rails/game/move/ObjectMove.java trunk/18xx/rails/util/Util.java Property Changed: ---------------- trunk/18xx/data/ Modified: trunk/18xx/.settings/org.eclipse.jdt.core.prefs =================================================================== --- trunk/18xx/.settings/org.eclipse.jdt.core.prefs 2010-07-17 11:08:38 UTC (rev 1342) +++ trunk/18xx/.settings/org.eclipse.jdt.core.prefs 2010-07-17 15:06:13 UTC (rev 1343) @@ -1,248 +1,258 @@ -#Tue Jun 03 20:16:50 GMT+01:00 2008 -eclipse.preferences.version=1 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=16 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=18 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false -org.eclipse.jdt.core.formatter.comment.format_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +#Sun Jul 04 20:27:07 CEST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=16 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=18 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false +org.eclipse.jdt.core.formatter.comment.format_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false +org.eclipse.jdt.core.formatter.comment.indent_root_tags=false +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false Property changes on: trunk/18xx/data ___________________________________________________________________ Added: svn:ignore + MyGames.xml Modified: trunk/18xx/rails/game/City.java =================================================================== --- trunk/18xx/rails/game/City.java 2010-07-17 11:08:38 UTC (rev 1342) +++ trunk/18xx/rails/game/City.java 2010-07-17 15:06:13 UTC (rev 1343) @@ -93,21 +93,11 @@ public boolean addToken(TokenI token, int position) { - if (tokens.contains(token)) { - return false; - } else { - token.setHolder(this); - if (position == -1) { - return tokens.add(token); - } else { - try { - tokens.add(position, token); - return true; - } catch (IndexOutOfBoundsException e) { - return false; - } - } - } + if (tokens.contains(token)) return false; + + boolean result = Util.addToList(tokens, token, position); + if (result) token.setHolder(this); + return result; } public boolean addObject(Moveable object, int position) { Modified: trunk/18xx/rails/game/GameManager.java =================================================================== --- trunk/18xx/rails/game/GameManager.java 2010-07-17 11:08:38 UTC (rev 1342) +++ trunk/18xx/rails/game/GameManager.java 2010-07-17 15:06:13 UTC (rev 1343) @@ -1537,16 +1537,7 @@ if (commonSpecialProperties == null) { commonSpecialProperties = new ArrayList<SpecialPropertyI>(2); } - if (position == -1) { - return commonSpecialProperties.add(property); - } else { - try { - commonSpecialProperties.add(position, property); - return true; - } catch (IndexOutOfBoundsException e) { - return false; - } - } + return Util.addToList(commonSpecialProperties, property, position); } /** Modified: trunk/18xx/rails/game/MapHex.java =================================================================== --- trunk/18xx/rails/game/MapHex.java 2010-07-17 11:08:38 UTC (rev 1342) +++ trunk/18xx/rails/game/MapHex.java 2010-07-17 15:06:13 UTC (rev 1343) @@ -794,19 +794,11 @@ offStationTokens = new ArrayList<TokenI>(); if (offStationTokens.contains(token)) { return false; - } else { - token.setHolder(this); - if (position == -1) { - return offStationTokens.add(token); - } else { - try { - offStationTokens.add(position, token); - return true; - } catch (IndexOutOfBoundsException e) { - return false; - } - } } + + boolean result = Util.addToList(offStationTokens, token, position); + if (result) token.setHolder(this); + return result; } public List<BaseToken> getBaseTokens () { Modified: trunk/18xx/rails/game/Portfolio.java =================================================================== --- trunk/18xx/rails/game/Portfolio.java 2010-07-17 11:08:38 UTC (rev 1342) +++ trunk/18xx/rails/game/Portfolio.java 2010-07-17 15:06:13 UTC (rev 1343) @@ -107,14 +107,9 @@ } public void addPrivate(PrivateCompanyI privateCompany, int position) { - if (position == -1) { - privateCompanies.add(privateCompany); - } else { - try { - privateCompanies.add(position, privateCompany); - } catch (IndexOutOfBoundsException e) { - } - } + + if (!Util.addToList(privateCompanies, privateCompany, position)) return; + privateCompany.setHolder(this); log.debug("Adding " + privateCompany.getName() + " to portfolio of " + name); @@ -135,16 +130,8 @@ certPerCompany.put(companyName, new ArrayList<PublicCertificateI>()); } - if (position == -1) { - certificates.add(certificate); - (certPerCompany.get(companyName)).add(certificate); - } else { - try { - certificates.add(position, certificate); - (certPerCompany.get(companyName)).add(position, certificate); - } catch (IndexOutOfBoundsException e) { - } - } + Util.addToList(certificates, certificate, position); + (certPerCompany.get(companyName)).add(certificate); String certTypeId = certificate.getTypeId(); if (!certsPerType.containsKey(certTypeId)) { @@ -387,14 +374,8 @@ } public void addTrain(TrainI train, int position) { - if (position == -1) { - trains.add(train); - } else { - try { - trains.add(position, train); - } catch (IndexOutOfBoundsException e) { - } - } + + Util.addToList(trains, train, position); TrainTypeI type = train.getType(); if (!trainsPerType.containsKey(type)) { trainsPerType.put(type, new ArrayList<TrainI>()); @@ -534,19 +515,14 @@ */ public boolean addSpecialProperty(SpecialPropertyI property, int position) { - boolean result = false; if (specialProperties == null) { specialProperties = new ArrayList<SpecialPropertyI>(2); } - if (position == -1) { - specialProperties.add(property); - } else { - try { - specialProperties.add(position, property); - } catch (IndexOutOfBoundsException e) { - } - } + + boolean result = Util.addToList(specialProperties, property, position); + if (!result) return false; + property.setHolder(this); // Special case for bonuses with predefined locations @@ -734,16 +710,8 @@ } public boolean addToken(TokenI token, int position) { - if (position == -1) { - return tokens.add(token); - } else { - try { - tokens.add(position, token); - return true; - } catch (IndexOutOfBoundsException e) { - return false; - } - } + + return Util.addToList(tokens, token, position); } public boolean removeToken(TokenI token) { Modified: trunk/18xx/rails/game/PrivateCompany.java =================================================================== --- trunk/18xx/rails/game/PrivateCompany.java 2010-07-17 11:08:38 UTC (rev 1342) +++ trunk/18xx/rails/game/PrivateCompany.java 2010-07-17 15:06:13 UTC (rev 1343) @@ -2,6 +2,7 @@ package rails.game; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import rails.game.move.*; @@ -54,7 +55,14 @@ // sfy 1889 changed to IntegerArray revenue = tag.getAttributeAsIntegerArray("revenue", new int[0]); - + + // pld: adding revenue to info text + infoText += "<br>Revenue: "; + for (int i = 0; i < revenue.length;i++) { + infoText += (Bank.format(revenue[i])); + if (i < revenue.length-1) {infoText += ", ";}; + } + // Blocked hexes (until bought by a company) Tag blockedTag = tag.getChild("Blocking"); if (blockedTag != null) { @@ -327,16 +335,7 @@ */ public boolean addObject(Moveable object, int position) { if (object instanceof SpecialPropertyI) { - if (position == -1) { - return specialProperties.add((SpecialPropertyI)object); - } else { - try { - specialProperties.add(position, (SpecialPropertyI)object); - return true; - } catch (IndexOutOfBoundsException e) { - return false; - } - } + return Util.addToList(specialProperties, (SpecialPropertyI)object, position); } else { return false; } Modified: trunk/18xx/rails/game/StockRound.java =================================================================== --- trunk/18xx/rails/game/StockRound.java 2010-07-17 11:08:38 UTC (rev 1342) +++ trunk/18xx/rails/game/StockRound.java 2010-07-17 15:06:13 UTC (rev 1343) @@ -190,7 +190,7 @@ stockSpace = comp.getCurrentSpace(); if ((stockSpace == null || !stockSpace.isNoCertLimit()) && !mayPlayerBuyCertificate( currentPlayer, comp, cert.getCertificateCount())) continue; - + shares = cert.getShares(); if (!cert.isPresidentShare()) { @@ -285,7 +285,7 @@ /* Would the player exceed the total certificate limit? */ if (!stockSpace.isNoCertLimit() - && !mayPlayerBuyCertificate(currentPlayer, comp, + && !mayPlayerBuyCertificate(currentPlayer, comp, number * uniqueCerts[shares].getCertificateCount())) continue; } @@ -766,7 +766,6 @@ break; } - //price = currentSpace.getPrice(); price = getBuyPrice (action, currentSpace); cost = shares * price / company.getShareUnitsForSharePrice(); @@ -1461,8 +1460,8 @@ company.getCurrentSpace().isNoHoldLimit() ? 100 : playerShareLimit; } - int maxAllowed = (limit - player.getPortfolio().getShare(company)) / shareSize; -// log.debug("MaxAllowedNumberOfSharesToBuy = " + maxAllowed + " for company = " + company + " shareSize " + shareSize); + int maxAllowed = (limit - player.getPortfolio().getShare(company)) / shareSize; + // log.debug("MaxAllowedNumberOfSharesToBuy = " + maxAllowed + " for company = " + company + " shareSize " + shareSize); return maxAllowed; } Modified: trunk/18xx/rails/game/move/ObjectMove.java =================================================================== --- trunk/18xx/rails/game/move/ObjectMove.java 2010-07-17 11:08:38 UTC (rev 1342) +++ trunk/18xx/rails/game/move/ObjectMove.java 2010-07-17 15:06:13 UTC (rev 1343) @@ -19,15 +19,13 @@ /** * Create a generic ObjectMove object. Any specific side effects must be - * implemented in the addToken and removeToken methods of the 'from' and - * 'to' TokenHolders. <p>The parameter descriptions cover the usual case of - * a Base Token lay, which is physically removed from a PublicCompany and - * added to a Station on a MapHex. + * implemented in the various addXxxx and removeXxxx methods of the 'from' and + * 'to' MoveableHolders, depending on the object type. * - * @param moveableObject The moveableObject to be moved (e.g. a BaseToken). - * @param from Where the moveableObject is removed from (e.g. a - * PublicCompany charter). + * @param moveableObject The object to be moved (e.g. a BaseToken). + * @param from Where the moveableObject is removed from (e.g. a PublicCompany charter). * @param to Where the moveableObject is moved to (e.g. a MapHex). + * It is moved to the end of the List in which the moved object type is stored. */ public ObjectMove(Moveable moveableObject, MoveableHolder from, @@ -35,6 +33,18 @@ this (moveableObject, from, to, -1); } + /** + * Create a generic ObjectMove object. Any specific side effects must be + * implemented in the various addXxxx and removeXxxx methods of the 'from' and + * 'to' MoveableHolders, depending on the object type. + * + * @param moveableObject The object to be moved (e.g. a BaseToken). + * @param from Where the moveableObject is removed from (e.g. a PublicCompany charter). + * @param to Where the moveableObject is moved to (e.g. a MapHex). + * @param toPosition At which List index in the 'to' holder the object must be inserted, + * -1 means at the end. + */ + public ObjectMove(Moveable moveableObject, MoveableHolder from, MoveableHolder to, int toPosition) { Modified: trunk/18xx/rails/util/Util.java =================================================================== --- trunk/18xx/rails/util/Util.java 2010-07-17 11:08:38 UTC (rev 1342) +++ trunk/18xx/rails/util/Util.java 2010-07-17 15:06:13 UTC (rev 1343) @@ -65,13 +65,13 @@ return bitmask | value; } else { System.out.println("Reset bit " + value + ": from " + bitmask - + " to " + (bitmask & ~value)); + + " to " + (bitmask & ~value)); return bitmask & ~value; } } /** - * Safely move objects from one holder to another, avoiding + * Safely move a list of objects from one holder to another, avoiding * ConcurrentModificationExceptions. * * @param from @@ -93,6 +93,29 @@ } + /** Safely add an object to a List at a given position + * @param objects The List to add the object to. + * @param object The object to be added. + * @param position The position at which the object must be added. + * <br>If between 0 and the current list size (inclusive), the object is inserted at + * the given position.<br>If -1, the object is inserted at the end. + * <br>If any other value, nothing is done. + * @return True if the insertion was successful. + * */ + public static <T extends Moveable, U extends T> boolean addToList (List<T> objects, + U object, int position) { + if (objects == null || object == null) { + return false; + } + if (position == -1) { + return objects.add(object); + } else if (position >= 0 && position <= objects.size()){ + objects.add(position, object); + return true; + } + return false; + } + /** * Parse a colour definition string. * Currently supported formats: @@ -117,8 +140,8 @@ try { String[] parts = s.split(","); c = new Color (Integer.parseInt(parts[0]), - Integer.parseInt(parts[1]), - Integer.parseInt(parts[2])); + Integer.parseInt(parts[1]), + Integer.parseInt(parts[2])); } catch (NumberFormatException e) { getLogger().error ("Invalid nummeric RGB colour: "+s, e); throw new ConfigurationException (e); @@ -133,8 +156,8 @@ public static boolean isDark(Color c) { if (c == null) return false; return Math.sqrt(0.241*c.getRed()*c.getRed() - + 0.691*c.getBlue()*c.getBlue() - + 0.068*c.getGreen()*c.getGreen()) < 128; + + 0.691*c.getBlue()*c.getBlue() + + 0.068*c.getGreen()*c.getGreen()) < 128; // Copied this formula from // http://www.nbdtech.com/blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-07-17 20:27:29
|
Revision: 1344 http://rails.svn.sourceforge.net/rails/?rev=1344&view=rev Author: stefanfrey Date: 2010-07-17 20:27:23 +0000 (Sat, 17 Jul 2010) Log Message: ----------- Update configuration management Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/data/Properties.xml trunk/18xx/rails/ui/swing/ConfigWindow.java trunk/18xx/rails/util/Config.java trunk/18xx/rails/util/ConfigItem.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-07-17 15:06:13 UTC (rev 1343) +++ trunk/18xx/LocalisedText.properties 2010-07-17 20:27:23 UTC (rev 1344) @@ -64,6 +64,7 @@ CLOSE_WINDOW=Do you really want to exit the game? COMPANY=Company COMPANY_DETAILS=Company details +CONFIG_CURRENT_PROFILE=Active profile = {0} (based on = {1}) CORRECT_CASH=Cash Correction CORRECT_MAP=Map Correction CURRENT=Current Modified: trunk/18xx/data/Properties.xml =================================================================== --- trunk/18xx/data/Properties.xml 2010-07-17 15:06:13 UTC (rev 1343) +++ trunk/18xx/data/Properties.xml 2010-07-17 20:27:23 UTC (rev 1344) @@ -4,7 +4,7 @@ --> <Properties> <Panel name="General"> - <Property name="locale" type="STRING"/> + <Property name="locale" type="LIST" values="en_US,de" /> </Panel> <Panel name="Colors"> <Property name="route.colour.1" type="COLOR"/> Modified: trunk/18xx/rails/ui/swing/ConfigWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-17 15:06:13 UTC (rev 1343) +++ trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-17 20:27:23 UTC (rev 1344) @@ -2,29 +2,49 @@ import java.awt.Color; import java.awt.Component; +import java.awt.EventQueue; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.io.File; import java.util.Map; import java.util.List; +import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JColorChooser; +import javax.swing.JComboBox; import javax.swing.JComponent; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileFilter; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.JSpinner; import javax.swing.JTabbedPane; +import javax.swing.SpinnerListModel; +import javax.swing.SwingConstants; +import javax.swing.border.Border; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import rails.game.ConfigurationException; import rails.util.Config; import rails.util.ConfigItem; import rails.util.LocalText; +import rails.util.Util; class ConfigWindow extends JFrame { private static final long serialVersionUID = 1L; - private JTabbedPane pane; + private JPanel profilePanel; + private JTabbedPane configPane; + private JPanel buttonPanel; ConfigWindow() { // JFrame properties @@ -32,55 +52,66 @@ // setSize(400,300); // add profile panel - add(setupProfilePanel(), "North"); + profilePanel = new JPanel(); + add(profilePanel, "North"); // configSetup pane - setupConfigPane(); - add(pane, "Center"); + configPane = new JTabbedPane(); + add(configPane, "Center"); // buttons - JPanel buttonPanel = new JPanel(); - - JButton saveButton = new JButton(LocalText.getText("Save")); - saveButton.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent arg0) { - ConfigWindow.this.saveConfig(); - } - } - ); - buttonPanel.add(saveButton); + buttonPanel = new JPanel(); + add(buttonPanel, "South"); - JButton cancelButton = new JButton(LocalText.getText("Cancel")); - cancelButton.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent arg0) { - ConfigWindow.this.cancelConfig(); - } - } - ); - buttonPanel.add(cancelButton); - - add(buttonPanel, "South"); - + init(); + } + + private void init() { + setupProfilePanel(); + setupConfigPane(); + setupButtonPanel(); this.pack(); } - - private JComponent setupProfilePanel() { - JComponent panel = new JPanel(); - panel.setLayout(new GridLayout(0,4)); + private void setupProfilePanel() { + profilePanel.removeAll(); - // default profile + profilePanel.setLayout(new GridLayout(0,4)); + String activeProfile = Config.getActiveProfileName(); + String defaultProfile = Config.getDefaultProfileName(); + Border etched = BorderFactory.createEtchedBorder(); + Border titled = BorderFactory.createTitledBorder(etched, LocalText.getText("CONFIG_CURRENT_PROFILE", activeProfile, defaultProfile)); + profilePanel.setBorder(titled); - return panel; + JLabel userLabel = new JLabel(LocalText.getText("CONFIG_SELECT_USER")); + profilePanel.add(userLabel); + final JComboBox comboBoxUser = new JComboBox(Config.getUserProfiles().toArray()); + comboBoxUser.setSelectedItem(Config.getActiveProfileName()); + comboBoxUser.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent arg0) { + Config.changeActiveProfile((String)comboBoxUser.getSelectedItem()); + EventQueue.invokeLater(new Runnable() { + public void run() { + init(); + ConfigWindow.this.repaint(); + } + } + ); + } + } + ); + profilePanel.add(comboBoxUser); + } private void setupConfigPane() { - // create pane - pane = new JTabbedPane(); + configPane.removeAll(); + Border etched = BorderFactory.createEtchedBorder(); + Border titled = BorderFactory.createTitledBorder(etched, LocalText.getText("CONFIG_SETTINGS")); + configPane.setBorder(titled); + Map<String, List<ConfigItem>> configPanels = Config.getConfigPanels(); for (String panelName:configPanels.keySet()) { @@ -89,54 +120,153 @@ for (ConfigItem item:configPanels.get(panelName)) { defineElement(newPanel, item); } - pane.addTab(panelName, newPanel); + configPane.addTab(panelName, newPanel); } } - private void defineElement(JPanel panel, ConfigItem item) { - + private void defineElement(JPanel panel, final ConfigItem item) { + // item label panel.add(new JLabel(LocalText.getText("Config." + item.name))); - final String configValue = Config.get(item.name); + // standard components + final String configValue = item.getCurrentValue(); + + switch (item.type) { - case COLOR: { + case COLOR: final JLabel label = new JLabel(configValue); Color selectedColor; try { - selectedColor = Color.decode(configValue); - } catch (NumberFormatException e) { + selectedColor = Util.parseColour(configValue); + } catch (ConfigurationException e) { selectedColor = Color.WHITE; } label.setOpaque(true); + label.setHorizontalAlignment(SwingConstants.CENTER); label.setBackground(selectedColor); + if (Util.isDark(selectedColor)) { + label.setForeground(Color.WHITE); + } else { + label.setForeground(Color.BLACK); + } panel.add(label); - JButton button = new JButton("Color"); + JButton button = new JButton("Choose..."); final Color oldColor = selectedColor; button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { Color selectedColor=JColorChooser.showDialog(ConfigWindow.this, "", oldColor); - label.setText(Integer.toHexString(selectedColor.getRGB()).substring(2)); + if (selectedColor == null) return; + String newValue = Integer.toHexString(selectedColor.getRGB()).substring(3); + label.setText(newValue); + item.setNewValue(newValue); label.setBackground(selectedColor); + if (Util.isDark(selectedColor)) { + label.setForeground(Color.WHITE); + } else { + label.setForeground(Color.BLACK); + } } } ); panel.add(button); break; - } + case LIST: + final JComboBox comboBox = new JComboBox(item.allowedValues.toArray()); + comboBox.setSelectedItem(configValue); + comboBox.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent arg0) { + // do nothing + } + public void focusLost(FocusEvent arg0) { + item.setNewValue((String)comboBox.getSelectedItem()); + } + } + ); + panel.add(comboBox); + break; case STRING: - default: { - JFormattedTextField textField = new JFormattedTextField(); + default: // default like String + final JFormattedTextField textField = new JFormattedTextField(); textField.setValue(configValue); + textField.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent arg0) { + // do nothing + } + public void focusLost(FocusEvent arg0) { + item.setNewValue(textField.getText()); + } + } + ); panel.add(textField); + break; } + } + + private void setupButtonPanel() { + buttonPanel.removeAll(); + + // save button + if (Config.isFilePathDefined()) { + JButton saveButton = new JButton(LocalText.getText("SAVE")); + saveButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + ConfigWindow.this.saveConfig(); + } + } + ); + buttonPanel.add(saveButton); } + + JButton saveAsButton = new JButton(LocalText.getText("SAVEAS")); + saveAsButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + ConfigWindow.this.saveAsConfig(); + } + } + ); + buttonPanel.add(saveAsButton); + + JButton cancelButton = new JButton(LocalText.getText("CANCEL")); + cancelButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + ConfigWindow.this.cancelConfig(); + } + } + ); + buttonPanel.add(cancelButton); + } private void saveConfig() { this.dispose(); } + private void saveAsConfig() { + JFileChooser fc = new JFileChooser(); + fc.setFileFilter( + new FileFilter() { + public boolean accept( File f ){ + return f.isDirectory() || + f.getName().toLowerCase().endsWith( ".rails_config" ); + } + public String getDescription() { + return "Rails Config"; + } + } + ); + + int state = fc.showOpenDialog( null ); + if ( state == JFileChooser.APPROVE_OPTION ) + { + File file = fc.getSelectedFile(); + Config.setActiveFilepath(file.getPath()); + } + } + private void cancelConfig() { this.dispose(); } Modified: trunk/18xx/rails/util/Config.java =================================================================== --- trunk/18xx/rails/util/Config.java 2010-07-17 15:06:13 UTC (rev 1343) +++ trunk/18xx/rails/util/Config.java 2010-07-17 20:27:23 UTC (rev 1344) @@ -8,10 +8,13 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; import org.apache.log4j.Logger; @@ -31,13 +34,6 @@ protected static Logger log = Logger.getLogger(Config.class.getPackage().getName()); - - /** - * Defines possible types (Java classes used as types in ConfigItem below - */ - public static enum ConfigType { - INTEGER, FLOAT, STRING, BOOLEAN, DIRECTORY, COLOR; - } /** XML setup */ private static final String CONFIG_XML_DIR = "data"; @@ -59,12 +55,11 @@ private static final String TEST_PROFILE_SELECTION = "test"; private static final String DEFAULT_PROFILE_SELECTION = "default"; private static final String DEFAULT_PROFILE_PROPERTY = "default.profile"; - private static final String STANDARD_PROFILE_PROPERTY = "standard.profile"; + private static final String STANDARD_PROFILE_SELECTION = "user"; /** selected profile */ private static String selectedProfile; private static boolean legacyConfigFile; - private static boolean standardProfile; /** properties storage. */ private static Properties defaultProperties = new Properties(); @@ -157,20 +152,13 @@ } -// /** -// * store user config file -// */ -// public static boolean saveUserConfig() { -// } -// -// /** -// * @return if user location is defined -// */ -// public static boolean hasUserLocation() { -// return userConfigFile != null; -// } + /** + * @return if user location is defined + */ + public static boolean isFilePathDefined() { + return Util.hasValue(userProfiles.getProperty(selectedProfile)); + } - private static boolean storePropertyFile(Properties properties, String filepath) { File outFile = new File(filepath); boolean result = true; @@ -192,24 +180,46 @@ /** * change active Profile */ - public static boolean setActiveProfile(String profileName) { - boolean result = loadPropertyProfile(profileName); - if (result) selectedProfile = profileName; - return result; + public static boolean changeActiveProfile(String profileName) { + readConfigSetupXML(); + loadPropertyProfile(profileName); + selectedProfile = profileName; + return true; } + private static Map<String, String> convertProperties(Properties properties) { + Map<String, String> converted = new HashMap<String, String>(); + for (Object key:properties.keySet()) { + converted.put((String) key, (String) properties.get(key)); + } + return converted; + } + + + /** + * get all default profiles + */ + public static List<String> getDefaultProfiles() { + List<String> profiles = new ArrayList<String>(convertProperties(defaultProfiles).keySet()); + profiles.remove(DEFAULT_PROFILE_PROPERTY); + Collections.sort(profiles); + return profiles; + } + + /** + * get all user profiles + */ + public static List<String> getUserProfiles() { + List<String> profiles = new ArrayList<String>(convertProperties(userProfiles).keySet()); + Collections.sort(profiles); + return profiles; + } + /** * returns name of (active) default profile */ public static String getDefaultProfileName() { - String defaultProfileName = null; - if (isUserProfileActive()) { - defaultProfileName = userProfiles.getProperty(DEFAULT_PROFILE_PROPERTY); - if (defaultProfileName == null) { -// return - } - } - return defaultProfileName; + return userProperties.getProperty(DEFAULT_PROFILE_PROPERTY); } /** @@ -235,13 +245,6 @@ } /** - * returns true if active profile is a user profile - */ - public static boolean isUserProfileActive() { - return userProfiles.getProperty(selectedProfile) != null; - } - - /** * activates settings used for testing */ public static void setConfigTest() { @@ -290,9 +293,8 @@ } /* if nothing has selected so far, choose standardProfile */ - standardProfile = false; if (!Util.hasValue(configSelection)) { - standardProfile = true; + configSelection = STANDARD_PROFILE_SELECTION; } selectedProfile = configSelection; @@ -303,7 +305,7 @@ private static void initialLoad() { if (legacyConfigFile) { if (!propertiesLoaded) { - loadPropertyFile(defaultProperties, selectedProfile, true, false); + loadPropertyFile(defaultProperties, selectedProfile, false); propertiesLoaded = true; setSaveDirDefaults(); } @@ -311,45 +313,47 @@ } if (!profilesLoaded) { - loadPropertyFile(defaultProfiles, defaultProfilesFile, true, false); - loadPropertyFile(userProfiles, userProfilesFile, false, false); + loadPropertyFile(defaultProfiles, defaultProfilesFile, true); + loadPropertyFile(userProfiles, userProfilesFile, false); profilesLoaded = true; } - if (standardProfile) { - selectedProfile = userProfiles.getProperty(STANDARD_PROFILE_PROPERTY); - if (selectedProfile == null) { - selectedProfile = defaultProfiles.getProperty(STANDARD_PROFILE_PROPERTY); - } - if (selectedProfile == null) { - selectedProfile = DEFAULT_PROFILE_SELECTION; - } - } - /* Tell the properties loader to read this file. */ log.info("Selected profile = " + selectedProfile); if (!propertiesLoaded) { - propertiesLoaded = loadPropertyProfile(selectedProfile); + loadPropertyProfile(selectedProfile); + propertiesLoaded = true; } } - private static boolean loadPropertyProfile(String profileName) { + /** + * loads a user profile and the according default profile + * if not defined or loadable, creates a default user profile + */ + private static void loadPropertyProfile(String userProfile) { + // reset properties + userProperties = new Properties(); + defaultProperties = new Properties(); - /* first check if it is a default profile */ - String defaultConfigFile = defaultProfiles.getProperty(profileName); + // check if the profile is already defined under userProfiles + String userConfigFile = userProfiles.getProperty(userProfile); + String defaultConfigFile = null; + if (Util.hasValue(userConfigFile) && // load user profile + loadPropertyFile(userProperties, userConfigFile, false)) { + String defaultConfig = userProperties.getProperty(DEFAULT_PROFILE_PROPERTY); + if (defaultConfig != null) { + defaultConfigFile = defaultProfiles.getProperty(defaultConfig); + } + } else { + userProfiles.setProperty(userProfile, ""); + } if (defaultConfigFile == null) { - String userConfigFile = userProfiles.getProperty(profileName); - if (userConfigFile == null) return false; - loadPropertyFile(userProperties, userConfigFile, false, false); - defaultConfigFile = userProperties.getProperty(DEFAULT_PROFILE_PROPERTY); - if (defaultConfigFile == null) { - defaultConfigFile = defaultProfiles.getProperty(DEFAULT_PROFILE_SELECTION); - } + defaultConfigFile = defaultProfiles.getProperty(DEFAULT_PROFILE_SELECTION); + userProperties.setProperty(DEFAULT_PROFILE_PROPERTY, DEFAULT_PROFILE_SELECTION); } - loadPropertyFile(defaultProperties, defaultConfigFile, true, false); + loadPropertyFile(defaultProperties, defaultConfigFile, true); setSaveDirDefaults(); - return true; } /** @@ -357,11 +361,11 @@ * * @param filename - file key name as a String. * @param resource - if TRUE, loaded from jar (via classloader), otherwise from filesystem - * @param required - if TRUE, an exception will be logged if the file does - * not exist. + * @return TRUE if load was successful */ - private static void loadPropertyFile(Properties properties, String filename, boolean resource, boolean required) { + private static boolean loadPropertyFile(Properties properties, String filename, boolean resource) { + boolean result = true; try { log.info("Loading properties from file " + filename); InputStream inFile; @@ -371,15 +375,13 @@ inFile = new FileInputStream(filename); } properties.load(inFile); - } catch (FileNotFoundException FNFE) { - if (required) { - System.err.println("File not found: " + filename); - } } catch (Exception e) { System.err.println(e + " whilst loading properties file " + filename); e.printStackTrace(System.err); + result = false; } + return result; } private static void setSaveDirDefaults() { Modified: trunk/18xx/rails/util/ConfigItem.java =================================================================== --- trunk/18xx/rails/util/ConfigItem.java 2010-07-17 15:06:13 UTC (rev 1343) +++ trunk/18xx/rails/util/ConfigItem.java 2010-07-17 20:27:23 UTC (rev 1344) @@ -2,21 +2,38 @@ import java.util.Arrays; import java.util.List; + +import org.apache.log4j.Logger; + import rails.game.ConfigurationException; -import rails.util.Config.ConfigType; /** * Defines an item used for the configuration of rails * T represents the value type */ -public class ConfigItem { +public final class ConfigItem { + + protected static Logger log = + Logger.getLogger(ConfigItem.class.getPackage().getName()); + + /** + * Defines possible types (Java classes used as types in ConfigItem below + */ + public static enum ConfigType { + INTEGER, FLOAT, STRING, BOOLEAN, LIST, DIRECTORY, COLOR; + } + + // static attributes public final String name; public final ConfigType type; public final List<String> allowedValues; public final String formatMask; public final String helpText; + // dynamic attributes + private String newValue; + ConfigItem(Tag tag) throws ConfigurationException { // check name and type (required) String name = tag.getAttributeAsString("name"); @@ -25,29 +42,68 @@ } else { throw new ConfigurationException("Missing name for configuration item"); } - String type = tag.getAttributeAsString("type"); - if (Util.hasValue(type)) { - this.type = ConfigType.valueOf(type); - } else { - throw new ConfigurationException("Missing or invalid type for configuration item"); - } // optional: list of allowed values String valueString = tag.getAttributeAsString("values"); if (Util.hasValue(valueString)) { allowedValues = Arrays.asList(valueString.split(",")); + this.type = ConfigType.LIST; } else { allowedValues = null; + String type = tag.getAttributeAsString("type"); + if (Util.hasValue(type)) { + try { + this.type = ConfigType.valueOf(type.toUpperCase()); + } catch (Exception e) { + throw new ConfigurationException("Missing or invalid type for configuration item"); + } + } else { + throw new ConfigurationException("Missing or invalid type for configuration item"); + } + if (this.type == ConfigType.LIST) { + throw new ConfigurationException("No values defined for LIST config item"); + } } + // optional: formatMask formatMask = tag.getAttributeAsString("formatMask"); // optional: helpText helpText = tag.getAttributeAsString("formatMask"); + + newValue = null; } + public boolean hasNewValue() { + return (newValue != null); + } + + public String getNewValue() { + return newValue; + } + + public void setNewValue(String newValue) { + if (newValue.equals(getConfigValue())) { + this.newValue = null; + } else { + this.newValue = newValue; + } + log.debug("ConfigItem " + name + " set to new value " + this.newValue); + } + + public String getCurrentValue() { + if (newValue != null) return newValue; + return getConfigValue(); + } + + public String getConfigValue() { + return Config.get(this.name); + } + public String toString() { StringBuffer s = new StringBuffer(); s.append("Configuration Item: name = " + name + ", type = " + type); + s.append(", config value = " + getConfigValue()); + s.append(", current value = " + getCurrentValue()); if (allowedValues != null) { s.append(", allowedValues = " + allowedValues); } @@ -57,6 +113,7 @@ if (helpText != null) { s.append(", helpText = " + helpText); } + return s.toString(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-07-19 20:52:25
|
Revision: 1351 http://rails.svn.sourceforge.net/rails/?rev=1351&view=rev Author: stefanfrey Date: 2010-07-19 20:52:17 +0000 (Mon, 19 Jul 2010) Log Message: ----------- Further update of configuration mechanism Modified Paths: -------------- trunk/18xx/data/Properties.xml trunk/18xx/rails/ui/swing/ConfigWindow.java trunk/18xx/rails/ui/swing/GameUIManager.java trunk/18xx/rails/ui/swing/StatusWindow.java trunk/18xx/test/test.properties Modified: trunk/18xx/data/Properties.xml =================================================================== --- trunk/18xx/data/Properties.xml 2010-07-18 17:24:36 UTC (rev 1350) +++ trunk/18xx/data/Properties.xml 2010-07-19 20:52:17 UTC (rev 1351) @@ -4,8 +4,12 @@ --> <Properties> <Panel name="General"> - <Property name="locale" type="LIST" values="en_US,de" /> + <Property name="locale" type="LIST" values="en_US,te_ST" helpText="Language Selection" /> </Panel> + <Panel name="Save"> + <Property name="save.dir" type="DIRECTORY" helpText="Default save file directory" /> + + </Panel> <Panel name="Colors"> <Property name="route.colour.1" type="COLOR"/> </Panel> Modified: trunk/18xx/rails/ui/swing/ConfigWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-18 17:24:36 UTC (rev 1350) +++ trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-19 20:52:17 UTC (rev 1351) @@ -2,13 +2,18 @@ import java.awt.Color; import java.awt.EventQueue; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; import java.awt.GridLayout; +import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.io.File; import java.util.Map; import java.util.List; @@ -19,6 +24,7 @@ import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; +import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; @@ -26,6 +32,7 @@ import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.SwingConstants; +import javax.swing.WindowConstants; import javax.swing.border.Border; import rails.game.ConfigurationException; @@ -38,7 +45,7 @@ private static final long serialVersionUID = 1L; private static final String CONFIG_EXTENSION = ".rails_config"; - private static final String CONFIG_DESCRIPTION = "Rails configuration files (.rails_config)"; + private static final String CONFIG_DESCRIPTION = "Rails configuration files ( *.rails_config )"; private JPanel profilePanel; private JTabbedPane configPane; @@ -61,10 +68,17 @@ buttonPanel = new JPanel(); add(buttonPanel, "South"); - init(); + // hide on close and inform + this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + cancelConfig(); + } + }); } - private void init() { + public void init() { setupProfilePanel(); setupConfigPane(); setupButtonPanel(); @@ -94,7 +108,9 @@ ); profilePanel.add(comboBoxUser); - // new button + JPanel buttonPanel = new JPanel(); + + // button to create a new profile JButton newButton = new JButton(LocalText.getText("NEW")); newButton.addActionListener( new ActionListener() { @@ -103,7 +119,20 @@ } } ); - profilePanel.add(newButton); + buttonPanel.add(newButton); + + // button to load a new profile + JButton loadButton = new JButton(LocalText.getText("LOAD")); + loadButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + loadProfile(); + } + } + ); + buttonPanel.add(loadButton); + + profilePanel.add(buttonPanel); } @@ -118,75 +147,123 @@ for (String panelName:configPanels.keySet()) { JPanel newPanel = new JPanel(); - newPanel.setLayout(new GridLayout(0,3)); + newPanel.setLayout(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridwidth = 1; + gbc.gridheight = 1; + gbc.gridx = 0; + gbc.weightx = 0.8; + gbc.weighty = 0.8; + gbc.insets = new Insets(10,10,10,10); + gbc.anchor = GridBagConstraints.WEST; for (ConfigItem item:configPanels.get(panelName)) { - defineElement(newPanel, item); + gbc.gridx = 0; + defineElement(newPanel, item, gbc); + gbc.gridy ++; } configPane.addTab(panelName, newPanel); } } - private void defineElement(JPanel panel, final ConfigItem item) { - // item label - panel.add(new JLabel(LocalText.getText("Config." + item.name))); + + private void addToGridBag(JComponent container, JComponent element, GridBagConstraints gbc) { + container.add(element, gbc); + gbc.gridx ++; + } + + private void defineElement(JPanel panel, final ConfigItem item, GridBagConstraints gbc) { // standard components final String configValue = item.getCurrentValue(); + final String toolTip = item.helpText; + // item label + JLabel label = new JLabel(LocalText.getText("Config." + item.name)); + label.setToolTipText(toolTip); + gbc.fill = GridBagConstraints.NONE; + addToGridBag(panel, label, gbc); switch (item.type) { + case LIST: + final JComboBox comboBox = new JComboBox(item.allowedValues.toArray()); + comboBox.setSelectedItem(configValue); + comboBox.setToolTipText(toolTip); + comboBox.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent arg0) { + // do nothing + } + public void focusLost(FocusEvent arg0) { + item.setNewValue((String)comboBox.getSelectedItem()); + } + } + ); + gbc.fill = GridBagConstraints.HORIZONTAL; + addToGridBag(panel, comboBox, gbc); + break; + case DIRECTORY: + final JLabel dirLabel = new JLabel(configValue); + dirLabel.setHorizontalAlignment(SwingConstants.CENTER); + dirLabel.setToolTipText(toolTip); + gbc.fill = GridBagConstraints.HORIZONTAL; + addToGridBag(panel, dirLabel, gbc); + JButton dirButton = new JButton("Choose..."); + dirButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JFileChooser fc = new JFileChooser(dirLabel.getText()); + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int state = fc.showOpenDialog(ConfigWindow.this); + if ( state == JFileChooser.APPROVE_OPTION ){ + File file = fc.getSelectedFile(); + dirLabel.setText(file.getAbsolutePath()); + item.setNewValue(file.getAbsolutePath()); + } + } + } + ); + gbc.fill = GridBagConstraints.NONE; + addToGridBag(panel, dirButton, gbc); + break; case COLOR: - final JLabel label = new JLabel(configValue); + final JLabel colorLabel = new JLabel(configValue); Color selectedColor; try { selectedColor = Util.parseColour(configValue); } catch (ConfigurationException e) { selectedColor = Color.WHITE; } - label.setOpaque(true); - label.setHorizontalAlignment(SwingConstants.CENTER); - label.setBackground(selectedColor); + colorLabel.setOpaque(true); + colorLabel.setHorizontalAlignment(SwingConstants.CENTER); + colorLabel.setBackground(selectedColor); if (Util.isDark(selectedColor)) { - label.setForeground(Color.WHITE); + colorLabel.setForeground(Color.WHITE); } else { - label.setForeground(Color.BLACK); + colorLabel.setForeground(Color.BLACK); } - panel.add(label); - JButton button = new JButton("Choose..."); - final Color oldColor = selectedColor; - button.addActionListener( + colorLabel.setToolTipText(toolTip); + gbc.fill = GridBagConstraints.HORIZONTAL; + addToGridBag(panel, colorLabel, gbc); + JButton colorButton = new JButton("Choose..."); + colorButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { - Color selectedColor=JColorChooser.showDialog(ConfigWindow.this, "", oldColor); + Color selectedColor=JColorChooser.showDialog(ConfigWindow.this, "", colorLabel.getBackground()); if (selectedColor == null) return; String newValue = Integer.toHexString(selectedColor.getRGB()).substring(3); - label.setText(newValue); + colorLabel.setText(newValue); item.setNewValue(newValue); - label.setBackground(selectedColor); + colorLabel.setBackground(selectedColor); if (Util.isDark(selectedColor)) { - label.setForeground(Color.WHITE); + colorLabel.setForeground(Color.WHITE); } else { - label.setForeground(Color.BLACK); + colorLabel.setForeground(Color.BLACK); } } } ); - panel.add(button); + gbc.fill = GridBagConstraints.NONE; + addToGridBag(panel, colorButton, gbc); break; - case LIST: - final JComboBox comboBox = new JComboBox(item.allowedValues.toArray()); - comboBox.setSelectedItem(configValue); - comboBox.addFocusListener(new FocusListener() { - public void focusGained(FocusEvent arg0) { - // do nothing - } - public void focusLost(FocusEvent arg0) { - item.setNewValue((String)comboBox.getSelectedItem()); - } - } - ); - panel.add(comboBox); - break; case STRING: default: // default like String final JFormattedTextField textField = new JFormattedTextField(); @@ -200,7 +277,8 @@ } } ); - panel.add(textField); + gbc.fill = GridBagConstraints.HORIZONTAL; + addToGridBag(panel, textField, gbc); break; } } @@ -262,6 +340,31 @@ }); } + private void loadProfile() { + String directory = Config.get("save.directory"); + + JFileChooser fc = new JFileChooser(directory); + fc.setFileFilter( + new FileFilter() { + public boolean accept( File f ){ + return f.isDirectory() || + f.getName().toLowerCase().endsWith( ".rails_config" ); + } + public String getDescription() { + return CONFIG_DESCRIPTION; + } + } + ); + int state = fc.showOpenDialog(this); + if ( state == JFileChooser.APPROVE_OPTION ) + { + File file = fc.getSelectedFile(); + if (Config.loadProfileFromFile(file)) { + changeProfile(Config.getActiveProfileName()); + } + } + } + private void changeProfile(String profileName) { Config.changeActiveProfile(profileName); EventQueue.invokeLater(new Runnable() { @@ -273,7 +376,10 @@ } private void saveConfig() { + Config.updateProfile(); // transfer the configitem to the active profile Config.saveActiveProfile(); + JOptionPane.showMessageDialog(ConfigWindow.this, LocalText.getText("CONFIG_SAVE_MESSAGE"), + LocalText.getText("CONFIG_SAVE_TITLE"), JOptionPane.INFORMATION_MESSAGE); } private void saveAsConfig() { @@ -303,12 +409,19 @@ File file = fc.getSelectedFile(); Config.setActiveFilepath(file.getPath()); saveConfig(); - setupButtonPanel(); + EventQueue.invokeLater(new Runnable() { + public void run() { + setupButtonPanel(); + ConfigWindow.this.pack(); + ConfigWindow.this.repaint(); + } + }); } } private void cancelConfig() { - this.dispose(); + StatusWindow.uncheckMenuItemBox(StatusWindow.CONFIG_CMD); + this.setVisible(false); } } Modified: trunk/18xx/rails/ui/swing/GameUIManager.java =================================================================== --- trunk/18xx/rails/ui/swing/GameUIManager.java 2010-07-18 17:24:36 UTC (rev 1350) +++ trunk/18xx/rails/ui/swing/GameUIManager.java 2010-07-19 20:52:17 UTC (rev 1351) @@ -1,6 +1,9 @@ package rails.ui.swing; import java.awt.Font; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.io.File; import java.text.SimpleDateFormat; import java.util.*; @@ -26,6 +29,7 @@ public StockChart stockChart; public StatusWindow statusWindow; public ReportWindow reportWindow; + public ConfigWindow configWindow; public ORUIManager orUIManager; public ORWindow orWindow; // TEMPORARY private StartRoundWindow startRoundWindow; @@ -151,6 +155,13 @@ Class<? extends StatusWindow> statusWindowClass = Class.forName(statusWindowClassName).asSubclass(StatusWindow.class); statusWindow = statusWindowClass.newInstance(); + +// GraphicsEnvironment ge = GraphicsEnvironment. +// getLocalGraphicsEnvironment(); +// GraphicsDevice[] gs = ge.getScreenDevices(); +// log.debug("ScreenDevices = " + Arrays.toString(gs)); +// statusWindow = statusWindowClass.getConstructor(GraphicsConfiguration.class).newInstance(gs[1].getDefaultConfiguration()); + statusWindow.init(this); } catch (Exception e) { log.fatal("Cannot instantiate class " + statusWindowClassName, e); @@ -160,6 +171,10 @@ updateUI(); reportWindow.scrollDown(); + + // define configWindow + configWindow = new ConfigWindow(); + configWindow.init(); } public void startLoadedGame() { Modified: trunk/18xx/rails/ui/swing/StatusWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/StatusWindow.java 2010-07-18 17:24:36 UTC (rev 1350) +++ trunk/18xx/rails/ui/swing/StatusWindow.java 2010-07-19 20:52:17 UTC (rev 1351) @@ -608,9 +608,7 @@ } else if (command.equals(MAP_CMD)) { gameUIManager.orWindow.setVisible(((JMenuItem) actor.getSource()).isSelected()); } else if (command.equals(CONFIG_CMD)) { - JFrame configWindow = new ConfigWindow(); - configWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - configWindow.setVisible(true); + gameUIManager.configWindow.setVisible(((JMenuItem) actor.getSource()).isSelected()); } else if (executedAction == null) { ; } else if (executedAction instanceof GameAction) { Modified: trunk/18xx/test/test.properties =================================================================== --- trunk/18xx/test/test.properties 2010-07-18 17:24:36 UTC (rev 1350) +++ trunk/18xx/test/test.properties 2010-07-19 20:52:17 UTC (rev 1351) @@ -17,7 +17,7 @@ # (implying a language variant of that country; no default). # Locale: concatenation of the above. If present, overrides any of the above. # Examples: en, en_US, en_UK, fr_FR, fr_CA. -locale=te_st0 +locale=te_st #language= #country= This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-07-25 22:45:40
|
Revision: 1360 http://rails.svn.sourceforge.net/rails/?rev=1360&view=rev Author: stefanfrey Date: 2010-07-25 22:45:34 +0000 (Sun, 25 Jul 2010) Log Message: ----------- Further update of configuration Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/data/Properties.xml trunk/18xx/default.profiles trunk/18xx/rails/ui/swing/ConfigWindow.java trunk/18xx/rails/util/Config.java trunk/18xx/rails/util/ConfigItem.java trunk/18xx/rails/util/LocalText.java Added Paths: ----------- trunk/18xx/data/profiles/ trunk/18xx/data/profiles/default.profile trunk/18xx/data/profiles/test.profile Removed Paths: ------------- trunk/18xx/test/test.properties Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-07-25 19:27:21 UTC (rev 1359) +++ trunk/18xx/LocalisedText.properties 2010-07-25 22:45:34 UTC (rev 1360) @@ -54,6 +54,7 @@ BuysTrainUsingSP={0} buys a {1}-train from {2} for {3} using {4}. BYFloatsAt=Bayern floats at CASH=Cash +CANCEL=Cancel CanOperate={0} can operate this round CannotOperate={0} cannot operate this round CannotBuyAnything={0} cannot buy anything @@ -64,7 +65,17 @@ CLOSE_WINDOW=Do you really want to exit the game? COMPANY=Company COMPANY_DETAILS=Company details -CONFIG_CURRENT_PROFILE=Active profile = {0} (based on = {1}) +CONFIG=Configuration +CONFIG_CURRENT_PROFILE=Active profile = {0} (based on = {1}) +CONFIG_DEFAULT_TITLE=Default profile +CONFIG_DEFAULT_MESSAGE=Select a template for settings +CONFIG_NEW_MESSAGE=Select a name of the new profile +CONFIG_NEW_TITLE=Create profile +CONFIG_SELECT_PROFILE=Select profile -> +CONFIG_SETTINGS=Profile settings +CONFIG_SAVE_MESSAGE=Active profile {0} was saved +CONFIG_SAVE_TITLE=Save confirmation +CONFIG_WINDOW_TITLE=Rails Configuration CORRECT_CASH=Cash Correction CORRECT_MAP=Map Correction CURRENT=Current @@ -440,6 +451,7 @@ RunsWithBorrowedTrain={0} runs with a borrowed {1}-train and must withhold revenue RustsTrains=Rusts {0}-trains SAVE=Save +SAVEAS=Save As ... SaveFailed=Save failed, reason: {0} Select=Select SelectCompanyToMergeMinorInto=Select major company to merge minor {0} into Modified: trunk/18xx/data/Properties.xml =================================================================== --- trunk/18xx/data/Properties.xml 2010-07-25 19:27:21 UTC (rev 1359) +++ trunk/18xx/data/Properties.xml 2010-07-25 22:45:34 UTC (rev 1360) @@ -4,13 +4,14 @@ --> <Properties> <Panel name="General"> - <Property name="locale" type="LIST" values="en_US,te_ST" helpText="Language Selection" /> + <Property name="locale" type="LIST" values="en_US,te_ST" toolTip="Language Selection" + initClass="rails.util.LocalText" initMethod="setLocale" initParameter="yes"/> </Panel> <Panel name="Save"> - <Property name="save.dir" type="DIRECTORY" helpText="Default save file directory" /> - + <Property name="save.directory" type="DIRECTORY" toolTip="Default save file directory" /> + <Property name="save.filename.date_time_pattern" type="STRING" toolTip="Datetime pattern for filename" /> </Panel> <Panel name="Colors"> - <Property name="route.colour.1" type="COLOR"/> + <Property name="route.colour.1" type="COLOR" toolTip="Route color of first train" /> </Panel> </Properties> \ No newline at end of file Added: trunk/18xx/data/profiles/default.profile =================================================================== --- trunk/18xx/data/profiles/default.profile (rev 0) +++ trunk/18xx/data/profiles/default.profile 2010-07-25 22:45:34 UTC (rev 1360) @@ -0,0 +1,7 @@ +locale=en_US +save.directory= +save.filename.date_time_pattern=yyyyMMdd_HHmm +save.filename.date_time_zone=UTC +save.filename.suffix=NEXT_PLAYER +save.filename.extension=rails + Copied: trunk/18xx/data/profiles/test.profile (from rev 1351, trunk/18xx/test/test.properties) =================================================================== --- trunk/18xx/data/profiles/test.profile (rev 0) +++ trunk/18xx/data/profiles/test.profile 2010-07-25 22:45:34 UTC (rev 1360) @@ -0,0 +1,124 @@ +####################### Test preferences ################################ +# +# Those are the settings used for automated testing +# +######################################################################## +# +# Preferred tile format. +# The only currently supported format is svg. Anything else is ignored. +#tile.format_preference=svg +# Root directory for the tile images (just above directory 'tiles'). +# Not required if tile images are provided included in the Rails jar file. +#tile.root_directory= + +### Locale #### +# Language: two-letter ISO code (lower case; default is en=English). +# Country: two-letter ISO code (upper case; specifies country +# (implying a language variant of that country; no default). +# Locale: concatenation of the above. If present, overrides any of the above. +# Examples: en, en_US, en_UK, fr_FR, fr_CA. +locale=te_st +#language= +#country= + +### Money display ### +# Each game has a specific format for monetary amounts (e.g. $100, 100M). +# An overriding format can be specified here, but then applies to all games. +# The @ character must be present and is replaced by the amount. +# Example: \xA3@ to specify a pound sign prefix: \xA3100. +#money_format=$@ + +### Save file directory +# If the below entry exists, is not empty, and specifies an existing +# directory, that directory is used as a starting point for any +# file choosing action for the Save and Load commands. +# The path may be relative or absolute. +save.directory=test/data +# The default Save filename is <gamename>_<datetimepattern>.<extension> +# This name will be initially proposed. +# As soon as that proposal has been changed once in a Save action, +# the last used name is always proposed in stead. +# The default date/time pattern is yyyyMMdd_HHmm +# The pattern codes are as defined in the Java class +# SimpleDateFormat (just Google that name to find the codes). +#save.filename.date_time_pattern=yyyyMMdd_HHmm +# The default timezone is local time. +# A specific timezone (such as UTC) can be set; the value must be a Java timezone ID +#save.filename.date_time_zone=UTC +# Optionally, a suffix (e.g. player name) can be added after the time stamp +# with a preceding underscore (which is automatically added) +# The special value NEXT_PLAYER puts the next moving player name into this spot. +#save.filename.suffix=NEXT_PLAYER +# The default extension is .rails +save.filename.extension=rails + +### Game report directory +# If the below entry exists, is not empty, and specifies an existing +# directory, a copy of the Game Report (as displayed in the Report Window) +# will be saved there. The path may be relative or absolute. +#report.directory=log +# The default file name includes the game name and the game start time: +# 18XX_yyyymmdd_hhmm.txt where 18XX is the game name. +# You can specify different values for the date/time part and teh extension here. +# The date/time pattern must be as defined in the Java SimpleDateFormat class. +#report.filename.date_time_pattern=yyyyMMdd +report.filename.extension=report + +### Windows +## Report window visibility +# By default the report window is hidden when starting or loading a game. +# This property allows to open it automatically. +# Valid values are yes and no (default). +#report.window.open=yes +## Report window editability +# Specify if the report window is editable, so you can add your own comments. +# Valid values are yes and no (default). +#report.window.editable=yes +## Stock Chart window visibility +# By default the stock chart hides at the end of an SR. +# By specifying "yes" here, the window will not be automatically hidden any more +#stockchart.window.open=yes + +### Player info +## Default players +# Comma-separated list of player names. +# Useful for game testing purposes. +#default_players=Alice,Bob,Charlie +# +## Local player name +# Useful for distributed usage (Internet, PBEM, cloud storage/dropbox) +# Required for "request turn" facility with cloud storage (dropbox) +#local.player.name=Alice + +### Default game +# Name of game selected in the game selection window. +# Useful for game testing purposes. +#default_game=1830 + +### Various options +# Show simple (ORx) or composite (ORx.x) OR number. +# Valid values: "simple" and "composite" (default) +#or.number_format=simple + +####################### Log4J properties ############################## +# For information on how to customise log4j logging, see for instance +# http://www.vipan.com/htdocs/log4jhelp.html +# It's a bit outdated: Category is now named Logger, +# and Priority is now named Level. +# But it's the best intro I know on how to configure Appenders. (EV) +####################################################################### +# Set root logger level to DEBUG and use appender F(file) +#log4j.debug=true +log4j.rootLogger=DEBUG, F + +# Define the Log file appender +log4j.appender.F=org.apache.log4j.FileAppender + +# Log file properties +log4j.appender.F.File=test/test.log +log4j.appender.F.append=false + +# Log file layout +log4j.appender.F.layout=org.apache.log4j.PatternLayout +log4j.appender.F.layout.ConversionPattern=%-5p %m%n +################## End of Log4J properties ############################# \ No newline at end of file Modified: trunk/18xx/default.profiles =================================================================== --- trunk/18xx/default.profiles 2010-07-25 19:27:21 UTC (rev 1359) +++ trunk/18xx/default.profiles 2010-07-25 22:45:34 UTC (rev 1360) @@ -1,2 +1,2 @@ -default=my.properties -test=test/test.properties +default=data/profiles/default.profile +.test=data/profiles/test.profile Modified: trunk/18xx/rails/ui/swing/ConfigWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-25 19:27:21 UTC (rev 1359) +++ trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-25 22:45:34 UTC (rev 1360) @@ -53,7 +53,7 @@ ConfigWindow() { // JFrame properties - setTitle(LocalText.getText("ConfigWindowTitle")); + setTitle(LocalText.getText("CONFIG_WINDOW_TITLE")); // setSize(400,300); // add profile panel @@ -96,7 +96,7 @@ Border titled = BorderFactory.createTitledBorder(etched, LocalText.getText("CONFIG_CURRENT_PROFILE", activeProfile, defaultProfile)); profilePanel.setBorder(titled); - JLabel userLabel = new JLabel(LocalText.getText("CONFIG_SELECT_USER")); + JLabel userLabel = new JLabel(LocalText.getText("CONFIG_SELECT_PROFILE")); profilePanel.add(userLabel); final JComboBox comboBoxUser = new JComboBox(Config.getUserProfiles().toArray()); comboBoxUser.setSelectedItem(Config.getActiveProfileName()); @@ -151,17 +151,17 @@ GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = 1; gbc.gridheight = 1; - gbc.gridx = 0; gbc.weightx = 0.8; gbc.weighty = 0.8; gbc.insets = new Insets(10,10,10,10); gbc.anchor = GridBagConstraints.WEST; + int y = 0; for (ConfigItem item:configPanels.get(panelName)) { gbc.gridx = 0; + gbc.gridy = y++; defineElement(newPanel, item, gbc); - gbc.gridy ++; } - configPane.addTab(panelName, newPanel); + configPane.addTab(LocalText.getText("Config.panel." + panelName), newPanel); } } @@ -175,7 +175,7 @@ // standard components final String configValue = item.getCurrentValue(); - final String toolTip = item.helpText; + final String toolTip = item.toolTip; // item label JLabel label = new JLabel(LocalText.getText("Config." + item.name)); @@ -329,8 +329,10 @@ if (Util.hasValue(newProfile)) { String defaultProfile = (String)JOptionPane.showInputDialog(ConfigWindow.this, LocalText.getText("CONFIG_DEFAULT_MESSAGE"), LocalText.getText("CONFIG_DEFAULT_TITLE"), JOptionPane.QUESTION_MESSAGE, null, - Config.getDefaultProfiles().toArray(), Config.getDefaultProfileSelection()); + Config.getDefaultProfiles(true).toArray(), Config.getDefaultProfileSelection()); + if (Util.hasValue(defaultProfile)) { Config.createUserProfile(newProfile, defaultProfile); + } } EventQueue.invokeLater(new Runnable() { public void run() { @@ -378,7 +380,7 @@ private void saveConfig() { Config.updateProfile(); // transfer the configitem to the active profile Config.saveActiveProfile(); - JOptionPane.showMessageDialog(ConfigWindow.this, LocalText.getText("CONFIG_SAVE_MESSAGE"), + JOptionPane.showMessageDialog(ConfigWindow.this, LocalText.getText("CONFIG_SAVE_MESSAGE", Config.getActiveProfileName()), LocalText.getText("CONFIG_SAVE_TITLE"), JOptionPane.INFORMATION_MESSAGE); } Modified: trunk/18xx/rails/util/Config.java =================================================================== --- trunk/18xx/rails/util/Config.java 2010-07-25 19:27:21 UTC (rev 1359) +++ trunk/18xx/rails/util/Config.java 2010-07-25 22:45:34 UTC (rev 1360) @@ -32,7 +32,6 @@ protected static Logger log; /** Commandline options */ - private static final String LOG4J_CMDLINE = "log4j"; private static final String CONFIGFILE_CMDLINE = "configfile"; private static final String PROFILE_CMDLINE = "profile"; @@ -52,7 +51,7 @@ private static String userProfilesFile = "user.profiles"; private static Properties userProfiles = new Properties(); private static boolean profilesLoaded = false; - private static final String TEST_PROFILE_SELECTION = "test"; + private static final String TEST_PROFILE_SELECTION = ".test"; private static final String DEFAULT_PROFILE_SELECTION = "default"; private static final String STANDARD_PROFILE_SELECTION = "user"; private static final String DEFAULTPROFILE_PROPERTY = "default.profile"; @@ -128,6 +127,7 @@ for (ConfigItem item:items) { if (!item.hasNewValue() || item.getNewValue().equals(defaultProperties.get(item.name))) continue; userProperties.setProperty(item.name, item.getNewValue()); + item.callInitMethod(); log.debug("Changed property name = " + item.name + " to value = " + item.getNewValue()); item.setNewValue(null); } @@ -210,9 +210,10 @@ } - private static Map<String, String> convertProperties(Properties properties) { + private static Map<String, String> convertProperties(Properties properties, boolean visibleOnly) { Map<String, String> converted = new HashMap<String, String>(); for (Object key:properties.keySet()) { + if (visibleOnly && ((String)key).substring(0,1).equals(".")) continue; converted.put((String) key, (String) properties.get(key)); } return converted; @@ -221,8 +222,8 @@ /** * get all default profiles */ - public static List<String> getDefaultProfiles() { - List<String> profiles = new ArrayList<String>(convertProperties(defaultProfiles).keySet()); + public static List<String> getDefaultProfiles(boolean visibleOnly) { + List<String> profiles = new ArrayList<String>(convertProperties(defaultProfiles, visibleOnly).keySet()); Collections.sort(profiles); return profiles; } @@ -235,7 +236,7 @@ * get all user profiles */ public static List<String> getUserProfiles() { - List<String> profiles = new ArrayList<String>(convertProperties(userProfiles).keySet()); + List<String> profiles = new ArrayList<String>(convertProperties(userProfiles, true).keySet()); Collections.sort(profiles); return profiles; } @@ -509,4 +510,5 @@ defaultProperties.put("save.directory", System.getProperty("user.dir")); } } + } Modified: trunk/18xx/rails/util/ConfigItem.java =================================================================== --- trunk/18xx/rails/util/ConfigItem.java 2010-07-25 19:27:21 UTC (rev 1359) +++ trunk/18xx/rails/util/ConfigItem.java 2010-07-25 22:45:34 UTC (rev 1360) @@ -1,5 +1,6 @@ package rails.util; +import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; @@ -29,8 +30,15 @@ public final ConfigType type; public final List<String> allowedValues; public final String formatMask; + public final String toolTip; public final String helpText; + // method call attributes + private final String initClass; + private final String initMethod; + private final boolean initParameter; + + // dynamic attributes private String newValue; @@ -67,9 +75,16 @@ // optional: formatMask formatMask = tag.getAttributeAsString("formatMask"); - // optional: helpText + // optional: helpText and toolTip + toolTip = tag.getAttributeAsString("toolTip"); helpText = tag.getAttributeAsString("helpText"); + + // optional: init method attributes + initClass = tag.getAttributeAsString("initClass"); + initMethod = tag.getAttributeAsString("initMethod"); + initParameter = tag.getAttributeAsBoolean("initParameter", false); + // initialize newValue newValue = null; } @@ -99,6 +114,25 @@ return Config.get(this.name); } + void callInitMethod() { + if (initClass == null || initMethod == null) return; + + // call without parameter + try { + Class<?> clazz = Class.forName(initClass); + + if (initParameter) { + clazz.getMethod(initMethod, String.class).invoke(null, newValue); + + } else { + clazz.getMethod(initMethod).invoke(null); + } + } catch (Exception e) { + log.error("Config profile: cannot call initMethod"); + } + } + + public String toString() { StringBuffer s = new StringBuffer(); s.append("Configuration Item: name = " + name + ", type = " + type); Modified: trunk/18xx/rails/util/LocalText.java =================================================================== --- trunk/18xx/rails/util/LocalText.java 2010-07-25 19:27:21 UTC (rev 1359) +++ trunk/18xx/rails/util/LocalText.java 2010-07-25 22:45:34 UTC (rev 1360) @@ -117,7 +117,9 @@ String[] codes = localeCode.split("_"); if (codes.length > 0) language = codes[0]; if (codes.length > 1) country = codes[1]; - + + // reset localised text + localisedText = null; } public Enumeration<String> getKeys() { Deleted: trunk/18xx/test/test.properties =================================================================== --- trunk/18xx/test/test.properties 2010-07-25 19:27:21 UTC (rev 1359) +++ trunk/18xx/test/test.properties 2010-07-25 22:45:34 UTC (rev 1360) @@ -1,124 +0,0 @@ -####################### Test preferences ################################ -# -# Those are the settings used for automated testing -# -######################################################################## -# -# Preferred tile format. -# The only currently supported format is svg. Anything else is ignored. -#tile.format_preference=svg -# Root directory for the tile images (just above directory 'tiles'). -# Not required if tile images are provided included in the Rails jar file. -#tile.root_directory= - -### Locale #### -# Language: two-letter ISO code (lower case; default is en=English). -# Country: two-letter ISO code (upper case; specifies country -# (implying a language variant of that country; no default). -# Locale: concatenation of the above. If present, overrides any of the above. -# Examples: en, en_US, en_UK, fr_FR, fr_CA. -locale=te_st -#language= -#country= - -### Money display ### -# Each game has a specific format for monetary amounts (e.g. $100, 100M). -# An overriding format can be specified here, but then applies to all games. -# The @ character must be present and is replaced by the amount. -# Example: \xA3@ to specify a pound sign prefix: \xA3100. -#money_format=$@ - -### Save file directory -# If the below entry exists, is not empty, and specifies an existing -# directory, that directory is used as a starting point for any -# file choosing action for the Save and Load commands. -# The path may be relative or absolute. -save.directory=test/data -# The default Save filename is <gamename>_<datetimepattern>.<extension> -# This name will be initially proposed. -# As soon as that proposal has been changed once in a Save action, -# the last used name is always proposed in stead. -# The default date/time pattern is yyyyMMdd_HHmm -# The pattern codes are as defined in the Java class -# SimpleDateFormat (just Google that name to find the codes). -#save.filename.date_time_pattern=yyyyMMdd_HHmm -# The default timezone is local time. -# A specific timezone (such as UTC) can be set; the value must be a Java timezone ID -#save.filename.date_time_zone=UTC -# Optionally, a suffix (e.g. player name) can be added after the time stamp -# with a preceding underscore (which is automatically added) -# The special value NEXT_PLAYER puts the next moving player name into this spot. -#save.filename.suffix=NEXT_PLAYER -# The default extension is .rails -save.filename.extension=rails - -### Game report directory -# If the below entry exists, is not empty, and specifies an existing -# directory, a copy of the Game Report (as displayed in the Report Window) -# will be saved there. The path may be relative or absolute. -#report.directory=log -# The default file name includes the game name and the game start time: -# 18XX_yyyymmdd_hhmm.txt where 18XX is the game name. -# You can specify different values for the date/time part and teh extension here. -# The date/time pattern must be as defined in the Java SimpleDateFormat class. -#report.filename.date_time_pattern=yyyyMMdd -report.filename.extension=report - -### Windows -## Report window visibility -# By default the report window is hidden when starting or loading a game. -# This property allows to open it automatically. -# Valid values are yes and no (default). -#report.window.open=yes -## Report window editability -# Specify if the report window is editable, so you can add your own comments. -# Valid values are yes and no (default). -#report.window.editable=yes -## Stock Chart window visibility -# By default the stock chart hides at the end of an SR. -# By specifying "yes" here, the window will not be automatically hidden any more -#stockchart.window.open=yes - -### Player info -## Default players -# Comma-separated list of player names. -# Useful for game testing purposes. -#default_players=Alice,Bob,Charlie -# -## Local player name -# Useful for distributed usage (Internet, PBEM, cloud storage/dropbox) -# Required for "request turn" facility with cloud storage (dropbox) -#local.player.name=Alice - -### Default game -# Name of game selected in the game selection window. -# Useful for game testing purposes. -#default_game=1830 - -### Various options -# Show simple (ORx) or composite (ORx.x) OR number. -# Valid values: "simple" and "composite" (default) -#or.number_format=simple - -####################### Log4J properties ############################## -# For information on how to customise log4j logging, see for instance -# http://www.vipan.com/htdocs/log4jhelp.html -# It's a bit outdated: Category is now named Logger, -# and Priority is now named Level. -# But it's the best intro I know on how to configure Appenders. (EV) -####################################################################### -# Set root logger level to DEBUG and use appender F(file) -#log4j.debug=true -log4j.rootLogger=DEBUG, F - -# Define the Log file appender -log4j.appender.F=org.apache.log4j.FileAppender - -# Log file properties -log4j.appender.F.File=test/test.log -log4j.appender.F.append=false - -# Log file layout -log4j.appender.F.layout=org.apache.log4j.PatternLayout -log4j.appender.F.layout.ConversionPattern=%-5p %m%n -################## End of Log4J properties ############################# \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-07-29 23:33:31
|
Revision: 1361 http://rails.svn.sourceforge.net/rails/?rev=1361&view=rev Author: stefanfrey Date: 2010-07-29 23:33:24 +0000 (Thu, 29 Jul 2010) Log Message: ----------- Update configuration mechanism Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/data/Properties.xml trunk/18xx/data/profiles/default.profile trunk/18xx/rails/ui/swing/ConfigWindow.java trunk/18xx/rails/ui/swing/hexmap/HexMap.java trunk/18xx/rails/util/Config.java trunk/18xx/rails/util/ConfigItem.java trunk/18xx/rails/util/LocalText.java trunk/18xx/rails/util/Util.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-07-25 22:45:34 UTC (rev 1360) +++ trunk/18xx/LocalisedText.properties 2010-07-29 23:33:24 UTC (rev 1361) @@ -7,6 +7,7 @@ ALL=All ALL_PASSED=All players have passed. ALSO_GETS={0} also gets {1} +APPLY=Apply AT_PRICE=at {0} AcceptingConfigFailure=Temporarily accepting configuration failure AcquiresBonus={0} acquires a {1} +{2} bonus on hex(es) {3} Modified: trunk/18xx/data/Properties.xml =================================================================== --- trunk/18xx/data/Properties.xml 2010-07-25 22:45:34 UTC (rev 1360) +++ trunk/18xx/data/Properties.xml 2010-07-29 23:33:24 UTC (rev 1361) @@ -1,17 +1,51 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Supported properties -Defines rails configuration options, but do not stores the actual values - --> +<!-- Supported properties Defines rails configuration options, but do not + stores the actual values --> <Properties> <Panel name="General"> - <Property name="locale" type="LIST" values="en_US,te_ST" toolTip="Language Selection" - initClass="rails.util.LocalText" initMethod="setLocale" initParameter="yes"/> + <Property name="locale" type="LIST" values="en_US,te_ST" + initClass="rails.util.LocalText" initMethod="setLocale" + initParameter="yes" /> + <Property name="default_game" type="STRING" /> + <Property name="default_players" type="STRING" /> + <Property name="local.player.name" type="STRING" /> + </Panel> <Panel name="Save"> - <Property name="save.directory" type="DIRECTORY" toolTip="Default save file directory" /> - <Property name="save.filename.date_time_pattern" type="STRING" toolTip="Datetime pattern for filename" /> + <Property name="save.directory" type="DIRECTORY" /> + <Property name="save.filename.date_time_pattern" type="STRING" /> + <Property name="save.filename.suffix" type="STRING" /> + <Property name="save.filename.extension" type="STRING" /> + <Property name="save.recovery.active" type="BOOLEAN" /> + <Property name="save.recovery.filepath" type="FILE" /> </Panel> - <Panel name="Colors"> - <Property name="route.colour.1" type="COLOR" toolTip="Route color of first train" /> + <Panel name="UI"> + <Property name="report.window.open" type="BOOLEAN" /> + <Property name="report.window.editable" type="BOOLEAN" /> + <Property name="stockchart.window.open" type="BOOLEAN" /> + <Property name="font.ui.scale" type="PERCENT" /> + <Property name="font.ui.name" type="FONT" /> + <Property name="font.ui.style" type="LIST" values="plain,bold" /> </Panel> + <Panel name="Map"> + <Property name="map.autoscroll" type="BOOLEAN" /> + <Property name="map.zoomstep" type="INTEGER" /> + </Panel> + <Panel name="Format"> + <Property name="money_format" type="STRING" /> + <Property name="or.number_format" type="LIST" values="simple,composite" /> + <Property name="route.colour.1" type="COLOR" + initClass="rails.ui.swing.hexmap.HexMap" initMethod="setRouteColours" /> + <Property name="route.colour.2" type="COLOR" + initClass="rails.ui.swing.hexmap.HexMap" initMethod="setRouteColours" /> + <Property name="route.colour.3" type="COLOR" + initClass="rails.ui.swing.hexmap.HexMap" initMethod="setRouteColours" /> + <Property name="route.colour.4" type="COLOR" + initClass="rails.ui.swing.hexmap.HexMap" initMethod="setRouteColours" /> + </Panel> + <Panel name="Log"> + <Property name="report.directory" type="DIRECTORY" /> + <Property name="report.filename.date_time_pattern" type="STRING" /> + <Property name="report.filename.extension" type="STRING" /> + </Panel> </Properties> \ No newline at end of file Modified: trunk/18xx/data/profiles/default.profile =================================================================== --- trunk/18xx/data/profiles/default.profile 2010-07-25 22:45:34 UTC (rev 1360) +++ trunk/18xx/data/profiles/default.profile 2010-07-29 23:33:24 UTC (rev 1361) @@ -1,7 +1,39 @@ +### Panel General locale=en_US +default_game=1830 +default_players= +local.player.names= + +### Panel Save save.directory= save.filename.date_time_pattern=yyyyMMdd_HHmm save.filename.date_time_zone=UTC save.filename.suffix=NEXT_PLAYER save.filename.extension=rails +save.recovery.active=no +save.recovery.filepath=18xx_autosave.rails +### Panel UI +report.window.open=yes +report.window.editable=no +stockchart.window.open=yes +font.ui.scale=1 +font.ui.name= +font.ui.style=bold + +### Panel Map +map.autoscroll=yes +map.zoomstep=10 + +### Panel Format +money_format= +or.number_format=composite +route.colour.1=00ffff +route.colour.2=ffc0cb +route.colour.3=ffa500 +route.colour.4=808080 + +### Panel Log +#report.directory=log +#report.filename.date_time_pattern=yyyyMMdd +#report.filename.extension=log Modified: trunk/18xx/rails/ui/swing/ConfigWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-25 22:45:34 UTC (rev 1360) +++ trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-29 23:33:24 UTC (rev 1361) @@ -2,6 +2,8 @@ import java.awt.Color; import java.awt.EventQueue; +import java.awt.Font; +import java.awt.GraphicsEnvironment; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; @@ -24,14 +26,18 @@ import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; +import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JSpinner; import javax.swing.JTabbedPane; +import javax.swing.SpinnerNumberModel; import javax.swing.SwingConstants; +import javax.swing.UIManager; import javax.swing.WindowConstants; import javax.swing.border.Border; @@ -73,7 +79,7 @@ addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - cancelConfig(); + closeConfig(); } }); } @@ -136,6 +142,8 @@ } + + private void setupConfigPane() { configPane.removeAll(); @@ -144,7 +152,8 @@ configPane.setBorder(titled); Map<String, List<ConfigItem>> configPanels = Config.getConfigPanels(); - + int maxElements = Config.getMaxElementsInPanels(); + for (String panelName:configPanels.keySet()) { JPanel newPanel = new JPanel(); newPanel.setLayout(new GridBagLayout()); @@ -153,14 +162,19 @@ gbc.gridheight = 1; gbc.weightx = 0.8; gbc.weighty = 0.8; - gbc.insets = new Insets(10,10,10,10); + gbc.insets = new Insets(5,5,5,5); gbc.anchor = GridBagConstraints.WEST; - int y = 0; for (ConfigItem item:configPanels.get(panelName)) { gbc.gridx = 0; - gbc.gridy = y++; + gbc.gridy++; defineElement(newPanel, item, gbc); } + // fill up to maxElements + gbc.gridx = 0; + for (gbc.gridy++; gbc.gridy < maxElements; gbc.gridy++) { + JLabel emptyLabel = new JLabel(""); + newPanel.add(emptyLabel, gbc); + } configPane.addTab(LocalText.getText("Config.panel." + panelName), newPanel); } } @@ -171,23 +185,94 @@ gbc.gridx ++; } + private void addEmptyLabel(JComponent container, GridBagConstraints gbc) { + JLabel label = new JLabel(""); + addToGridBag(container, label, gbc ); + } + private void defineElement(JPanel panel, final ConfigItem item, GridBagConstraints gbc) { // standard components - final String configValue = item.getCurrentValue(); - final String toolTip = item.toolTip; + String configValue = item.getCurrentValue(); +// final String toolTip = item.toolTip; // item label JLabel label = new JLabel(LocalText.getText("Config." + item.name)); - label.setToolTipText(toolTip); +// label.setToolTipText(toolTip); gbc.fill = GridBagConstraints.NONE; addToGridBag(panel, label, gbc); switch (item.type) { + case BOOLEAN: + final JCheckBox checkBox = new JCheckBox(); + boolean selected = Util.parseBoolean(configValue); + checkBox.setSelected(selected); + checkBox.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent arg0) { + // do nothing + } + public void focusLost(FocusEvent arg0) { + if (checkBox.isSelected()) { + item.setNewValue("yes"); + } else { + item.setNewValue("no"); + } + } + } + ); + gbc.fill = GridBagConstraints.HORIZONTAL; + addToGridBag(panel, checkBox, gbc); + break; + case PERCENT: // percent uses a spinner with 5 changes + case INTEGER: + int spinnerStepSize; + final int spinnerMultiple; + if (item.type == ConfigItem.ConfigType.PERCENT) { + spinnerStepSize = 5; + spinnerMultiple = 100; + } else { + spinnerStepSize = 1; + spinnerMultiple = 1; + } + int spinnerValue; + try { + spinnerValue = (int)Math.round(Double.parseDouble(configValue) * spinnerMultiple); + } catch (NumberFormatException e) { + spinnerValue = 0; + } + final JSpinner spinner = new JSpinner(new SpinnerNumberModel + (spinnerValue, Integer.MIN_VALUE, Integer.MAX_VALUE, spinnerStepSize)); + ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField(). + addFocusListener(new FocusListener() { + public void focusGained(FocusEvent arg0) { + // do nothing + } + public void focusLost(FocusEvent arg0) { + int value = (Integer)spinner.getValue(); + Double adjValue = (double)value / spinnerMultiple; + item.setNewValue(adjValue.toString()); + } + } + ); + gbc.fill = GridBagConstraints.HORIZONTAL; + addToGridBag(panel, spinner, gbc); + addEmptyLabel(panel, gbc); + break; + case FONT: // fonts are a special list + if (!Util.hasValue(configValue)) { + configValue = ((Font)UIManager.getDefaults().get("Label.font")).getFamily(); + } case LIST: - final JComboBox comboBox = new JComboBox(item.allowedValues.toArray()); + String[] allowedValues; + if (item.type == ConfigItem.ConfigType.FONT) { + allowedValues = GraphicsEnvironment.getLocalGraphicsEnvironment(). + getAvailableFontFamilyNames(); + } else { + allowedValues = (String[])item.allowedValues.toArray(); + } + final JComboBox comboBox = new JComboBox(allowedValues); comboBox.setSelectedItem(configValue); - comboBox.setToolTipText(toolTip); +// comboBox.setToolTipText(toolTip)); comboBox.addFocusListener(new FocusListener() { public void focusGained(FocusEvent arg0) { // do nothing @@ -199,11 +284,13 @@ ); gbc.fill = GridBagConstraints.HORIZONTAL; addToGridBag(panel, comboBox, gbc); + addEmptyLabel(panel, gbc); break; case DIRECTORY: + case FILE: final JLabel dirLabel = new JLabel(configValue); dirLabel.setHorizontalAlignment(SwingConstants.CENTER); - dirLabel.setToolTipText(toolTip); +// dirLabel.setToolTipText(toolTip); gbc.fill = GridBagConstraints.HORIZONTAL; addToGridBag(panel, dirLabel, gbc); JButton dirButton = new JButton("Choose..."); @@ -211,7 +298,11 @@ new ActionListener() { public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(dirLabel.getText()); - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + if (item.type == ConfigItem.ConfigType.DIRECTORY) { + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + } else { + fc.setFileSelectionMode(JFileChooser.FILES_ONLY); + } int state = fc.showOpenDialog(ConfigWindow.this); if ( state == JFileChooser.APPROVE_OPTION ){ File file = fc.getSelectedFile(); @@ -240,7 +331,7 @@ } else { colorLabel.setForeground(Color.BLACK); } - colorLabel.setToolTipText(toolTip); +// colorLabel.setToolTipText(toolTip); gbc.fill = GridBagConstraints.HORIZONTAL; addToGridBag(panel, colorLabel, gbc); JButton colorButton = new JButton("Choose..."); @@ -249,7 +340,7 @@ public void actionPerformed(ActionEvent e) { Color selectedColor=JColorChooser.showDialog(ConfigWindow.this, "", colorLabel.getBackground()); if (selectedColor == null) return; - String newValue = Integer.toHexString(selectedColor.getRGB()).substring(3); + String newValue = Integer.toHexString(selectedColor.getRGB()).substring(2); colorLabel.setText(newValue); item.setNewValue(newValue); colorLabel.setBackground(selectedColor); @@ -279,6 +370,7 @@ ); gbc.fill = GridBagConstraints.HORIZONTAL; addToGridBag(panel, textField, gbc); + addEmptyLabel(panel, gbc); break; } } @@ -310,12 +402,22 @@ buttonPanel.add(saveButton); } + JButton applyButton = new JButton(LocalText.getText("APPLY")); + applyButton.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + ConfigWindow.this.applyConfig(); + } + } + ); + buttonPanel.add(applyButton); + JButton cancelButton = new JButton(LocalText.getText("CANCEL")); cancelButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent arg0) { - ConfigWindow.this.cancelConfig(); + ConfigWindow.this.closeConfig(); } } ); @@ -420,8 +522,13 @@ }); } } - - private void cancelConfig() { + + private void applyConfig() { + Config.updateProfile(); // transfer the configitem to the active profile + } + + private void closeConfig() { + Config.revertProfile(); StatusWindow.uncheckMenuItemBox(StatusWindow.CONFIG_CMD); this.setVisible(false); } Modified: trunk/18xx/rails/ui/swing/hexmap/HexMap.java =================================================================== --- trunk/18xx/rails/ui/swing/hexmap/HexMap.java 2010-07-25 22:45:34 UTC (rev 1360) +++ trunk/18xx/rails/ui/swing/hexmap/HexMap.java 2010-07-29 23:33:24 UTC (rev 1361) @@ -69,7 +69,6 @@ protected List<GeneralPath> trainPaths; private static Color colour1, colour2, colour3, colour4; - protected Color[] trainColors = new Color[4]; protected int strokeWidth = 5; protected int strokeCap = BasicStroke.CAP_ROUND; protected int strokeJoin = BasicStroke.JOIN_BEVEL; @@ -85,7 +84,7 @@ protected double coordinateXMargin; protected double coordinateYMargin; - static { + public static void setRouteColours () { try { colour1 = Util.parseColour(Config.get("route.colour.1", null)); colour2 = Util.parseColour(Config.get("route.colour.2", null)); @@ -99,7 +98,7 @@ if (colour4 == null) colour4 = Color.GRAY; } } - + public void init(ORUIManager orUIManager, MapManager mapManager) { this.orUIManager = orUIManager; @@ -120,14 +119,15 @@ setupHexes(); initializeSettings(); + + setRouteColours(); } /** * defines settings from the config files */ private void initializeSettings() { - trainColors = new Color[]{colour1, colour2, colour3, colour4}; - + // define zoomStep from config String zoomStepSetting = Config.getGameSpecific("map.zoomstep"); if (Util.hasValue(zoomStepSetting)) { @@ -143,6 +143,9 @@ } } + + + protected void setupHexesGUI() { hexes = new ArrayList<GUIHex>(); @@ -296,6 +299,8 @@ Stroke trainStroke = new BasicStroke((int)(strokeWidth * zoomFactor), strokeCap, strokeJoin); g2.setStroke(trainStroke); + + Color[] trainColors = new Color[]{colour1, colour2, colour3, colour4}; int color = 0; for (GeneralPath path:trainPaths) { g2.setColor(trainColors[color++ % trainColors.length]); Modified: trunk/18xx/rails/util/Config.java =================================================================== --- trunk/18xx/rails/util/Config.java 2010-07-25 22:45:34 UTC (rev 1360) +++ trunk/18xx/rails/util/Config.java 2010-07-29 23:33:24 UTC (rev 1361) @@ -107,7 +107,7 @@ } } catch (ConfigurationException e) { - log.error("Configuration error in setup of "); + log.error("Configuration error in setup of " + CONFIG_XML_FILE + ", exception = " + e); } } @@ -119,6 +119,15 @@ return configPanels; } + public static int getMaxElementsInPanels() { + int maxElements = 0; + for (List<ConfigItem> panel:configPanels.values()) { + maxElements = Math.max(maxElements, panel.size()); + } + log.debug("maxelements" + maxElements); + return maxElements; + } + /** * updates the profile according to the changes in configitems */ @@ -135,6 +144,17 @@ } /** + * reverts all changes in configitems + */ + public static void revertProfile() { + for (List<ConfigItem> items:configPanels.values()) { + for (ConfigItem item:items) { + item.setNewValue(null); + } + } + } + + /** * First tries to return {key}.{gameName}, if undefined returns {key} */ public static String getGameSpecific(String key) { Modified: trunk/18xx/rails/util/ConfigItem.java =================================================================== --- trunk/18xx/rails/util/ConfigItem.java 2010-07-25 22:45:34 UTC (rev 1360) +++ trunk/18xx/rails/util/ConfigItem.java 2010-07-29 23:33:24 UTC (rev 1361) @@ -1,6 +1,5 @@ package rails.util; -import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; @@ -22,7 +21,7 @@ * Defines possible types (Java classes used as types in ConfigItem below */ public static enum ConfigType { - INTEGER, FLOAT, STRING, BOOLEAN, LIST, DIRECTORY, COLOR; + BOOLEAN, INTEGER, PERCENT, STRING, LIST, FONT, DIRECTORY, FILE, COLOR; } // static attributes @@ -30,8 +29,6 @@ public final ConfigType type; public final List<String> allowedValues; public final String formatMask; - public final String toolTip; - public final String helpText; // method call attributes private final String initClass; @@ -62,7 +59,7 @@ try { this.type = ConfigType.valueOf(type.toUpperCase()); } catch (Exception e) { - throw new ConfigurationException("Missing or invalid type for configuration item"); + throw new ConfigurationException("Missing or invalid type for configuration item, exception = " + e); } } else { throw new ConfigurationException("Missing or invalid type for configuration item"); @@ -74,10 +71,6 @@ // optional: formatMask formatMask = tag.getAttributeAsString("formatMask"); - - // optional: helpText and toolTip - toolTip = tag.getAttributeAsString("toolTip"); - helpText = tag.getAttributeAsString("helpText"); // optional: init method attributes initClass = tag.getAttributeAsString("initClass"); @@ -144,9 +137,6 @@ if (formatMask != null) { s.append(", formatMask = " + formatMask); } - if (helpText != null) { - s.append(", helpText = " + helpText); - } return s.toString(); } Modified: trunk/18xx/rails/util/LocalText.java =================================================================== --- trunk/18xx/rails/util/LocalText.java 2010-07-25 22:45:34 UTC (rev 1360) +++ trunk/18xx/rails/util/LocalText.java 2010-07-29 23:33:24 UTC (rev 1361) @@ -32,7 +32,6 @@ return getText(key, new Object[] { parameter }); } - //public static String getText(String key, Object[] parameters) { public static String getText(String key, Object... parameters) { String result = ""; Modified: trunk/18xx/rails/util/Util.java =================================================================== --- trunk/18xx/rails/util/Util.java 2010-07-25 22:45:34 UTC (rev 1360) +++ trunk/18xx/rails/util/Util.java 2010-07-29 23:33:24 UTC (rev 1361) @@ -126,6 +126,18 @@ } /** + * Parse a boolean value for Rails + * @param value string (allowed values for true: standard Boolean.parseBoolean and yes (after conversion to lowercase) + * @return parsed value + */ + public static boolean parseBoolean(String s) { + if (s.toLowerCase().equals("yes")) { + return true; + } + return Boolean.parseBoolean(s); + } + + /** * Parse a colour definition string. * Currently supported formats: * "RRGGBB" - each character being a hexadecimal digit @@ -159,6 +171,9 @@ return c; } + + + /** * Is a colour dark? (to check if FG colour needs be reversed) */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-07-30 10:20:48
|
Revision: 1362 http://rails.svn.sourceforge.net/rails/?rev=1362&view=rev Author: stefanfrey Date: 2010-07-30 10:20:42 +0000 (Fri, 30 Jul 2010) Log Message: ----------- Fix some problems with config Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/rails/ui/swing/ConfigWindow.java trunk/18xx/rails/util/Config.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-07-29 23:33:24 UTC (rev 1361) +++ trunk/18xx/LocalisedText.properties 2010-07-30 10:20:42 UTC (rev 1362) @@ -67,6 +67,8 @@ COMPANY=Company COMPANY_DETAILS=Company details CONFIG=Configuration +CONFIG_APPLY_MESSAGE=Current changes (will be) applied +CONFIG_APPLY_TITLE=Apply confirmation CONFIG_CURRENT_PROFILE=Active profile = {0} (based on = {1}) CONFIG_DEFAULT_TITLE=Default profile CONFIG_DEFAULT_MESSAGE=Select a template for settings Modified: trunk/18xx/rails/ui/swing/ConfigWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-29 23:33:24 UTC (rev 1361) +++ trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-30 10:20:42 UTC (rev 1362) @@ -248,9 +248,14 @@ // do nothing } public void focusLost(FocusEvent arg0) { - int value = (Integer)spinner.getValue(); - Double adjValue = (double)value / spinnerMultiple; - item.setNewValue(adjValue.toString()); + Integer value = (Integer)spinner.getValue(); + if (item.type == ConfigItem.ConfigType.PERCENT) { + Double adjValue = (double)value / spinnerMultiple; + item.setNewValue(adjValue.toString()); + } else { + item.setNewValue(value.toString()); + } + } } ); @@ -525,6 +530,8 @@ private void applyConfig() { Config.updateProfile(); // transfer the configitem to the active profile + JOptionPane.showMessageDialog(ConfigWindow.this, LocalText.getText("CONFIG_APPLY_MESSAGE"), + LocalText.getText("CONFIG_APPLY_TITLE"), JOptionPane.INFORMATION_MESSAGE); } private void closeConfig() { Modified: trunk/18xx/rails/util/Config.java =================================================================== --- trunk/18xx/rails/util/Config.java 2010-07-29 23:33:24 UTC (rev 1361) +++ trunk/18xx/rails/util/Config.java 2010-07-30 10:20:42 UTC (rev 1362) @@ -134,7 +134,11 @@ public static void updateProfile() { for (List<ConfigItem> items:configPanels.values()) { for (ConfigItem item:items) { - if (!item.hasNewValue() || item.getNewValue().equals(defaultProperties.get(item.name))) continue; + if (!item.hasNewValue()) continue; + if (item.getNewValue().equals(defaultProperties.get(item.name))) { + userProperties.remove(item.name); + continue; + } userProperties.setProperty(item.name, item.getNewValue()); item.callInitMethod(); log.debug("Changed property name = " + item.name + " to value = " + item.getNewValue()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ev...@us...> - 2010-07-30 20:59:14
|
Revision: 1363 http://rails.svn.sourceforge.net/rails/?rev=1363&view=rev Author: evos Date: 2010-07-30 20:59:08 +0000 (Fri, 30 Jul 2010) Log Message: ----------- New option to enable selling stock of one company in one turn in separate actions at decreasing prices. Only for 1830 at this stage. Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/data/1830/Game.xml trunk/18xx/data/GamesList.xml trunk/18xx/rails/game/ShareSellingRound.java trunk/18xx/rails/game/StockRound.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-07-30 10:20:42 UTC (rev 1362) +++ trunk/18xx/LocalisedText.properties 2010-07-30 20:59:08 UTC (rev 1363) @@ -472,6 +472,7 @@ SELL_SHARES_LOG={0} sells {1} {2}% shares ({3}%) of {4} to Pool for {5}. SellHowManyShares=Sell how many shares? SellShares=Sell {0} {1}% share(s) ({2}%) of {3} for {4} +SeparateSalesAtSamePrice=Allow separate sales at same price SET_REVENUE=Set Revenue SET_SCALE=Set Scale SharesPutInTreasury=The remaining {0}% shares of {1} are put in its treasury Modified: trunk/18xx/data/1830/Game.xml =================================================================== --- trunk/18xx/data/1830/Game.xml 2010-07-30 10:20:42 UTC (rev 1362) +++ trunk/18xx/data/1830/Game.xml 2010-07-30 20:59:08 UTC (rev 1363) @@ -25,6 +25,7 @@ <GameOption name="UnlimitedTiles" type="toggle" default="no"/> <GameOption name="LeaveAuctionOnPass" type="toggle" default="no"/> <GameOption name="TwoPlayersCertLimit70Percent" type="toggle" default="yes"/> + <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <GameParameters> <PlayerShareLimit percentage="60"> <!-- Option "NumberOfPlayers" is automatically set Modified: trunk/18xx/data/GamesList.xml =================================================================== --- trunk/18xx/data/GamesList.xml 2010-07-30 10:20:42 UTC (rev 1362) +++ trunk/18xx/data/GamesList.xml 2010-07-30 20:59:08 UTC (rev 1363) @@ -30,6 +30,7 @@ <Option name="UnlimitedTiles" type="toggle" default="no"/> <Option name="LeaveAuctionOnPass" type="toggle" default="no"/> <Option name="TwoPlayersCertLimit70Percent" type="toggle" default="no"/> + <Option name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <Players minimum="2" maximum="6"/> </Game> Modified: trunk/18xx/rails/game/ShareSellingRound.java =================================================================== --- trunk/18xx/rails/game/ShareSellingRound.java 2010-07-30 10:20:42 UTC (rev 1362) +++ trunk/18xx/rails/game/ShareSellingRound.java 2010-07-30 20:59:08 UTC (rev 1363) @@ -22,7 +22,7 @@ Player sellingPlayer; IntegerState cashToRaise; PublicCompanyI unsellableCompany = null; - + private List<SellShares> sellableShares; /** @@ -86,15 +86,15 @@ public void setSellableShares() { possibleActions.addAll(sellableShares); } - + /** - * Create a list of certificates that a player may sell in an emergency + * Create a list of certificates that a player may sell in an emergency * share selling round, taking all rules taken into account. */ private List<SellShares> getSellableShares () { - + sellableShares = new ArrayList<SellShares> (); - + String compName; int price; int number; @@ -318,7 +318,8 @@ int price; // Get the sell price (does not change within a turn) - if (sellPrices.containsKey(companyName)) { + if (sellPrices.containsKey(companyName) + && GameOption.convertValueToBoolean(getGameOption("SeparateSalesAtSamePrice"))) { price = (sellPrices.get(companyName)).getPrice(); } else { sellPrice = company.getCurrentSpace(); Modified: trunk/18xx/rails/game/StockRound.java =================================================================== --- trunk/18xx/rails/game/StockRound.java 2010-07-30 10:20:42 UTC (rev 1362) +++ trunk/18xx/rails/game/StockRound.java 2010-07-30 20:59:08 UTC (rev 1363) @@ -412,7 +412,8 @@ * Check the price. If a cert was sold before this turn, the * original price is still valid */ - if (sellPrices.containsKey(compName)) { + if (sellPrices.containsKey(compName) + && GameOption.convertValueToBoolean(getGameOption("SeparateSalesAtSamePrice"))) { price = (sellPrices.get(compName)).getPrice(); } else { price = company.getMarketPrice(); @@ -1039,7 +1040,8 @@ boolean soldBefore = sellPrices.containsKey(companyName); // Get the sell price (does not change within a turn) - if (soldBefore) { + if (soldBefore + && GameOption.convertValueToBoolean(getGameOption("SeparateSalesAtSamePrice"))) { price = (sellPrices.get(companyName)).getPrice(); } else { sellPrice = company.getCurrentSpace(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-01 11:46:32
|
Revision: 1364 http://rails.svn.sourceforge.net/rails/?rev=1364&view=rev Author: stefanfrey Date: 2010-08-01 11:46:26 +0000 (Sun, 01 Aug 2010) Log Message: ----------- Updated and improved configuration settings Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/data/Properties.xml trunk/18xx/rails/ui/swing/ConfigWindow.java trunk/18xx/rails/ui/swing/StartRoundWindow.java trunk/18xx/rails/util/Config.java trunk/18xx/rails/util/LocalText.java Added Paths: ----------- trunk/18xx/rails/ui/swing/elements/RailsIcon.java Property Changed: ---------------- trunk/18xx/ Property changes on: trunk/18xx ___________________________________________________________________ Modified: svn:ignore - *.bat *.txt .cvsignore .classpath .externalToolBuilders 18xx.zip deploy.xml .project zip.xml NewUIstuff.zip COMP.WPS rails.jar rails.jardesc Rails-1.0.1.jar my_my.properties log rails-1.0.1.jar rails*.zip rails-*.jar tools rails-?.*.* jar/* classes/* 18xx_autosave.rails 18xx_autosave.rails.tmp + *.bat *.txt .cvsignore .classpath .externalToolBuilders 18xx.zip deploy.xml .project zip.xml NewUIstuff.zip COMP.WPS rails.jar rails.jardesc Rails-1.0.1.jar my_my.properties log rails-1.0.1.jar rails*.zip rails-*.jar tools rails-?.*.* jar/* classes/* 18xx_autosave.rails 18xx_autosave.rails.tmp user.profiles Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-07-30 20:59:08 UTC (rev 1363) +++ trunk/18xx/LocalisedText.properties 2010-08-01 11:46:26 UTC (rev 1364) @@ -67,18 +67,19 @@ COMPANY=Company COMPANY_DETAILS=Company details CONFIG=Configuration -CONFIG_APPLY_MESSAGE=Current changes (will be) applied +CONFIG_APPLY_MESSAGE=<html>Current changes (will be) applied.<br>Be aware that some changes to be active require <br> UI redraws or a restart of Rails.</html> CONFIG_APPLY_TITLE=Apply confirmation CONFIG_CURRENT_PROFILE=Active profile = {0} (based on = {1}) CONFIG_DEFAULT_TITLE=Default profile CONFIG_DEFAULT_MESSAGE=Select a template for settings +CONFIG_INFO_TITLE=Info text for {0} CONFIG_NEW_MESSAGE=Select a name of the new profile CONFIG_NEW_TITLE=Create profile CONFIG_SELECT_PROFILE=Select profile -> CONFIG_SETTINGS=Profile settings CONFIG_SAVE_MESSAGE=Active profile {0} was saved CONFIG_SAVE_TITLE=Save confirmation -CONFIG_WINDOW_TITLE=Rails Configuration +CONFIG_WINDOW_TITLE=Rails Configuration CORRECT_CASH=Cash Correction CORRECT_MAP=Map Correction CURRENT=Current @@ -149,6 +150,19 @@ ComponentInitAs=Component {0} is initialized as class {1} ComponentManagerNotReconfigured=Cannot reconfigure the ComponentManager. ComponentManagerNotYetConfigured=ComponentManager has not yet been configured. +Config.infoText.locale=<html>te_ST shows local text keys. <br> Requires restart.</html> +Config.infoText.default_players=Enter player names separated by commas. +Config.label.default_game=Default game +Config.label.default_players=Default players +Config.label.local.player.name=Local player (for pbem) +Config.label.locale=Language Setting +Config.toolTip.local.player.name=Player name used as suffix for game save +Config.section.Format=Format/Colors +Config.section.General=General +Config.section.Log=Log +Config.section.Map=Map +Config.section.Save=Save +Config.section.UI=Windows/Fonts ConfirmToken=Press Lay Token to confirm token, click another city hex, or press the No Token button. connected=connected CorrectCashAddMoney=CORRECTION: {0} receives {1} from the bank Modified: trunk/18xx/data/Properties.xml =================================================================== --- trunk/18xx/data/Properties.xml 2010-07-30 20:59:08 UTC (rev 1363) +++ trunk/18xx/data/Properties.xml 2010-08-01 11:46:26 UTC (rev 1364) @@ -2,7 +2,7 @@ <!-- Supported properties Defines rails configuration options, but do not stores the actual values --> <Properties> - <Panel name="General"> + <Section name="General"> <Property name="locale" type="LIST" values="en_US,te_ST" initClass="rails.util.LocalText" initMethod="setLocale" initParameter="yes" /> @@ -10,28 +10,28 @@ <Property name="default_players" type="STRING" /> <Property name="local.player.name" type="STRING" /> - </Panel> - <Panel name="Save"> + </Section> + <Section name="Save"> <Property name="save.directory" type="DIRECTORY" /> <Property name="save.filename.date_time_pattern" type="STRING" /> <Property name="save.filename.suffix" type="STRING" /> <Property name="save.filename.extension" type="STRING" /> <Property name="save.recovery.active" type="BOOLEAN" /> <Property name="save.recovery.filepath" type="FILE" /> - </Panel> - <Panel name="UI"> + </Section> + <Section name="UI"> <Property name="report.window.open" type="BOOLEAN" /> <Property name="report.window.editable" type="BOOLEAN" /> <Property name="stockchart.window.open" type="BOOLEAN" /> <Property name="font.ui.scale" type="PERCENT" /> <Property name="font.ui.name" type="FONT" /> <Property name="font.ui.style" type="LIST" values="plain,bold" /> - </Panel> - <Panel name="Map"> + </Section> + <Section name="Map"> <Property name="map.autoscroll" type="BOOLEAN" /> <Property name="map.zoomstep" type="INTEGER" /> - </Panel> - <Panel name="Format"> + </Section> + <Section name="Format"> <Property name="money_format" type="STRING" /> <Property name="or.number_format" type="LIST" values="simple,composite" /> <Property name="route.colour.1" type="COLOR" @@ -42,10 +42,10 @@ initClass="rails.ui.swing.hexmap.HexMap" initMethod="setRouteColours" /> <Property name="route.colour.4" type="COLOR" initClass="rails.ui.swing.hexmap.HexMap" initMethod="setRouteColours" /> - </Panel> - <Panel name="Log"> + </Section> + <Section name="Log"> <Property name="report.directory" type="DIRECTORY" /> <Property name="report.filename.date_time_pattern" type="STRING" /> <Property name="report.filename.extension" type="STRING" /> - </Panel> + </Section> </Properties> \ No newline at end of file Modified: trunk/18xx/rails/ui/swing/ConfigWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-07-30 20:59:08 UTC (rev 1363) +++ trunk/18xx/rails/ui/swing/ConfigWindow.java 2010-08-01 11:46:26 UTC (rev 1364) @@ -14,8 +14,12 @@ import java.awt.event.FocusListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.File; import java.util.Map; import java.util.List; @@ -28,6 +32,7 @@ import javax.swing.filechooser.FileFilter; import javax.swing.JCheckBox; import javax.swing.JComponent; +import javax.swing.JDialog; import javax.swing.JFormattedTextField; import javax.swing.JFrame; import javax.swing.JLabel; @@ -42,6 +47,7 @@ import javax.swing.border.Border; import rails.game.ConfigurationException; +import rails.ui.swing.elements.RailsIcon; import rails.util.Config; import rails.util.ConfigItem; import rails.util.LocalText; @@ -151,10 +157,10 @@ Border titled = BorderFactory.createTitledBorder(etched, LocalText.getText("CONFIG_SETTINGS")); configPane.setBorder(titled); - Map<String, List<ConfigItem>> configPanels = Config.getConfigPanels(); + Map<String, List<ConfigItem>> configSections = Config.getConfigSections(); int maxElements = Config.getMaxElementsInPanels(); - for (String panelName:configPanels.keySet()) { + for (String sectionName:configSections.keySet()) { JPanel newPanel = new JPanel(); newPanel.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); @@ -164,18 +170,18 @@ gbc.weighty = 0.8; gbc.insets = new Insets(5,5,5,5); gbc.anchor = GridBagConstraints.WEST; - for (ConfigItem item:configPanels.get(panelName)) { + for (ConfigItem item:configSections.get(sectionName)) { gbc.gridx = 0; gbc.gridy++; defineElement(newPanel, item, gbc); } // fill up to maxElements gbc.gridx = 0; - for (gbc.gridy++; gbc.gridy < maxElements; gbc.gridy++) { + while (++gbc.gridy < maxElements) { JLabel emptyLabel = new JLabel(""); newPanel.add(emptyLabel, gbc); } - configPane.addTab(LocalText.getText("Config.panel." + panelName), newPanel); + configPane.addTab(LocalText.getText("Config.section." + sectionName), newPanel); } } @@ -192,13 +198,17 @@ private void defineElement(JPanel panel, final ConfigItem item, GridBagConstraints gbc) { - // standard components + // current value (based on current changes and properties) String configValue = item.getCurrentValue(); -// final String toolTip = item.toolTip; - // item label - JLabel label = new JLabel(LocalText.getText("Config." + item.name)); -// label.setToolTipText(toolTip); + // item label, toolTip and infoText + final String itemLabel = LocalText.getText("Config.label." + item.name); + final String toolTip = LocalText.getTextWithDefault("Config.toolTip." + item.name, null); + final String infoText = LocalText.getTextWithDefault("Config.infoText." + item.name, null); + + // define label + JLabel label = new JLabel(itemLabel); + label.setToolTipText(toolTip); gbc.fill = GridBagConstraints.NONE; addToGridBag(panel, label, gbc); @@ -277,7 +287,7 @@ } final JComboBox comboBox = new JComboBox(allowedValues); comboBox.setSelectedItem(configValue); -// comboBox.setToolTipText(toolTip)); + comboBox.setToolTipText(toolTip); comboBox.addFocusListener(new FocusListener() { public void focusGained(FocusEvent arg0) { // do nothing @@ -295,19 +305,20 @@ case FILE: final JLabel dirLabel = new JLabel(configValue); dirLabel.setHorizontalAlignment(SwingConstants.CENTER); -// dirLabel.setToolTipText(toolTip); + dirLabel.setToolTipText(toolTip); gbc.fill = GridBagConstraints.HORIZONTAL; addToGridBag(panel, dirLabel, gbc); JButton dirButton = new JButton("Choose..."); dirButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { - JFileChooser fc = new JFileChooser(dirLabel.getText()); + JFileChooser fc = new JFileChooser(); if (item.type == ConfigItem.ConfigType.DIRECTORY) { fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); } else { fc.setFileSelectionMode(JFileChooser.FILES_ONLY); } + fc.setSelectedFile(new File(dirLabel.getText())); int state = fc.showOpenDialog(ConfigWindow.this); if ( state == JFileChooser.APPROVE_OPTION ){ File file = fc.getSelectedFile(); @@ -336,7 +347,7 @@ } else { colorLabel.setForeground(Color.BLACK); } -// colorLabel.setToolTipText(toolTip); + colorLabel.setToolTipText(toolTip); gbc.fill = GridBagConstraints.HORIZONTAL; addToGridBag(panel, colorLabel, gbc); JButton colorButton = new JButton("Choose..."); @@ -378,6 +389,43 @@ addEmptyLabel(panel, gbc); break; } + // add info icon for infoText + if (infoText != null) { + JLabel infoIcon = new JLabel(RailsIcon.INFO.icon); + infoIcon.addMouseListener(new MouseListener() { + public void mousePressed(MouseEvent e) { + final JDialog dialog = new JDialog(ConfigWindow.this, false); + final JOptionPane optionPane = new JOptionPane(); + optionPane.setMessageType(JOptionPane.INFORMATION_MESSAGE); + optionPane.setMessage(infoText); + optionPane.addPropertyChangeListener(JOptionPane.VALUE_PROPERTY, + new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent e) { + dialog.dispose(); + } + } + ); + dialog.setTitle(LocalText.getText("CONFIG_INFO_TITLE", itemLabel)); + dialog.getContentPane().add(optionPane); + dialog.pack(); + dialog.setVisible(true); + } + + public void mouseClicked(MouseEvent e) { + } + public void mouseReleased(MouseEvent e) { + } + + public void mouseEntered(MouseEvent e) { + } + + public void mouseExited(MouseEvent e) { + } + }); + gbc.fill = GridBagConstraints.NONE; + addToGridBag(panel, infoIcon, gbc); + addEmptyLabel(panel, gbc); + } } private void setupButtonPanel() { Modified: trunk/18xx/rails/ui/swing/StartRoundWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/StartRoundWindow.java 2010-07-30 20:59:08 UTC (rev 1363) +++ trunk/18xx/rails/ui/swing/StartRoundWindow.java 2010-08-01 11:46:26 UTC (rev 1364) @@ -702,15 +702,7 @@ } private ImageIcon createInfoIcon() { - - String path = "/rails/ui/images/Inform.gif"; - java.net.URL imgURL = getClass().getResource(path); - if (imgURL != null) { - return new ImageIcon(imgURL, "Info"); - } else { - System.err.println("Couldn't find file: " + path); - return null; - } + return RailsIcon.INFO.icon; } public void keyPressed(KeyEvent e) { Added: trunk/18xx/rails/ui/swing/elements/RailsIcon.java =================================================================== --- trunk/18xx/rails/ui/swing/elements/RailsIcon.java (rev 0) +++ trunk/18xx/rails/ui/swing/elements/RailsIcon.java 2010-08-01 11:46:26 UTC (rev 1364) @@ -0,0 +1,30 @@ +package rails.ui.swing.elements; + +import javax.swing.ImageIcon; + +/** + * Enumeration that provides a specific ImageIcon + * Simply use RailsIcon.{IconName}.create + * @author freystef + */ + +public enum RailsIcon { + + // in parentheses the image file + INFO ("Inform.gif"); + + private final static String IMAGE_PATH = "/rails/ui/images/"; + public final ImageIcon icon; + + private RailsIcon(String fileName) { + String path = IMAGE_PATH + fileName; + java.net.URL imgURL = getClass().getResource(path); + if (imgURL != null) { + icon = new ImageIcon(imgURL, "Info"); + } else { + System.err.println("Couldn't find file: " + path); + icon = null; + } + } + +} Property changes on: trunk/18xx/rails/ui/swing/elements/RailsIcon.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: trunk/18xx/rails/util/Config.java =================================================================== --- trunk/18xx/rails/util/Config.java 2010-07-30 20:59:08 UTC (rev 1363) +++ trunk/18xx/rails/util/Config.java 2010-08-01 11:46:26 UTC (rev 1364) @@ -39,7 +39,7 @@ private static final String CONFIG_XML_DIR = "data"; private static final String CONFIG_XML_FILE = "Properties.xml"; private static final String CONFIG_TAG = "Properties"; - private static final String PANEL_TAG = "Panel"; + private static final String SECTION_TAG = "Section"; private static final String ITEM_TAG = "Property"; /** Log 4j configuration */ @@ -67,7 +67,7 @@ private static boolean propertiesLoaded = false; /** Map that holds the panel, which contains config items */ - private static Map<String, List<ConfigItem>> configPanels = null; + private static Map<String, List<ConfigItem>> configSections = null; /** * Hidden constructor, the class is never instantiated, everything is static @@ -81,28 +81,30 @@ List<String> directories = new ArrayList<String>(); directories.add(CONFIG_XML_DIR); try { - // Find the <Config> tag + // Find the config tag inside the the config xml file Tag configTag = Tag.findTopTagInFile(CONFIG_XML_FILE, directories, CONFIG_TAG); log.debug("Opened config xml, filename = " + CONFIG_XML_FILE); - configPanels = new LinkedHashMap<String, List<ConfigItem>>(); - // find panels - List<Tag> panelTags = configTag.getChildren(PANEL_TAG); - if (panelTags != null) { - for (Tag panelTag:panelTags) { + // define sections + configSections = new LinkedHashMap<String, List<ConfigItem>>(); + + // find sections + List<Tag> sectionTags = configTag.getChildren(SECTION_TAG); + if (sectionTags != null) { + for (Tag sectionTag:sectionTags) { // find name attribute - String panelName = panelTag.getAttributeAsString("name"); - if (!Util.hasValue(panelName)) continue; + String sectionName = sectionTag.getAttributeAsString("name"); + if (!Util.hasValue(sectionName)) continue; // find items - List<Tag> itemTags = panelTag.getChildren(ITEM_TAG); + List<Tag> itemTags = sectionTag.getChildren(ITEM_TAG); if (itemTags == null || itemTags.size() == 0) continue; - List<ConfigItem> panelItems = new ArrayList<ConfigItem>(); + List<ConfigItem> sectionItems = new ArrayList<ConfigItem>(); for (Tag itemTag:itemTags) { - panelItems.add(new ConfigItem(itemTag)); + sectionItems.add(new ConfigItem(itemTag)); } - configPanels.put(panelName, panelItems); + configSections.put(sectionName, sectionItems); } } @@ -111,20 +113,20 @@ } } - public static Map<String, List<ConfigItem>> getConfigPanels() { - if (configPanels == null) { + public static Map<String, List<ConfigItem>> getConfigSections() { + if (configSections == null) { readConfigSetupXML(); } - log.debug("Configuration setup = " + configPanels); - return configPanels; + log.debug("Configuration setup = " + configSections); + return configSections; } public static int getMaxElementsInPanels() { int maxElements = 0; - for (List<ConfigItem> panel:configPanels.values()) { + for (List<ConfigItem> panel:configSections.values()) { maxElements = Math.max(maxElements, panel.size()); } - log.debug("maxelements" + maxElements); + log.debug("Configuration sections with maximum elements of " + maxElements); return maxElements; } @@ -132,7 +134,7 @@ * updates the profile according to the changes in configitems */ public static void updateProfile() { - for (List<ConfigItem> items:configPanels.values()) { + for (List<ConfigItem> items:configSections.values()) { for (ConfigItem item:items) { if (!item.hasNewValue()) continue; if (item.getNewValue().equals(defaultProperties.get(item.name))) { @@ -151,7 +153,7 @@ * reverts all changes in configitems */ public static void revertProfile() { - for (List<ConfigItem> items:configPanels.values()) { + for (List<ConfigItem> items:configSections.values()) { for (ConfigItem item:items) { item.setNewValue(null); } Modified: trunk/18xx/rails/util/LocalText.java =================================================================== --- trunk/18xx/rails/util/LocalText.java 2010-07-30 20:59:08 UTC (rev 1363) +++ trunk/18xx/rails/util/LocalText.java 2010-08-01 11:46:26 UTC (rev 1364) @@ -29,10 +29,20 @@ } public static String getText(String key, Object parameter) { - return getText(key, new Object[] { parameter }); + return getText(key, new Object[] { parameter }); } + + public static String getText(String key, Object... parameters) { + /* If the text is not found, return the key in brackets */ + return getTextExecute(key, "<" + key + ">", true, parameters); + } + + public static String getTextWithDefault(String key, String defaultText) { + return getTextExecute(key, defaultText, false, (Object[]) null); + } - public static String getText(String key, Object... parameters) { + // actual procedure to retrieve the local text + private static String getTextExecute(String key, String defaultText, boolean errorOnMissing, Object... parameters) { String result = ""; if (key == null || key.length() == 0) return ""; @@ -95,11 +105,12 @@ try { result = localisedText.getString(key); } catch (Exception e) { - System.out.println("Missing text for key " + key + " in locale " + if (errorOnMissing) { + System.out.println("Missing text for key " + key + " in locale " + locale.getDisplayName() + " (" + localeCode + ")"); - /* If the text is not found, return the key in brackets */ - return "<" + key + ">"; + } + return defaultText; } if (parameters != null) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-01 12:17:32
|
Revision: 1365 http://rails.svn.sourceforge.net/rails/?rev=1365&view=rev Author: stefanfrey Date: 2010-08-01 12:17:26 +0000 (Sun, 01 Aug 2010) Log Message: ----------- Changed location for default.profiles Modified Paths: -------------- trunk/18xx/rails/util/Config.java Added Paths: ----------- trunk/18xx/data/profiles/default.profiles Removed Paths: ------------- trunk/18xx/default.profiles Copied: trunk/18xx/data/profiles/default.profiles (from rev 1363, trunk/18xx/default.profiles) =================================================================== --- trunk/18xx/data/profiles/default.profiles (rev 0) +++ trunk/18xx/data/profiles/default.profiles 2010-08-01 12:17:26 UTC (rev 1365) @@ -0,0 +1,2 @@ +default=data/profiles/default.profile +.test=data/profiles/test.profile Deleted: trunk/18xx/default.profiles =================================================================== --- trunk/18xx/default.profiles 2010-08-01 11:46:26 UTC (rev 1364) +++ trunk/18xx/default.profiles 2010-08-01 12:17:26 UTC (rev 1365) @@ -1,2 +0,0 @@ -default=data/profiles/default.profile -.test=data/profiles/test.profile Modified: trunk/18xx/rails/util/Config.java =================================================================== --- trunk/18xx/rails/util/Config.java 2010-08-01 11:46:26 UTC (rev 1364) +++ trunk/18xx/rails/util/Config.java 2010-08-01 12:17:26 UTC (rev 1365) @@ -46,7 +46,7 @@ private static final String LOG4J_CONFIG_FILE = "log4j.properties"; /** Rails profile configurations */ - private static String defaultProfilesFile = "default.profiles"; + private static String defaultProfilesFile = "data/profiles/default.profiles"; private static Properties defaultProfiles = new Properties(); private static String userProfilesFile = "user.profiles"; private static Properties userProfiles = new Properties(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ev...@us...> - 2010-08-01 15:28:30
|
Revision: 1366 http://rails.svn.sourceforge.net/rails/?rev=1366&view=rev Author: evos Date: 2010-08-01 15:28:24 +0000 (Sun, 01 Aug 2010) Log Message: ----------- Implemented option to sell shares in same turn at decreasong prices for all games except 1835. Modified Paths: -------------- trunk/18xx/data/1825/Game.xml trunk/18xx/data/1851/Game.xml trunk/18xx/data/1856/Game.xml trunk/18xx/data/1870/Game.xml trunk/18xx/data/1889/Game.xml trunk/18xx/data/18AL/Game.xml trunk/18xx/data/18EU/Game.xml trunk/18xx/data/18Kaas/Game.xml trunk/18xx/data/GamesList.xml trunk/18xx/rails/game/StockRound.java trunk/18xx/rails/game/specific/_1835/StockRound_1835.java Modified: trunk/18xx/data/1825/Game.xml =================================================================== --- trunk/18xx/data/1825/Game.xml 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/data/1825/Game.xml 2010-08-01 15:28:24 UTC (rev 1366) @@ -14,6 +14,7 @@ --> <GameOption name="RouteAwareness" values="Highlight,Deactivate" default="Deactivate" /> <GameOption name="RevenueCalculation" values="Suggest,Deactivate" default="Deactivate" /> + <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <PlayerShareLimit percentage="100"/> <BankPoolLimit percentage="100"></BankPoolLimit> <EndOfGame> Modified: trunk/18xx/data/1851/Game.xml =================================================================== --- trunk/18xx/data/1851/Game.xml 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/data/1851/Game.xml 2010-08-01 15:28:24 UTC (rev 1366) @@ -7,6 +7,7 @@ <GameOption name="NoMapMode" type="toggle" default="no" /> <GameOption name="UnlimitedTiles" type="toggle" default="no"/> <GameOption name="UnlimitedTopTrains" parm="8" type="toggle" default="no"/> + <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <GameParameters> <PlayerShareLimit percentage="60"/> <BankPoolLimit percentage="50"/> Modified: trunk/18xx/data/1856/Game.xml =================================================================== --- trunk/18xx/data/1856/Game.xml 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/data/1856/Game.xml 2010-08-01 15:28:24 UTC (rev 1366) @@ -8,6 +8,7 @@ <GameOption name="UnlimitedBonusTokens" type="toggle" default="no"/> <GameOption name="UnlimitedTiles" type="toggle" default="no"/> <GameOption name="LeaveAuctionOnPass" type="toggle" default="no"/> + <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <GameParameters> <StockRound class="rails.game.specific._1856.StockRound_1856" sequence="SellBuyOrBuySell"> Modified: trunk/18xx/data/1870/Game.xml =================================================================== --- trunk/18xx/data/1870/Game.xml 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/data/1870/Game.xml 2010-08-01 15:28:24 UTC (rev 1366) @@ -6,6 +6,7 @@ <GameOption name="RevenueCalculation" values="Suggest,Deactivate" default="Deactivate" /> <GameOption name="UnlimitedTiles" type="toggle" default="no"/> <GameOption name="LeaveAuctionOnPass" type="toggle" default="no"/> + <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <GameParameters> <PlayerShareLimit percentage="60"> <PriceProtection/> Modified: trunk/18xx/data/1889/Game.xml =================================================================== --- trunk/18xx/data/1889/Game.xml 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/data/1889/Game.xml 2010-08-01 15:28:24 UTC (rev 1366) @@ -22,6 +22,7 @@ <GameOption name="WithOptional6Train" type="toggle" default="no"/> <GameOption name="UnlimitedTopTrains" parm="D" type="toggle" default="yes"/> <GameOption name="TwoPlayersCertLimit70Percent" type="toggle" default="yes"/> + <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <GameParameters> <PlayerShareLimit percentage="60"> <!-- Option "NumberOfPlayers" is automatically set Modified: trunk/18xx/data/18AL/Game.xml =================================================================== --- trunk/18xx/data/18AL/Game.xml 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/data/18AL/Game.xml 2010-08-01 15:28:24 UTC (rev 1366) @@ -9,6 +9,7 @@ <GameOption name="Obsolete4Trains" type="toggle" default="yes"/> <GameOption name="UnlimitedTiles" type="toggle" default="no"/> <GameOption name="LeaveAuctionOnPass" type="toggle" default="no"/> + <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <GameParameters> <OperatingRound class="rails.game.specific._18AL.OperatingRound_18AL"/> <PlayerShareLimit percentage="60"/> Modified: trunk/18xx/data/18EU/Game.xml =================================================================== --- trunk/18xx/data/18EU/Game.xml 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/data/18EU/Game.xml 2010-08-01 15:28:24 UTC (rev 1366) @@ -8,6 +8,7 @@ <GameOption name="Extra4Trains" values="0,1" default="0"/> <GameOption name="NoMapMode" type="toggle" default="no" /> <GameOption name="UnlimitedTiles" type="toggle" default="no"/> + <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <GameParameters> <StockRound class="rails.game.specific._18EU.StockRound_18EU" sequence="sellBuy" Modified: trunk/18xx/data/18Kaas/Game.xml =================================================================== --- trunk/18xx/data/18Kaas/Game.xml 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/data/18Kaas/Game.xml 2010-08-01 15:28:24 UTC (rev 1366) @@ -9,6 +9,7 @@ <GameOption name="WithOptional6Train" type="toggle" default="no"/> <GameOption name="UnlimitedTiles" type="toggle" default="no"/> <GameOption name="LeaveAuctionOnPass" type="toggle" default="no"/> + <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <GameParameters> <PlayerShareLimit percentage="60"/> <BankPoolLimit percentage="50"/> Modified: trunk/18xx/data/GamesList.xml =================================================================== --- trunk/18xx/data/GamesList.xml 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/data/GamesList.xml 2010-08-01 15:28:24 UTC (rev 1366) @@ -47,6 +47,7 @@ <Option name="NoMapMode" type="toggle" default="no" /> <Option name="UnlimitedTiles" type="toggle" default="no"/> <Option name="UnlimitedTopTrains" parm="8" type="toggle" default="no"/> + <Option name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <Players minimum="3" maximum="5"/> </Game> @@ -65,6 +66,7 @@ <Option name="UnlimitedBonusTokens" type="toggle" default="no"/> <Option name="UnlimitedTiles" type="toggle" default="no"/> <Option name="LeaveAuctionOnPass" type="toggle" default="no"/> + <Option name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <Players minimum="3" maximum="6"/> </Game> @@ -85,6 +87,7 @@ <Option name="WithOptional6Train" type="toggle" default="no"/> <Option name="UnlimitedTopTrains" parm="D" type="toggle" default="yes"/> <Option name="TwoPlayersCertLimit70Percent" type="toggle" default="no"/> + <Option name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> </Game> <Game name="18AL"> @@ -105,6 +108,7 @@ <Option name="Obsolete4Trains" type="toggle" default="yes"/> <Option name="UnlimitedTiles" type="toggle" default="no"/> <Option name="LeaveAuctionOnPass" type="toggle" default="no"/> + <Option name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <Players minimum="3" maximum="5"/> </Game> @@ -142,6 +146,7 @@ <Option name="UnlimitedTopTrains" parm="D" type="toggle" default="no"/> <Option name="UnlimitedTiles" type="toggle" default="no"/> <Option name="LeaveAuctionOnPass" type="toggle" default="no"/> + <Option name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <Players minimum="3" maximum="6"/> </Game> @@ -185,6 +190,7 @@ <Option name="RevenueCalculation" values="Suggest,Deactivate" default="Suggest" /> <Option name="UnlimitedTiles" type="toggle" default="no"/> <Option name="LeaveAuctionOnPass" type="toggle" default="no"/> + <Option name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> <Players minimum="2" maximum="6"/> </Game> @@ -201,13 +207,14 @@ <Option name="RouteAwareness" values="Highlight,Deactivate" default="Highlight" /> <Option name="RevenueCalculation" values="Suggest,Deactivate" default="Suggest" /> <Option name="UnlimitedTiles" type="toggle" default="no"/> + <Option name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> </Game> <Credits>Rails is a computer implementation of a number of railroad board games, that are collectively known as the "18xx" railway game system. Rails is a Sourceforge project. Project founder: Brett Lentz. -Developers: Erik Vos and Brett Lentz. +Developers: Erik Vos, Stefan Frey and Brett Lentz. The 18xx railway game system was originated by Francis Tresham and Hartland Trefoil Ltd. Modified: trunk/18xx/rails/game/StockRound.java =================================================================== --- trunk/18xx/rails/game/StockRound.java 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/rails/game/StockRound.java 2010-08-01 15:28:24 UTC (rev 1366) @@ -412,12 +412,7 @@ * Check the price. If a cert was sold before this turn, the * original price is still valid */ - if (sellPrices.containsKey(compName) - && GameOption.convertValueToBoolean(getGameOption("SeparateSalesAtSamePrice"))) { - price = (sellPrices.get(compName)).getPrice(); - } else { - price = company.getMarketPrice(); - } + price = getCurrentSellPrice(company); price /= company.getShareUnitsForSharePrice(); /* Allow for different share units (as in 1835) */ @@ -1035,18 +1030,14 @@ } // All seems OK, now do the selling. - StockSpaceI sellPrice; - int price; + // Selling price + int price = getCurrentSellPrice (company); + + // Save original price as it may be reused in subsequent sale actions in the same turn boolean soldBefore = sellPrices.containsKey(companyName); - // Get the sell price (does not change within a turn) - if (soldBefore - && GameOption.convertValueToBoolean(getGameOption("SeparateSalesAtSamePrice"))) { - price = (sellPrices.get(companyName)).getPrice(); - } else { - sellPrice = company.getCurrentSpace(); - price = sellPrice.getPrice() / company.getShareUnitsForSharePrice(); - sellPrices.put(companyName, sellPrice); + if (!soldBefore) { + sellPrices.put(companyName, company.getCurrentSpace()); } moveStack.start(true); @@ -1118,6 +1109,20 @@ return true; } + protected int getCurrentSellPrice (PublicCompanyI company) { + + String companyName = company.getName(); + int price; + + if (sellPrices.containsKey(companyName) + && GameOption.convertValueToBoolean(getGameOption("SeparateSalesAtSamePrice"))) { + price = (sellPrices.get(companyName)).getPrice(); + } else { + price = company.getCurrentSpace().getPrice() / company.getShareUnitsForSharePrice(); + } + return price; + } + protected void adjustSharePrice (PublicCompanyI company, int numberSold, boolean soldBefore) { if (company.canSharePriceVary()) { Modified: trunk/18xx/rails/game/specific/_1835/StockRound_1835.java =================================================================== --- trunk/18xx/rails/game/specific/_1835/StockRound_1835.java 2010-08-01 12:17:26 UTC (rev 1365) +++ trunk/18xx/rails/game/specific/_1835/StockRound_1835.java 2010-08-01 15:28:24 UTC (rev 1366) @@ -78,6 +78,22 @@ return price; } + @Override + // The sell-in-same-turn-at-decreasing-price option does not apply here + protected int getCurrentSellPrice (PublicCompanyI company) { + + String companyName = company.getName(); + int price; + + if (sellPrices.containsKey(companyName)) { + price = (sellPrices.get(companyName)).getPrice(); + } else { + price = company.getCurrentSpace().getPrice() / company.getShareUnitsForSharePrice(); + } + return price; + } + + /** Share price goes down 1 space for any number of shares sold. */ @Override This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-04 22:06:03
|
Revision: 1368 http://rails.svn.sourceforge.net/rails/?rev=1368&view=rev Author: stefanfrey Date: 2010-08-04 22:05:57 +0000 (Wed, 04 Aug 2010) Log Message: ----------- Further updates to configuration dialog Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/data/Properties.xml trunk/18xx/rails/ui/swing/GameUIManager.java trunk/18xx/rails/util/ConfigItem.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-08-01 21:30:16 UTC (rev 1367) +++ trunk/18xx/LocalisedText.properties 2010-08-04 22:05:57 UTC (rev 1368) @@ -154,8 +154,31 @@ Config.infoText.default_players=Enter player names separated by commas. Config.label.default_game=Default game Config.label.default_players=Default players +Config.label.font.ui.name=Font selection +Config.label.font.ui.scale=Font scaling +Config.label.font.ui.style=Font style Config.label.local.player.name=Local player (for pbem) -Config.label.locale=Language Setting +Config.label.locale=Language setting +Config.label.map.autoscroll=Map autoscroll +Config.label.map.zoomstep=Map zoomstep +Config.label.money_format=Money format +Config.label.or.number_format=Number format +Config.label.report.directory=Report directory +Config.label.report.filename.date_time_pattern=Report filename date pattern +Config.label.report.filename.extension=Report filename extension +Config.label.report.window.open=Report window open +Config.label.report.window.editable=Report window editable +Config.label.route.colour.1=Route color for first train +Config.label.route.colour.2=Route color for second train +Config.label.route.colour.3=Route color for third train +Config.label.route.colour.4=Route color for fourth train +Config.label.stockchart.window.open=Stockchart open +Config.label.save.directory=Save folder +Config.label.save.filename.date_time_pattern=Filename date pattern +Config.label.save.filename.suffix=Filename suffix +Config.label.save.filename.extension=Filename extension +Config.label.save.recovery.active=Automatic save +Config.label.save.recovery.filepath=Automatic save filepath Config.toolTip.local.player.name=Player name used as suffix for game save Config.section.Format=Format/Colors Config.section.General=General Modified: trunk/18xx/data/Properties.xml =================================================================== --- trunk/18xx/data/Properties.xml 2010-08-01 21:30:16 UTC (rev 1367) +++ trunk/18xx/data/Properties.xml 2010-08-04 22:05:57 UTC (rev 1368) @@ -23,9 +23,12 @@ <Property name="report.window.open" type="BOOLEAN" /> <Property name="report.window.editable" type="BOOLEAN" /> <Property name="stockchart.window.open" type="BOOLEAN" /> - <Property name="font.ui.scale" type="PERCENT" /> - <Property name="font.ui.name" type="FONT" /> - <Property name="font.ui.style" type="LIST" values="plain,bold" /> + <Property name="font.ui.scale" type="PERCENT" + initClass="rails.ui.swing.GameUIManager" initMethod="updateUILookAndFeel" initParameter="no" /> + <Property name="font.ui.name" type="FONT" + initClass="rails.ui.swing.GameUIManager" initMethod="updateUILookAndFeel" initParameter="no" /> + <Property name="font.ui.style" type="LIST" values="plain,bold" + initClass="rails.ui.swing.GameUIManager" initMethod="updateUILookAndFeel" initParameter="no" /> </Section> <Section name="Map"> <Property name="map.autoscroll" type="BOOLEAN" /> Modified: trunk/18xx/rails/ui/swing/GameUIManager.java =================================================================== --- trunk/18xx/rails/ui/swing/GameUIManager.java 2010-08-01 21:30:16 UTC (rev 1367) +++ trunk/18xx/rails/ui/swing/GameUIManager.java 2010-08-04 22:05:57 UTC (rev 1368) @@ -1,5 +1,6 @@ package rails.ui.swing; +import java.awt.EventQueue; import java.awt.Font; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -87,6 +88,14 @@ this.gameManager = gameManager; uiHints = gameManager.getUIHints(); + initSaveSettings(); + initFontSettings(); + + configuredStockChartVisibility = "yes".equalsIgnoreCase(Config.get("stockchart.window.open")); + + } + + private void initSaveSettings() { saveDirectory = Config.get("save.directory"); if (!Util.hasValue(saveDirectory)) { saveDirectory = DEFAULT_SAVE_DIRECTORY; @@ -109,9 +118,10 @@ if (Util.hasValue(saveSuffixSpec) && !saveSuffixSpec.equals(NEXT_PLAYER_SUFFIX)) { saveSuffix = "_" + saveSuffixSpec; } + } - configuredStockChartVisibility = "yes".equalsIgnoreCase(Config.get("stockchart.window.open")); - + private void initFontSettings() { + // font settings, can be game specific String fontType = Config.getGameSpecific("font.ui.name"); Font font = null; @@ -120,7 +130,7 @@ String fontStyle = Config.getGameSpecific("font.ui.style"); if (Util.hasValue(fontStyle)) { if (fontStyle.equalsIgnoreCase("plain")) { - boldStyle = false; + boldStyle = false; } } if (boldStyle) { @@ -141,6 +151,7 @@ } } } + public void gameUIInit() { @@ -807,5 +818,31 @@ public boolean getGameParameterAsBoolean (GuiDef.Parm key) { return (Boolean) getGameParameter(key); } - + + private void updateWindowsLookAndFeel() { + SwingUtilities.updateComponentTreeUI(statusWindow); + statusWindow.pack(); + SwingUtilities.updateComponentTreeUI(orWindow); + orWindow.pack(); + SwingUtilities.updateComponentTreeUI(reportWindow); + reportWindow.pack(); + SwingUtilities.updateComponentTreeUI(configWindow); + configWindow.pack(); + SwingUtilities.updateComponentTreeUI(stockChart); + stockChart.pack(); + } + + /** update fonts settings + * (after configuration changes) + */ + public static void updateUILookAndFeel() { + instance.initFontSettings(); + instance.updateWindowsLookAndFeel(); + +// EventQueue.invokeLater(new Runnable() { +// public void run() { +// instance.repaintWindows(); +// } +// }); + } } Modified: trunk/18xx/rails/util/ConfigItem.java =================================================================== --- trunk/18xx/rails/util/ConfigItem.java 2010-08-01 21:30:16 UTC (rev 1367) +++ trunk/18xx/rails/util/ConfigItem.java 2010-08-04 22:05:57 UTC (rev 1368) @@ -121,7 +121,7 @@ clazz.getMethod(initMethod).invoke(null); } } catch (Exception e) { - log.error("Config profile: cannot call initMethod"); + log.error("Config profile: cannot call initMethod, Exception = " + e.toString()); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-05 18:53:19
|
Revision: 1369 http://rails.svn.sourceforge.net/rails/?rev=1369&view=rev Author: stefanfrey Date: 2010-08-05 18:53:13 +0000 (Thu, 05 Aug 2010) Log Message: ----------- 1. Added DisplayBuffer report for forced selling due to certificate limit 2. Fixed problem of hermit base token in revenue calculation 3. Added gameoption for 1856 THB (but not implementation yet) Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/data/1856/Game.xml trunk/18xx/rails/algorithms/NetworkGraphBuilder.java trunk/18xx/rails/algorithms/RevenueAdapter.java trunk/18xx/rails/game/StockRound.java trunk/18xx/rails/ui/swing/ORUIManager.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-08-04 22:05:57 UTC (rev 1368) +++ trunk/18xx/LocalisedText.properties 2010-08-05 18:53:13 UTC (rev 1369) @@ -1,4 +1,5 @@ # Texts with lowercase keys are intended to be inserted into other messages +1856THBHomeBlocked=THB home hex is blocked for token lays (unless gray tile) 1889PrivateBactive=Player {0} (owner of Private B) may lay port tile 1889PrivateCactive=Player {0} (previous owner of Private C) may lay tile on C4 immediately 18ALOptimizeNamedTrains=Optimize named train assignment @@ -246,6 +247,9 @@ ExchangeTokensPrompt1=Select {0} cities where {1} will exchange a base token ExchangeTokensPrompt2=Select {0} through {1} cities where {2} will exchange a base token ExchangesTrain={0} exchanges a {1}-train for a {2}-train from {3} for {4} +ExceedCertificateLimit=<em>{0} exceeds certificate limit!</em><br>{1}<br>Only share selling allowed until certificate limit holds. +ExceedCertificateLimitTotal=-> Player has {0} certificates, exceeds total certificate limit of {1}. +ExceedCertificateLimitCompany=-> Player has a {1}% holding of {0}, exceeds company holding limit of {2}%. extra=extra ExtraTile= You can lay an unconnected tile on {0}. ExtraToken= You can lay an unconnected base token on {0}. @@ -501,7 +505,7 @@ SelectNoBid=Select, No Bid SelectTrain=Select a train and press OK, or press Done. SelectCheapTrain=You can buy a cheaper new train by using {0}. -SelectStationForToken={0}, select a station on tile {1} for the {2} home base token +SelectStationForToken={0}, select a station on hex {1} for the {2} home base token SelectStationForTokenOption=Place token in station {0} with tracks to {1} SelectForAuctioning=\n{0} selects {1} for auctioning SELL=Sell Modified: trunk/18xx/data/1856/Game.xml =================================================================== --- trunk/18xx/data/1856/Game.xml 2010-08-04 22:05:57 UTC (rev 1368) +++ trunk/18xx/data/1856/Game.xml 2010-08-05 18:53:13 UTC (rev 1369) @@ -9,6 +9,7 @@ <GameOption name="UnlimitedTiles" type="toggle" default="no"/> <GameOption name="LeaveAuctionOnPass" type="toggle" default="no"/> <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> + <GameOption name="1856THBHomeBlocked" type="toggle" default="no" /> <GameParameters> <StockRound class="rails.game.specific._1856.StockRound_1856" sequence="SellBuyOrBuySell"> Modified: trunk/18xx/rails/algorithms/NetworkGraphBuilder.java =================================================================== --- trunk/18xx/rails/algorithms/NetworkGraphBuilder.java 2010-08-04 22:05:57 UTC (rev 1368) +++ trunk/18xx/rails/algorithms/NetworkGraphBuilder.java 2010-08-05 18:53:13 UTC (rev 1369) @@ -265,6 +265,11 @@ for (NetworkVertex vertex:graph.vertexSet()) { Set<NetworkEdge> vertexEdges = graph.edgesOf(vertex); + // always keep protected vertices + if (protectedVertices.contains(vertex)) { + continue; + } + // remove hermit if (vertexEdges.size() == 0) { log.info("Remove hermit (no connection) = " + vertex); @@ -282,7 +287,7 @@ removed = true; break; } // vertex is not necessary and not on the protected list - else if (vertexEdges.size() == 2 && !protectedVertices.contains(vertex)) { + else if (vertexEdges.size() == 2) { NetworkEdge[] edges = vertexEdges.toArray(new NetworkEdge[2]); if (edges[0].isGreedy() == edges[1].isGreedy()) { if (!edges[0].isGreedy()) { Modified: trunk/18xx/rails/algorithms/RevenueAdapter.java =================================================================== --- trunk/18xx/rails/algorithms/RevenueAdapter.java 2010-08-04 22:05:57 UTC (rev 1368) +++ trunk/18xx/rails/algorithms/RevenueAdapter.java 2010-08-05 18:53:13 UTC (rev 1369) @@ -143,10 +143,9 @@ return startVertices; } - public boolean addStartVertex(NetworkVertex startVertex) { - if (startVertices.contains(startVertex)) return false; - - startVertices.add(startVertex); + public boolean addStartVertices(Collection<NetworkVertex> startVertices) { + this.startVertices.addAll(startVertices); + protectedVertices.addAll(startVertices); return true; } @@ -208,7 +207,7 @@ NetworkVertex.initAllRailsVertices(graph.vertexSet(), company, phase); // define startVertexes - startVertices.addAll(companyGraph.getCompanyBaseTokenVertexes(company)); + addStartVertices(companyGraph.getCompanyBaseTokenVertexes(company)); // define visit sets defineVertexVisitSets(); Modified: trunk/18xx/rails/game/StockRound.java =================================================================== --- trunk/18xx/rails/game/StockRound.java 2010-08-04 22:05:57 UTC (rev 1368) +++ trunk/18xx/rails/game/StockRound.java 2010-08-05 18:53:13 UTC (rev 1369) @@ -101,7 +101,15 @@ setSellableShares(); - if (isPlayerOverLimits (currentPlayer)) return true; + // check certification limits and display warning + if (isPlayerOverLimits (currentPlayer)) { + DisplayBuffer.add(LocalText.getText("ExceedCertificateLimit" + , currentPlayer.getName() + , isPlayerOverLimitsDetail(currentPlayer) + ) + ); + return true; + } passAllowed = true; @@ -1398,18 +1406,36 @@ } protected boolean isPlayerOverLimits(Player player) { - + return (isPlayerOverLimitsDetail(player) != null); + } + + protected String isPlayerOverLimitsDetail(Player player) { + StringBuffer violations = new StringBuffer(); + // Over the total certificate hold Limit? - if (player.getPortfolio().getCertificateCount() > gameManager.getPlayerCertificateLimit(player)) - return true; + if (player.getPortfolio().getCertificateCount() > gameManager.getPlayerCertificateLimit(player)) { + violations.append(LocalText.getText("ExceedCertificateLimitTotal", + player.getPortfolio().getCertificateCount(), + gameManager.getPlayerCertificateLimit(player))); + } + ; // Over the hold limit of any company? for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { if (company.hasStarted() && company.hasStockPrice() - && !checkAgainstHoldLimit(player, company, 0)) return true; + && !checkAgainstHoldLimit(player, company, 0)) { + violations.append(LocalText.getText("ExceedCertificateLimitCompany", + company.getName(), + player.getPortfolio().getShare(company), + getGameParameterAsInt(GameDef.Parm.PLAYER_SHARE_LIMIT) + )); + } } - - return false; + if (violations.length() != 0) { + return violations.toString(); + } else { + return null; + } } /** Modified: trunk/18xx/rails/ui/swing/ORUIManager.java =================================================================== --- trunk/18xx/rails/ui/swing/ORUIManager.java 2010-08-04 22:05:57 UTC (rev 1368) +++ trunk/18xx/rails/ui/swing/ORUIManager.java 2010-08-05 18:53:13 UTC (rev 1369) @@ -879,7 +879,11 @@ if (prompts.size () > 1) { String selected = (String) JOptionPane.showInputDialog(orWindow, - LocalText.getText("SelectStationForToken"), + LocalText.getText("SelectStationForToken", + action.getPlayerName(), + hex.getName(), + company.getName() + ), LocalText.getText("WhichStation"), JOptionPane.PLAIN_MESSAGE, null, prompts.toArray(), prompts.get(0)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-07 14:26:17
|
Revision: 1372 http://rails.svn.sourceforge.net/rails/?rev=1372&view=rev Author: stefanfrey Date: 2010-08-07 14:26:10 +0000 (Sat, 07 Aug 2010) Log Message: ----------- Fixed bug of wrong cgr train limit Improved undo behavior of cgr formation Added PresidentModel for UI reasons Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/rails/game/OperatingRound.java trunk/18xx/rails/game/PublicCompany.java trunk/18xx/rails/game/PublicCompanyI.java trunk/18xx/rails/game/Round.java trunk/18xx/rails/game/model/ShareModel.java trunk/18xx/rails/game/move/MoveStack.java trunk/18xx/rails/game/specific/_1856/CGRFormationRound.java trunk/18xx/rails/ui/swing/GameUIManager.java trunk/18xx/rails/ui/swing/ORPanel.java trunk/18xx/rails/ui/swing/ORUIManager.java trunk/18xx/rails/ui/swing/gamespecific/_1856/StatusWindow_1856.java Added Paths: ----------- trunk/18xx/rails/game/model/PresidentModel.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/LocalisedText.properties 2010-08-07 14:26:10 UTC (rev 1372) @@ -1,4 +1,5 @@ # Texts with lowercase keys are intended to be inserted into other messages +1856MergerDialog=Repay loan decision of {0} for CGR merger 1856THBHomeBlocked=THB home hex is blocked for token lays (unless gray tile) 1889PrivateBactive=Player {0} (owner of Private B) may lay port tile 1889PrivateCactive=Player {0} (previous owner of Private C) may lay tile on C4 immediately @@ -247,7 +248,7 @@ ExchangeTokensPrompt1=Select {0} cities where {1} will exchange a base token ExchangeTokensPrompt2=Select {0} through {1} cities where {2} will exchange a base token ExchangesTrain={0} exchanges a {1}-train for a {2}-train from {3} for {4} -ExceedCertificateLimit=<em>{0} exceeds certificate limit!</em><br>{1}<br>Only share selling allowed until certificate limit holds. +ExceedCertificateLimit=<em>{0} exceeds certificate limit!</em><br>{1}<br>Only share selling allowed until certificate limit holds again. ExceedCertificateLimitTotal=-> Player has {0} certificates, exceeds total certificate limit of {1}. ExceedCertificateLimitCompany=-> Player has a {1}% holding of {0}, exceeds company holding limit of {2}%. extra=extra Modified: trunk/18xx/rails/game/OperatingRound.java =================================================================== --- trunk/18xx/rails/game/OperatingRound.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/game/OperatingRound.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -233,7 +233,7 @@ } else if (selectedAction instanceof ExchangeTokens) { - result = exchangeTokens ((ExchangeTokens)selectedAction); + result = exchangeTokens ((ExchangeTokens)selectedAction, false); // 2nd parameter: unlinked moveset } else if (selectedAction instanceof ClosePrivate) { Modified: trunk/18xx/rails/game/PublicCompany.java =================================================================== --- trunk/18xx/rails/game/PublicCompany.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/game/PublicCompany.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -93,6 +93,9 @@ /** Company treasury, holding cash */ protected CashModel treasury = null; + + /** PresidentModel */ + protected PresidentModel presidentModel = null; /** Has the company started? */ protected BooleanState hasStarted = null; @@ -620,6 +623,7 @@ lastRevenue.setOption(MoneyModel.SUPPRESS_INITIAL_ZERO); lastRevenueAllocation = new StringState(name + "_lastAllocation"); baseTokensModel = new BaseTokensModel(this); + presidentModel = new PresidentModel(this); hasStarted = new BooleanState(name + "_hasStarted", false); hasFloated = new BooleanState(name + "_hasFloated", false); @@ -1241,6 +1245,10 @@ return null; } + public PresidentModel getPresidentModel() { + return presidentModel; + } + public PublicCertificateI getPresidentsShare () { return certificates.get(0); } @@ -1982,4 +1990,5 @@ public String getExtraShareMarks () { return ""; } + } Modified: trunk/18xx/rails/game/PublicCompanyI.java =================================================================== --- trunk/18xx/rails/game/PublicCompanyI.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/game/PublicCompanyI.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -209,6 +209,8 @@ public Player getPresident(); + public PresidentModel getPresidentModel(); + public PublicCertificateI getPresidentsShare(); public int getFloatPercentage(); @@ -355,6 +357,7 @@ public ModelObject getInGameModel (); public ModelObject getIsClosedModel (); + } Modified: trunk/18xx/rails/game/Round.java =================================================================== --- trunk/18xx/rails/game/Round.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/game/Round.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -167,7 +167,7 @@ return true; } - protected boolean exchangeTokens (ExchangeTokens action) { + protected boolean exchangeTokens(ExchangeTokens action, boolean linkedMoveSet) { String errMsg = null; @@ -199,6 +199,7 @@ } moveStack.start(true); + if (linkedMoveSet) moveStack.linkToPreviousMoveSet(); if (exchanged > 0) { MapHex hex; Added: trunk/18xx/rails/game/model/PresidentModel.java =================================================================== --- trunk/18xx/rails/game/model/PresidentModel.java (rev 0) +++ trunk/18xx/rails/game/model/PresidentModel.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -0,0 +1,34 @@ +package rails.game.model; + +import java.util.Observable; +import java.util.Observer; + +import rails.game.Player; +import rails.game.PublicCompanyI; + +/** + * model object for the current company president + * gets registered by the ShareModels + */ + +public class PresidentModel extends ModelObject implements Observer { + + PublicCompanyI company; + + public PresidentModel(PublicCompanyI company) { + this.company = company; + } + + public void update(Observable o, Object arg) { + // if notified by ShareModels, calls update itself + update(); + } + + @Override + public String getText() { + Player president = company.getPresident(); + if (president == null ) return ""; + else return company.getPresident().getNameAndPriority(); + } + +} Property changes on: trunk/18xx/rails/game/model/PresidentModel.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: trunk/18xx/rails/game/model/ShareModel.java =================================================================== --- trunk/18xx/rails/game/model/ShareModel.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/game/model/ShareModel.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -13,6 +13,8 @@ this.portfolio = portfolio; this.company = company; this.share = 0; + // add companies president model as observer + this.addObserver(company.getPresidentModel()); } public void setShare() { Modified: trunk/18xx/rails/game/move/MoveStack.java =================================================================== --- trunk/18xx/rails/game/move/MoveStack.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/game/move/MoveStack.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -128,8 +128,14 @@ public boolean redoMoveSet () { if (currentMoveSet == null && lastIndex < moveStack.size() - 1) { - ReportBuffer.add(LocalText.getText("REDO")); - (moveStack.get(++lastIndex)).reexecute(); + MoveSet redoAction; + redoAction= moveStack.get(++lastIndex); + do { + ReportBuffer.add(LocalText.getText("REDO")); + redoAction.reexecute(); + if (lastIndex == moveStack.size() - 1) break; + redoAction= moveStack.get(++lastIndex); + } while (redoAction.isLinkedToPreviousMove()); // log.debug ("MoveStack redo index is "+lastIndex); return true; } else { Modified: trunk/18xx/rails/game/specific/_1856/CGRFormationRound.java =================================================================== --- trunk/18xx/rails/game/specific/_1856/CGRFormationRound.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/game/specific/_1856/CGRFormationRound.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -15,13 +15,23 @@ public class CGRFormationRound extends SwitchableUIRound { private Player startingPlayer; + private int maxLoansToRepayByPresident = 0; private Map<Player, List<PublicCompanyI>> companiesToRepayLoans = null; + private PublicCompanyI currentCompany = null; - private int maxLoansToRepayByPresident = 0; private List<PublicCompanyI> mergingCompanies = new ArrayList<PublicCompanyI>(); + + /* + * pointers to cgr company + */ private String cgrName = PublicCompany_CGR.NAME; private PublicCompany_CGR cgr = (PublicCompany_CGR)gameManager.getCompanyManager().getPublicCompany(cgrName); + + /* + * effects from the merger, processed at the end + * thus no need for state variables + */ private List<TrainI> trainsToDiscardFrom = null; private boolean forcedTrainDiscard = true; private List<ExchangeableToken> tokensToExchangeFrom = null; @@ -187,14 +197,14 @@ numberOfLoans, currentCompany.getName()), false); - currentCompany.getLoanValueModel().setText(LocalText.getText("MERGE")); +// currentCompany.getLoanValueModel().setText(LocalText.getText("MERGE")); } maxLoansToRepayByPresident = maxNumber; break; } else { // President cannot help, this company will merge into CGR anyway mergingCompanies.add(currentCompany); - currentCompany.getLoanValueModel().setText(LocalText.getText("MERGE")); +// currentCompany.getLoanValueModel().setText(LocalText.getText("MERGE")); message = LocalText.getText("WillMergeInto", currentCompany.getName(), PublicCompany_CGR.NAME); @@ -237,7 +247,7 @@ // TODO Validation skipped for now... - moveStack.start(true); + moveStack.start(true).linkToPreviousMoveSet(); PublicCompanyI company = action.getCompany(); int numberRepaid = action.getNumberRepaid(); @@ -273,7 +283,7 @@ if (action.getCompany().getCurrentNumberOfLoans() > 0) { mergingCompanies.add(currentCompany); - currentCompany.getLoanValueModel().setText(LocalText.getText("MERGE")); +// currentCompany.getLoanValueModel().setText(LocalText.getText("MERGE")); String message = LocalText.getText("WillMergeInto", currentCompany.getName(), PublicCompany_CGR.NAME); @@ -633,7 +643,7 @@ key, oldTokens.get(key))); } } else { - executeExchangeTokens (nonHomeTokens); + executeExchangeTokens(nonHomeTokens); } // Close the merged companies @@ -692,7 +702,7 @@ } else if (action instanceof DiscardTrain) { result = discardTrain((DiscardTrain)action); } else if (action instanceof ExchangeTokens) { - result = exchangeTokens ((ExchangeTokens)action); + result = exchangeTokens((ExchangeTokens)action, true); // 2nd parameter: linked moveset } if (!result) return false; @@ -812,7 +822,8 @@ } /* End of validation, start of execution */ - moveStack.start(true); + // new: link always, see below commented + moveStack.start(true).linkToPreviousMoveSet(); if (train != null) { @@ -825,8 +836,6 @@ } else { cgrHasDiscardedTrains.set(true); } - // new: link always, see above uncommented - moveStack.linkToPreviousMoveSet(); return true; } Modified: trunk/18xx/rails/ui/swing/GameUIManager.java =================================================================== --- trunk/18xx/rails/ui/swing/GameUIManager.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/ui/swing/GameUIManager.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -305,6 +305,9 @@ /* Finish previous round UI processing */ if (previousRoundType != null) { + /* close current dialog */ + setCurrentDialog(null, null); + if (StockRound.class.isAssignableFrom(previousRoundType)) { log.debug("UI leaving Stock Round "+previousRoundName); statusWindow.finishRound(); Modified: trunk/18xx/rails/ui/swing/ORPanel.java =================================================================== --- trunk/18xx/rails/ui/swing/ORPanel.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/ui/swing/ORPanel.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -407,8 +407,9 @@ f = president[i] = - new Field(c.hasStarted() && !c.isClosed() - ? c.getPresident().getNameAndPriority() : ""); +// new Field(c.hasStarted() && !c.isClosed() +// ? c.getPresident().getNameAndPriority() : ""); + new Field(c.getPresidentModel()); addField(f, presidentXOffset, presidentYOffset + i, 1, 1, 0, visible); f = sharePrice[i] = new Field(c.getCurrentPriceModel()); @@ -468,7 +469,8 @@ addField(f, revXOffset, revYOffset + i, 1, 1, 0, visible); f = revenueSelect[i] = new Spinner(0, 0, 0, 10); addField(f, revXOffset, revYOffset + i, 1, 1, 0, false); - revenue[i].addDependent(revenueSelect[i]); + // deactived below, as this caused problems by gridpanel rowvisibility function -- sfy + // revenue[i].addDependent(revenueSelect[i]); f = decision[i] = new Field(c.getLastRevenueAllocationModel()); addField(f, revXOffset + 1, revYOffset + i, 1, 1, WIDE_RIGHT, visible); @@ -749,6 +751,10 @@ president[i].setHighlight(false); } + if (hasCompanyLoans) { + loansCaption.setHighlight(false); + } + for (JMenuItem item : menuItemsToReset) { item.setEnabled(false); if (item instanceof ActionMenuItem) { @@ -764,6 +770,11 @@ } } + public void resetCurrentRevenueDisplay() { + setSelect(revenue[orCompIndex], revenueSelect[orCompIndex], false); + } + + public void initORCompanyTurn(PublicCompanyI orComp, int orCompIndex) { this.orComp = orComp; Modified: trunk/18xx/rails/ui/swing/ORUIManager.java =================================================================== --- trunk/18xx/rails/ui/swing/ORUIManager.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/ui/swing/ORUIManager.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -619,6 +619,12 @@ orWindow.process(mapCorrectionAction); } } else if (tokenLayingEnabled) { + // if clickedHex == null, then go back to select hex step + if (clickedHex == null) { + upgradePanel.setPossibleTokenLays(null); + setLocalStep(SELECT_HEX_FOR_TOKEN); + return; + } List<LayToken> allowances = map.getTokenAllowanceForHex(clickedHex.getHexModel()); if (allowances.size() > 0) { @@ -640,16 +646,18 @@ && clickedHex == selectedHex) { selectedHex.rotateTile(); map.repaint(selectedHex.getBounds()); - return; } else { - if (selectedHex != null && clickedHex != selectedHex) { selectedHex.removeTile(); map.selectHex(null); } - if (clickedHex != null) { + // if clickedHex == null, then go back to select hex step + if (clickedHex == null) { + upgradePanel.setTileUpgrades(null); + setLocalStep(SELECT_HEX_FOR_TILE); + } else { if (clickedHex.getHexModel().isUpgradeableNow()) /* * Direct call to Model to be replaced later by use of @@ -1443,6 +1451,7 @@ // initial deactivation of revenue calculation if (!possibleActions.contains(SetDividend.class)) { orPanel.stopRevenueUpdate(); + orPanel.resetCurrentRevenueDisplay(); } if (possibleActions.contains(MapCorrectionAction.class)) { Modified: trunk/18xx/rails/ui/swing/gamespecific/_1856/StatusWindow_1856.java =================================================================== --- trunk/18xx/rails/ui/swing/gamespecific/_1856/StatusWindow_1856.java 2010-08-07 14:24:24 UTC (rev 1371) +++ trunk/18xx/rails/ui/swing/gamespecific/_1856/StatusWindow_1856.java 2010-08-07 14:26:10 UTC (rev 1372) @@ -1,5 +1,8 @@ package rails.ui.swing.gamespecific._1856; +import javax.swing.JDialog; +import javax.swing.WindowConstants; + import rails.game.*; import rails.game.action.*; import rails.game.specific._1856.CGRFormationRound; @@ -19,7 +22,6 @@ @Override public void updateStatus() { RoundI currentRound = gameUIManager.getCurrentRound(); - //if (!(currentRound instanceof OperatingRound)) { if (!(currentRound instanceof CGRFormationRound)) { super.updateStatus(); } else if (possibleActions.contains(RepayLoans.class)) { @@ -97,10 +99,11 @@ } RadioButtonDialog currentDialog = new RadioButtonDialog (gameUIManager, - LocalText.getText("Select"), + LocalText.getText("1856MergerDialog", action.getCompanyName()), message, options, 0); + currentDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); gameUIManager.setCurrentDialog (currentDialog, action); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ev...@us...> - 2010-08-08 15:20:57
|
Revision: 1373 http://rails.svn.sourceforge.net/rails/?rev=1373&view=rev Author: evos Date: 2010-08-08 15:20:50 +0000 (Sun, 08 Aug 2010) Log Message: ----------- 1835 to use "proper" (JDG) company names Modified Paths: -------------- trunk/18xx/data/1835/CompanyManager.xml trunk/18xx/rails/game/Company.java trunk/18xx/rails/game/CompanyI.java trunk/18xx/rails/game/CompanyManager.java trunk/18xx/rails/game/CompanyManagerI.java trunk/18xx/rails/game/PublicCompany.java trunk/18xx/rails/game/action/BuyCertificate.java trunk/18xx/rails/game/action/BuyTrain.java trunk/18xx/rails/game/action/SellShares.java trunk/18xx/rails/game/specific/_1835/GameManager_1835.java trunk/18xx/rails/game/specific/_1835/OperatingRound_1835.java Modified: trunk/18xx/data/1835/CompanyManager.xml =================================================================== --- trunk/18xx/data/1835/CompanyManager.xml 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/data/1835/CompanyManager.xml 2010-08-08 15:20:50 UTC (rev 1373) @@ -155,29 +155,34 @@ </SpecialProperties> </Company> - <Company name="Bay" longname="Bayerische Eisenbahn" type="Major" startspace="C3" tokens="5" fgColour="FFFFFF" bgColour="0000FF"> + <Company name="BY" longname="Bayerische Eisenbahn" type="Major" startspace="C3" tokens="5" fgColour="FFFFFF" bgColour="0000FF" + alias="Bay"> <Home hex="O15"/> <IfOption name="BYFloatsAt" value="20%"> <Float percentage="20"/> </IfOption> </Company> - <Company name="Sax" longname="Sächsische Eisenbahn" type="Major" startspace="C4" tokens="3" fgColour="FFFFFF" bgColour="FF0000"> + <Company name="SX" longname="Sächsische Eisenbahn" type="Major" startspace="C4" tokens="3" fgColour="FFFFFF" bgColour="FF0000" + alias="Sax"> <Home hex="H16"/> <FirstTrainCloses type="Private" name="LD"/> </Company> - <Company name="Bad" longname="Badische Eisenbahn" type="Major" startspace="B4" available="no" tokens="2" fgColour="FFFFFF" bgColour="808000"> + <Company name="BA" longname="Badische Eisenbahn" type="Major" startspace="B4" available="no" tokens="2" fgColour="FFFFFF" bgColour="808000" + alias="Bad"> <Home hex="L6"/> <Certificate type="President" shares="2"/> <Certificate shares="1" number="6"/> <Certificate shares="2" number="1"/> </Company> - <Company name="Wrt" longname="Württembergische Eisenbahn" type="Major" startspace="B4" available="no" tokens="2" fgColour="000000" bgColour="FFFF00"> + <Company name="WT" longname="Württembergische Eisenbahn" type="Major" startspace="B4" available="no" tokens="2" fgColour="000000" bgColour="FFFF00" + alias="Wrt"> <Home hex="M9"/> <Certificate type="President" shares="2"/> <Certificate shares="1" number="6"/> <Certificate shares="2" number="1"/> </Company> - <Company name="Hes" longname="Hessische Eisenbahn" type="Major" startspace="B4" available="no" tokens="2" fgColour="000000" bgColour="00CC00"> + <Company name="HE" longname="Hessische Eisenbahn" type="Major" startspace="B4" available="no" tokens="2" fgColour="000000" bgColour="00CC00" + alias="Hes"> <Home hex="J8"/> <Certificate type="President" shares="2"/> <Certificate shares="1" number="6"/> @@ -189,13 +194,15 @@ <Certificate shares="2" number="2"/> <Certificate shares="1" number="4"/> </Company> - <Company name="Old" longname="Oldenburgische Eisenbahn" type="Major" startspace="B5" available="no" tokens="2" fgColour="000000" bgColour="C0C0C0"> + <Company name="OL" longname="Oldenburgische Eisenbahn" type="Major" startspace="B5" available="no" tokens="2" fgColour="000000" bgColour="C0C0C0" + alias="Old"> <Home hex="D6"/> <Certificate type="President" shares="2"/> <Certificate shares="2" number="2"/> <Certificate shares="1" number="4"/> </Company> - <Company name="Pr" longname="Preußische Eisenbahn" type="Major" startspace="I4" available="no" tokens="7" fgColour="FFFFFF" bgColour="000000"> + <Company name="PR" longname="Preußische Eisenbahn" type="Major" startspace="I4" available="no" tokens="7" fgColour="FFFFFF" bgColour="000000" + alias="Pr"> <Home hex="E19"/> <ShareUnit percentage="5" sharePriceUnits="2"/> <Float percentage="10"/> Modified: trunk/18xx/rails/game/Company.java =================================================================== --- trunk/18xx/rails/game/Company.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/Company.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -17,6 +17,7 @@ protected String name; protected String longName; + protected String alias = null; // To allow reloading files with old names after name changes protected CompanyTypeI type; protected int companyNumber; // For internal use @@ -160,6 +161,10 @@ return longName; } + public String getAlias() { + return alias; + } + public String getInfoText(){ return infoText; } Modified: trunk/18xx/rails/game/CompanyI.java =================================================================== --- trunk/18xx/rails/game/CompanyI.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/CompanyI.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -53,6 +53,8 @@ public String getInfoText(); + public String getAlias(); + /** * Returns the CompanyType of the Company * Modified: trunk/18xx/rails/game/CompanyManager.java =================================================================== --- trunk/18xx/rails/game/CompanyManager.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/CompanyManager.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -40,6 +40,9 @@ private Map<String, StartPacket> startPacketMap = new HashMap<String, StartPacket>(); + /** A map to enable translating aliases to names */ + protected Map<String, String> aliases = null; + private int numberOfPublicCompanies = 0; protected static Logger log = @@ -140,10 +143,15 @@ new HashMap<String, CompanyI>()); (mCompaniesByTypeAndName.get(type)).put( name, company); + + String alias = company.getAlias(); + if (alias != null) createAlias (alias, name); + } catch (Exception e) { throw new ConfigurationException(LocalText.getText( "ClassCannotBeInstantiated", cType.getClassName()), e); } + } /* Read and configure the start packets */ @@ -182,6 +190,30 @@ } } + private void createAlias (String alias, String name) { + if (aliases == null) { + aliases = new HashMap<String, String>(); + } + aliases.put(alias, name); + } + + public String checkAlias (String alias) { + if (aliases != null && aliases.containsKey(alias)) { + return aliases.get(alias); + } else { + return alias; + } + } + + public String checkAliasInCertId (String certId) { + String[] parts = certId.split("-"); + String realName = checkAlias (parts[0]); + if (!parts[0].equals(realName)) { + return realName + "-" + parts[1]; + } else { + return certId; + } + } /** * @see rails.game.CompanyManagerI#getCompany(java.lang.String) * @@ -191,7 +223,7 @@ } public PublicCompanyI getPublicCompany(String name) { - return mPublicCompanies.get(name); + return mPublicCompanies.get(checkAlias(name)); } public List<PrivateCompanyI> getAllPrivateCompanies() { @@ -202,19 +234,6 @@ return lPublicCompanies; } - /* - public PublicCompanyI getCompanyByName(String name) { - for (int i = 0; i < lPublicCompanies.size(); i++) { - PublicCompany co = (PublicCompany) lPublicCompanies.get(i); - if (name.equalsIgnoreCase(co.getName())) { - return lPublicCompanies.get(i); - } - } - - return null; - } - */ - public List<CompanyTypeI> getCompanyTypes() { return lCompanyTypes; } @@ -222,7 +241,7 @@ public CompanyI getCompany(String type, String name) { if (mCompaniesByTypeAndName.containsKey(type)) { - return (mCompaniesByTypeAndName.get(type)).get(name); + return (mCompaniesByTypeAndName.get(type)).get(checkAlias(name)); } else { return null; } Modified: trunk/18xx/rails/game/CompanyManagerI.java =================================================================== --- trunk/18xx/rails/game/CompanyManagerI.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/CompanyManagerI.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -54,7 +54,9 @@ */ public CompanyI getCompany(String type, String name); - //public PublicCompanyI getCompanyByName(String name); + public String checkAlias (String alias); + public String checkAliasInCertId (String certId); + public List<CompanyTypeI> getCompanyTypes(); public void closeAllPrivates(); Modified: trunk/18xx/rails/game/PublicCompany.java =================================================================== --- trunk/18xx/rails/game/PublicCompany.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/PublicCompany.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -93,7 +93,7 @@ /** Company treasury, holding cash */ protected CashModel treasury = null; - + /** PresidentModel */ protected PresidentModel presidentModel = null; @@ -196,9 +196,6 @@ /** Are the certificates available from the first SR? */ boolean certsAreInitiallyAvailable = true; - /** Privates and Certificates owned by the public company */ - //protected Portfolio portfolio; - /** What percentage of ownership constitutes "one share" */ protected IntegerState shareUnit; @@ -289,13 +286,13 @@ longName = tag.getAttributeAsString("longname", name); infoText = "<html>"+longName; + alias = tag.getAttributeAsString("alias", alias); + /* Configure public company features */ fgHexColour = tag.getAttributeAsString("fgColour", fgHexColour); - //fgColour = new Color(Integer.parseInt(fgHexColour, 16)); fgColour = Util.parseColour(fgHexColour); bgHexColour = tag.getAttributeAsString("bgColour", bgHexColour); - //bgColour = new Color(Integer.parseInt(bgHexColour, 16)); bgColour = Util.parseColour(bgHexColour); floatPerc = tag.getAttributeAsInteger("floatPerc", floatPerc); @@ -1990,5 +1987,5 @@ public String getExtraShareMarks () { return ""; } - + } Modified: trunk/18xx/rails/game/action/BuyCertificate.java =================================================================== --- trunk/18xx/rails/game/action/BuyCertificate.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/action/BuyCertificate.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -143,6 +143,11 @@ GameManagerI gameManager = GameManager.getInstance(); + /* Check for aliases (old company names) */ + CompanyManagerI companyManager = gameManager.getCompanyManager(); + companyName = companyManager.checkAlias (companyName); + certUniqueId = companyManager.checkAliasInCertId(certUniqueId); + if (certUniqueId != null) { // Old style certificate = PublicCertificate.getByUniqueId(certUniqueId); Modified: trunk/18xx/rails/game/action/BuyTrain.java =================================================================== --- trunk/18xx/rails/game/action/BuyTrain.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/action/BuyTrain.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -29,17 +29,17 @@ private boolean forcedBuyIfNoRoute = false; // TODO Remove once route checking exists transient private List<TrainI> trainsForExchange = null; private String[] trainsForExchangeUniqueIds; - + /** Obsolete, but left in for backwards compatibility of saved files */ private boolean forcedExchange = false; - + private boolean presidentMustAddCash = false; private boolean presidentMayAddCash = false; private int presidentCashToAdd = 0; transient private SpecialTrainBuy specialProperty = null; private int specialPropertyId = 0; - + private String extraMessage = null; // User settings @@ -91,7 +91,7 @@ public void setForcedBuyIfNoRoute(boolean hasNoTrains) { this.forcedBuyIfNoRoute = hasNoTrains; } - + public void setExtraMessage (String message) { extraMessage = message; } @@ -119,14 +119,14 @@ return specialProperty != null; } - /** - * To be used for all usage of train, also within this class. - * After reloading the 2nd copy etc. of a train with unlimited quantity, + /** + * To be used for all usage of train, also within this class. + * After reloading the 2nd copy etc. of a train with unlimited quantity, * the train attribute will be null (because readObject() is called and the * train is initiated before the actions have been executed - the second * train is in this case only created after buying the first one). * @return - */ + */ public TrainI getTrain() { if (train == null) { train = GameManager.getInstance().getTrainManager().getTrainByUniqueId(trainUniqueId); @@ -269,11 +269,14 @@ GameManagerI gameManager = GameManager.getInstance(); TrainManager trainManager = gameManager.getTrainManager(); + CompanyManagerI companyManager = gameManager.getCompanyManager(); + fromName = companyManager.checkAlias (fromName); + train = trainManager.getTrainByUniqueId(trainUniqueId); // Note: the 2nd etc. copy of an unlimited quantity train will become null this way. // Set getTrain() for how this is fixed. - + from = gameManager.getPortfolioByName(fromName); if (trainsForExchangeUniqueIds != null && trainsForExchangeUniqueIds.length > 0) { Modified: trunk/18xx/rails/game/action/SellShares.java =================================================================== --- trunk/18xx/rails/game/action/SellShares.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/action/SellShares.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -8,8 +8,7 @@ import java.io.IOException; import java.io.ObjectInputStream; -import rails.game.Bank; -import rails.game.PublicCompanyI; +import rails.game.*; import rails.util.Util; /** @@ -115,7 +114,9 @@ in.defaultReadObject(); + CompanyManagerI companyManager = getCompanyManager(); if (Util.hasValue(companyName)) - company = getCompanyManager().getPublicCompany(companyName); + companyName = companyManager.checkAlias(companyName); + company = companyManager.getPublicCompany(companyName); } } Modified: trunk/18xx/rails/game/specific/_1835/GameManager_1835.java =================================================================== --- trunk/18xx/rails/game/specific/_1835/GameManager_1835.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/specific/_1835/GameManager_1835.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -7,16 +7,16 @@ private RoundI previousRound = null; private Player prFormStartingPlayer = null; - + public static String M2_ID = "M2"; - public static String PR_ID = "Pr"; - public static String OL_ID = "Old"; + public static String PR_ID = "PR"; + public static String OL_ID = "OL"; public static String MS_ID = "MS"; - public static String WT_ID = "Wrt"; - public static String HE_ID = "Hes"; - public static String BA_ID = "Bad"; - public static String SX_ID = "Sax"; - public static String BY_ID = "Bay"; + public static String WT_ID = "WT"; + public static String HE_ID = "HE"; + public static String BA_ID = "BA"; + public static String SX_ID = "SX"; + public static String BY_ID = "BY"; public GameManager_1835() { super(); @@ -47,7 +47,7 @@ } } - + public void startPrussianFormationRound(OperatingRound_1835 or) { interruptedRound = or; @@ -61,12 +61,13 @@ public Player getPrussianFormationStartingPlayer() { return prFormStartingPlayer; } - + + @Override public int getPlayerCertificateLimit(Player player) { int limit = playerCertificateLimit.intValue(); for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { if (company.getTypeName().equalsIgnoreCase("Major") - && company.getPresident() == player + && company.getPresident() == player && player.getPortfolio().getShare(company) >= 80) limit++; } return limit; Modified: trunk/18xx/rails/game/specific/_1835/OperatingRound_1835.java =================================================================== --- trunk/18xx/rails/game/specific/_1835/OperatingRound_1835.java 2010-08-07 14:26:10 UTC (rev 1372) +++ trunk/18xx/rails/game/specific/_1835/OperatingRound_1835.java 2010-08-08 15:20:50 UTC (rev 1373) @@ -1,45 +1,24 @@ package rails.game.specific._1835; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; -import rails.game.Bank; -import rails.game.CashHolder; -import rails.game.DisplayBuffer; -import rails.game.GameDef; -import rails.game.GameManagerI; -import rails.game.GameOption; -import rails.game.OperatingRound; -import rails.game.PhaseI; -import rails.game.Player; -import rails.game.Portfolio; -import rails.game.PrivateCompanyI; -import rails.game.PublicCertificateI; -import rails.game.PublicCompanyI; -import rails.game.ReportBuffer; -import rails.game.StockSpaceI; +import rails.game.*; import rails.game.action.DiscardTrain; import rails.game.action.LayTile; import rails.game.move.CashMove; import rails.game.move.MapChange; -import rails.game.special.ExchangeForShare; -import rails.game.special.SpecialPropertyI; -import rails.game.special.SpecialTileLay; +import rails.game.special.*; import rails.game.state.BooleanState; import rails.util.LocalText; public class OperatingRound_1835 extends OperatingRound { - - private BooleanState needPrussianFormationCall + + private BooleanState needPrussianFormationCall = new BooleanState ("NeedPrussianFormationCall", false); private BooleanState hasLaidExtraOBBTile = new BooleanState ("HasLaidExtraOBBTile", false); - - /** + + /** * Registry of percentage of PR revenue to be denied per player * because of having produced revenue in the same OR. */ @@ -51,6 +30,7 @@ } /** Can a public company operate? (1835 special version) */ + @Override protected boolean canCompanyOperateThisRound (PublicCompanyI company) { if (!company.hasFloated() || company.isClosed()) { return false; @@ -66,6 +46,7 @@ return true; } + @Override protected void privatesPayOut() { int count = 0; for (PrivateCompanyI priv : companyManager.getAllPrivateCompanies()) { @@ -79,8 +60,8 @@ Bank.format(revenue), priv.getName())); new CashMove(bank, recipient, revenue); - - /* Register black private equivalent PR share value + + /* Register black private equivalent PR share value * so it can be subtracted if PR operates */ if (recipient instanceof Player && priv.getSpecialProperties() != null && priv.getSpecialProperties().size() > 0) { @@ -92,7 +73,7 @@ Player player = (Player) recipient; addIncomeDenialShare (player, share); } - + } } } @@ -103,11 +84,11 @@ } private void addIncomeDenialShare (Player player, int share) { - + if (!deniedIncomeShare.containsKey(player)) { new MapChange<Player, Integer> (deniedIncomeShare, player, share); } else { - new MapChange<Player, Integer> (deniedIncomeShare, player, + new MapChange<Player, Integer> (deniedIncomeShare, player, share + deniedIncomeShare.get(player)); } //log.debug("+++ Denied "+share+"% share of PR income to "+player.getName()); @@ -117,10 +98,11 @@ * A special rule applies to 1835 to prevent black privates and minors providing * income twice during an OR. */ + @Override protected Map<CashHolder, Integer> countSharesPerRecipient () { - + Map<CashHolder, Integer> sharesPerRecipient = super.countSharesPerRecipient(); - + if (operatingCompany.getName().equalsIgnoreCase(GameManager_1835.PR_ID)) { for (Player player : deniedIncomeShare.keySet()) { if (!sharesPerRecipient.containsKey(player)) continue; @@ -131,19 +113,20 @@ player.getName(), share, GameManager_1835.PR_ID)); - + } } - + return sharesPerRecipient; } - /** - * Register black minors as having operated + /** + * Register black minors as having operated * for the purpose of denying income after conversion to a PR share */ + @Override protected void initTurn() { - + super.initTurn(); List<SpecialPropertyI> sps = operatingCompany.getSpecialProperties(); @@ -152,32 +135,32 @@ addIncomeDenialShare (operatingCompany.getPresident(), efs.getShare()); } } - + @Override public void resume() { - + PublicCompanyI prussian = companyManager.getPublicCompany(GameManager_1835.PR_ID); - + if (prussian.hasFloated() && !prussian.hasOperated() // PR has just started. Check if it can operate this round - // That's only the case if M1 has just bought + // That's only the case if M1 has just bought // the first 4-train or 4+4-train && operatingCompany == companyManager.getPublicCompany("M1")) { log.debug("M2 has not operated: PR can operate"); - + // Insert the Prussian before the first major company // with a lower current price that hoas not yet operated // and isn't currently operating - + int index = 0; int operatingCompanyIndex = getOperatingCompanyIndex(); for (PublicCompanyI company : setOperatingCompanies()) { if (index > operatingCompanyIndex - && company.hasStockPrice() + && company.hasStockPrice() && company.hasFloated() && !company.isClosed() && company != operatingCompany - && company.getCurrentSpace().getPrice() + && company.getCurrentSpace().getPrice() < prussian.getCurrentSpace().getPrice()) { log.debug("PR will operate before "+company.getName()); break; @@ -189,15 +172,16 @@ log.debug("PR will operate at order position "+index); } else { - + log.debug("M2 has operated: PR cannot operate"); - + } - + guiHints.setCurrentRoundType(getClass()); super.resume(); } - + + @Override protected void setSpecialTileLays() { /* Special-property tile lays */ @@ -207,16 +191,17 @@ for (SpecialTileLay stl : getSpecialProperties(SpecialTileLay.class)) { if (stl.isExtra() || !currentNormalTileLays.isEmpty()) { - + // Exclude the second OBB free tile if the first was laid in this round if (stl.getLocationNameString().matches("M1(7|9)") && hasLaidExtraOBBTile.booleanValue()) continue; - + currentSpecialTileLays.add(new LayTile(stl)); } } } + @Override public boolean layTile(LayTile action) { // The extra OBB tiles may not both be laid in the same round @@ -233,17 +218,18 @@ return false; } } - + boolean result = super.layTile(action); - + if (result && action.getSpecialProperty() != null && action.getSpecialProperty().getLocationNameString().matches("M1(5|7)")) { hasLaidExtraOBBTile.set(true); } - + return result; } + @Override protected void newPhaseChecks() { PhaseI phase = getCurrentPhase(); if (phase.getName().equals("4") || phase.getName().equals("4+4") @@ -259,13 +245,14 @@ } } } - + + @Override public boolean discardTrain(DiscardTrain action) { - + boolean result = super.discardTrain(action); - if (result && getStep() == GameDef.OrStep.BUY_TRAIN + if (result && getStep() == GameDef.OrStep.BUY_TRAIN && needPrussianFormationCall.booleanValue()) { - // Do the postponed formation calls + // Do the postponed formation calls ((GameManager_1835)gameManager).startPrussianFormationRound (this); needPrussianFormationCall.set(false); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ev...@us...> - 2010-08-10 19:39:06
|
Revision: 1374 http://rails.svn.sourceforge.net/rails/?rev=1374&view=rev Author: evos Date: 2010-08-10 19:39:00 +0000 (Tue, 10 Aug 2010) Log Message: ----------- Fixed bug that allowed 1835 share selling of unfloated companies. Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/rails/game/ShareSellingRound.java trunk/18xx/rails/game/StockRound.java trunk/18xx/rails/game/TreasuryShareRound.java trunk/18xx/rails/game/specific/_1835/PrussianFormationRound.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/LocalisedText.properties 2010-08-10 19:39:00 UTC (rev 1374) @@ -495,6 +495,7 @@ RouteAwareness=support for tile and token lays RunsWithBorrowedTrain={0} runs with a borrowed {1}-train and must withhold revenue RustsTrains=Rusts {0}-trains +SaleNotAllowed=Selling shares of company {0} is not allowed SAVE=Save SAVEAS=Save As ... SaveFailed=Save failed, reason: {0} Modified: trunk/18xx/rails/game/ShareSellingRound.java =================================================================== --- trunk/18xx/rails/game/ShareSellingRound.java 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/rails/game/ShareSellingRound.java 2010-08-10 19:39:00 UTC (rev 1374) @@ -108,8 +108,8 @@ */ for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { - // Can't sell shares that have no price - if (!company.hasStarted()) continue; + // Check if shares of this company can be sold at all + if (!mayPlayerSellShareOfCompany(company)) continue; share = maxShareToSell = playerPortfolio.getShare(company); if (maxShareToSell == 0) continue; @@ -231,6 +231,12 @@ break; } + // May player sell this company + if (!mayPlayerSellShareOfCompany(company)) { + errMsg = LocalText.getText("SaleNotAllowed", companyName); + break; + } + // The player must have the share(s) if (portfolio.getShare(company) < numberToSell) { errMsg = LocalText.getText("NoShareOwned"); Modified: trunk/18xx/rails/game/StockRound.java =================================================================== --- trunk/18xx/rails/game/StockRound.java 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/rails/game/StockRound.java 2010-08-10 19:39:00 UTC (rev 1374) @@ -358,13 +358,9 @@ */ for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { - // Can't sell shares that have no price - if (!company.hasStarted() || !company.hasStockPrice()) continue; + // Check if shares of this company can be sold at all + if (!mayPlayerSellShareOfCompany(company)) continue; - // In some games, can't sell shares if not operated - if (company.mustHaveOperatedToTradeShares() - && !company.hasOperated()) continue; - share = maxShareToSell = playerPortfolio.getShare(company); if (maxShareToSell == 0) continue; @@ -957,6 +953,12 @@ break; } + // May player sell this company + if (!mayPlayerSellShareOfCompany(company)) { + errMsg = LocalText.getText("SaleNotAllowed", companyName); + break; + } + // The player must have the share(s) if (portfolio.getShare(company) < numberToSell) { errMsg = LocalText.getText("NoShareOwned"); @@ -1395,6 +1397,19 @@ return true; } + public boolean mayPlayerSellShareOfCompany(PublicCompanyI company) { + + // Can't sell shares that have no price + if (!company.hasStarted() || !company.hasStockPrice()) return false; + + // In some games, can't sell shares if not operated + if (noSaleIfNotOperated() + && !company.hasOperated()) return false; + + return true; + } + + /** * Can the current player do any buying? * @@ -1408,10 +1423,10 @@ protected boolean isPlayerOverLimits(Player player) { return (isPlayerOverLimitsDetail(player) != null); } - + protected String isPlayerOverLimitsDetail(Player player) { StringBuffer violations = new StringBuffer(); - + // Over the total certificate hold Limit? if (player.getPortfolio().getCertificateCount() > gameManager.getPlayerCertificateLimit(player)) { violations.append(LocalText.getText("ExceedCertificateLimitTotal", @@ -1423,7 +1438,7 @@ // Over the hold limit of any company? for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { if (company.hasStarted() && company.hasStockPrice() - && !checkAgainstHoldLimit(player, company, 0)) { + && !checkAgainstHoldLimit(player, company, 0)) { violations.append(LocalText.getText("ExceedCertificateLimitCompany", company.getName(), player.getPortfolio().getShare(company), Modified: trunk/18xx/rails/game/TreasuryShareRound.java =================================================================== --- trunk/18xx/rails/game/TreasuryShareRound.java 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/rails/game/TreasuryShareRound.java 2010-08-10 19:39:00 UTC (rev 1374) @@ -71,7 +71,8 @@ possibleActions.clear(); - if (!operatingCompany.hasOperated()) return true; + if (operatingCompany.mustHaveOperatedToTradeShares() + && !operatingCompany.hasOperated()) return true; if (!hasSold.booleanValue()) setBuyableCerts(); if (!hasBought.booleanValue()) setSellableCerts(); Modified: trunk/18xx/rails/game/specific/_1835/PrussianFormationRound.java =================================================================== --- trunk/18xx/rails/game/specific/_1835/PrussianFormationRound.java 2010-08-08 15:20:50 UTC (rev 1373) +++ trunk/18xx/rails/game/specific/_1835/PrussianFormationRound.java 2010-08-10 19:39:00 UTC (rev 1374) @@ -1,8 +1,6 @@ package rails.game.specific._1835; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; import rails.common.GuiDef; import rails.game.*; @@ -23,7 +21,7 @@ private boolean forcedStart; private boolean mergePr; private boolean forcedMerge; - + private List<CompanyI> foldablePrePrussians; private enum Step { @@ -36,7 +34,7 @@ private static String PR_ID = GameManager_1835.PR_ID; private static String M2_ID = GameManager_1835.M2_ID; - + public PrussianFormationRound (GameManagerI gameManager) { super (gameManager); @@ -60,7 +58,7 @@ +" mergePr="+mergePr+" forcedMerge="+forcedMerge); step = startPr ? Step.START : Step.MERGE; - + if (step == Step.START) { m2 = companyManager.getPublicCompany(M2_ID); setCurrentPlayer(m2.getPresident()); @@ -70,7 +68,7 @@ step = Step.MERGE; } } - + if (step == Step.MERGE) { startingPlayer = ((GameManager_1835)gameManager).getPrussianFormationStartingPlayer(); @@ -116,9 +114,9 @@ } else if (step == Step.MERGE) { possibleActions.add(new FoldIntoPrussian(foldablePrePrussians)); - + } else if (step == Step.DISCARD_TRAINS) { - + if (prussian.getNumberOfTrains() > prussian.getTrainLimit(getCurrentPhase().getIndex())) { possibleActions.add(new DiscardTrain(prussian, prussian.getPortfolio().getUniqueTrains(), true)); @@ -149,14 +147,14 @@ } } } - + @Override protected boolean processGameSpecificAction(PossibleAction action) { if (action instanceof FoldIntoPrussian) { FoldIntoPrussian a = (FoldIntoPrussian) action; - + if (step == Step.START) { if (!startPrussian(a)) { finishRound(); @@ -164,29 +162,29 @@ step = Step.MERGE; findNextMergingPlayer(false); } - + } else if (step == Step.MERGE) { - + mergeIntoPrussian (a); - + } - + return true; - + } else if (action instanceof DiscardTrain) { - + discardTrain ((DiscardTrain) action); return true; - + } else { return false; } } protected boolean findNextMergingPlayer(boolean skipCurrentPlayer) { - + while (true) { - + if (skipCurrentPlayer) { setNextPlayer(); if (getCurrentPlayer() == startingPlayer) { @@ -198,13 +196,13 @@ return false; } } - + setFoldablePrePrussians(); if (!foldablePrePrussians.isEmpty()) return true; skipCurrentPlayer = true; } } - + private boolean startPrussian (FoldIntoPrussian action) { // Validate @@ -237,9 +235,9 @@ return folding; } - + private void executeStartPrussian (boolean display) { - + prussian.start(); String message = LocalText.getText("START_MERGED_COMPANY", PR_ID, @@ -259,7 +257,7 @@ List<CompanyI> folded = action.getFoldedCompanies(); boolean folding = folded != null && !folded.isEmpty(); - + while (folding) { // TODO Some validation needed break; @@ -277,7 +275,7 @@ // Execute if (folding) executeExchange (folded, false, false); - + findNextMergingPlayer(true); return folding; @@ -320,11 +318,11 @@ company.getName()); ReportBuffer.add(message); if (display) DisplayBuffer.add (message); - + if (company instanceof PublicCompanyI) { PublicCompanyI minor = (PublicCompanyI) company; - + // Replace the home token BaseToken token = (BaseToken) minor.getTokens().get(0); City city = (City) token.getHolder(); @@ -337,15 +335,15 @@ city.getName()); ReportBuffer.add(message); if (display) DisplayBuffer.add (message); - + prussian.layBaseToken(hex, 0); } - + // Move any cash if (minor.getCash() > 0) { new CashMove (minor, prussian, minor.getCash()); } - + // Move any trains List<TrainI> trains = new ArrayList<TrainI> (minor.getPortfolio().getTrainList()); for (TrainI train : trains) { @@ -411,24 +409,26 @@ // This always finished this type of round finishRound(); - + return true; } + @Override protected void finishRound() { if (prussian.hasStarted()) prussian.checkPresidency(); + prussian.setOperated(); // To allow immediate share selling super.finishRound(); } public static boolean prussianIsComplete(GameManagerI gameManager) { - + for (PublicCompanyI company : gameManager.getAllPublicCompanies()) { if (!company.getTypeName().equalsIgnoreCase("Minor")) continue; - if (!company.isClosed()) return false; + if (!company.isClosed()) return false; } return true; } - + @Override public String toString() { return "1835 PrussianFormationRound"; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-10 23:08:15
|
Revision: 1378 http://rails.svn.sourceforge.net/rails/?rev=1378&view=rev Author: stefanfrey Date: 2010-08-10 23:08:08 +0000 (Tue, 10 Aug 2010) Log Message: ----------- Added dynamic (linked to game situations) report window Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/data/Properties.xml trunk/18xx/data/profiles/default.profile trunk/18xx/rails/game/ReportBuffer.java trunk/18xx/rails/game/move/MoveStack.java trunk/18xx/rails/ui/swing/GameUIManager.java trunk/18xx/rails/ui/swing/ORUIManager.java trunk/18xx/rails/ui/swing/ORWindow.java trunk/18xx/rails/ui/swing/ReportWindow.java trunk/18xx/rails/ui/swing/StatusWindow.java Added Paths: ----------- trunk/18xx/rails/ui/swing/AbstractReportWindow.java trunk/18xx/rails/ui/swing/ReportWindowDynamic.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/LocalisedText.properties 2010-08-10 23:08:08 UTC (rev 1378) @@ -168,8 +168,9 @@ Config.label.report.directory=Report directory Config.label.report.filename.date_time_pattern=Report filename date pattern Config.label.report.filename.extension=Report filename extension +Config.label.report.window.editable=Report window editable Config.label.report.window.open=Report window open -Config.label.report.window.editable=Report window editable +Config.label.report.window.type=Report window type Config.label.route.colour.1=Route color for first train Config.label.route.colour.2=Route color for second train Config.label.route.colour.3=Route color for third train @@ -185,9 +186,9 @@ Config.section.Format=Format/Colors Config.section.General=General Config.section.Log=Log -Config.section.Map=Map +Config.section.Font=Fonts Config.section.Save=Save -Config.section.UI=Windows/Fonts +Config.section.UI=Map/Report ConfirmToken=Press Lay Token to confirm token, click another city hex, or press the No Token button. connected=connected CorrectCashAddMoney=CORRECTION: {0} receives {1} from the bank @@ -485,6 +486,8 @@ RepayLoans=Repay loan(s) RepayLoan=Repay {0} loan(s) of {1} for {2} REPORT=Report Window +REPORT_MOVE_BACKWARD=<< +REPORT_MOVE_FORWARD=>> REVENUE=Revenue RevenueCalculation=support for revenue calculation RevenueStations=, Cities = {0}, Towns = {1} Modified: trunk/18xx/data/Properties.xml =================================================================== --- trunk/18xx/data/Properties.xml 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/data/Properties.xml 2010-08-10 23:08:08 UTC (rev 1378) @@ -19,10 +19,7 @@ <Property name="save.recovery.active" type="BOOLEAN" /> <Property name="save.recovery.filepath" type="FILE" /> </Section> - <Section name="UI"> - <Property name="report.window.open" type="BOOLEAN" /> - <Property name="report.window.editable" type="BOOLEAN" /> - <Property name="stockchart.window.open" type="BOOLEAN" /> + <Section name="Font"> <Property name="font.ui.scale" type="PERCENT" initClass="rails.ui.swing.GameUIManager" initMethod="updateUILookAndFeel" initParameter="no" /> <Property name="font.ui.name" type="FONT" @@ -30,9 +27,13 @@ <Property name="font.ui.style" type="LIST" values="plain,bold" initClass="rails.ui.swing.GameUIManager" initMethod="updateUILookAndFeel" initParameter="no" /> </Section> - <Section name="Map"> + <Section name="UI"> <Property name="map.autoscroll" type="BOOLEAN" /> <Property name="map.zoomstep" type="INTEGER" /> + <Property name="report.window.type" type="LIST" values="static,dynamic" /> + <Property name="report.window.open" type="BOOLEAN" /> + <Property name="report.window.editable" type="BOOLEAN" /> + <Property name="stockchart.window.open" type="BOOLEAN" /> </Section> <Section name="Format"> <Property name="money_format" type="STRING" /> Modified: trunk/18xx/data/profiles/default.profile =================================================================== --- trunk/18xx/data/profiles/default.profile 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/data/profiles/default.profile 2010-08-10 23:08:08 UTC (rev 1378) @@ -14,6 +14,7 @@ save.recovery.filepath=18xx_autosave.rails ### Panel UI +report.window.type=dynamic report.window.open=yes report.window.editable=no stockchart.window.open=yes Modified: trunk/18xx/rails/game/ReportBuffer.java =================================================================== --- trunk/18xx/rails/game/ReportBuffer.java 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/rails/game/ReportBuffer.java 2010-08-10 23:08:08 UTC (rev 1378) @@ -9,6 +9,7 @@ import org.apache.log4j.Logger; import rails.util.Config; +import rails.util.LocalText; import rails.util.Util; /** @@ -22,16 +23,69 @@ * */ public final class ReportBuffer { + + /** defines the collection of data that is stored in the report buffer */ + private class ReportItem { + private List<String> messages = new ArrayList<String>(); + private int index = 0; + private Player player = null; + private RoundI round = null; + + private void addMessage(String message) { + // ignore undos and redos + messages.add(message); + } + + private String getMessages() { + StringBuffer s = new StringBuffer(); + for (String message:messages) { + s.append(message); + } + return s.toString(); + } + + private String toHtml() { + StringBuffer s = new StringBuffer(); + boolean init = true; + for (String message:messages) { + if (init) { + s.append("<a href=http://rails:" + index + ">"); + s.append(message); + s.append("</a><br>"); + init = false; + } else { + s.append(message + "<br>"); + } + } + return s.toString(); + } + + public String toString() { + StringBuffer s = new StringBuffer(); + s.append("ReportItem for MoveStackIndex = " + index); + s.append(", player = " + player); + s.append(", round = " + round); + s.append(", messages = "); s.append(getMessages()); + return s.toString(); + } + } + + /** * A stack for displaying messages in the Log Window. Such messages are * intended to record the progress of the rails.game and can be used as a * rails.game report. */ - private List<String> reportQueue = new ArrayList<String>(); + private List<String> reportQueue = new ArrayList<String> (); /** Another stack for messages that must "wait" for other messages */ private List<String> waitQueue = new ArrayList<String> (); + /** Archive stack, the integer index corresponds with the moveset items */ + private SortedMap<Integer, ReportItem> reportItems = new TreeMap<Integer, ReportItem>(); + /** Indicator string to find the active message position in the parsed html document */ + public static final String ACTIVE_MESSAGE_INDICATOR = "(**)"; + private String reportPathname = null; private PrintWriter report = null; @@ -42,6 +96,7 @@ private static String reportDirectory = null; private static final String DEFAULT_DTS_PATTERN = "yyyyMMdd_HHmm"; private static final String DEFAULT_REPORT_EXTENSION = "txt"; + static { reportDirectory = Config.get("report.directory").trim(); @@ -53,15 +108,16 @@ public ReportBuffer() { + reportItems.put(0, new ReportItem()); if (!initialQueue.isEmpty()) { for (String s : initialQueue) { - addMessage (s); + addMessage(s, -1); // start of the game } initialQueue.clear(); } } - + private List<String> getReportQueue() { return reportQueue; } @@ -70,11 +126,15 @@ reportQueue.clear(); } - private void addMessage (String message) { + private void addMessage(String message, int moveStackIndex) { if (message != null) { - if (message.equals("")) + if (message.equals("")) { message = "---"; // workaround for testing + } + // legacy report queue reportQueue.add(message); + // new queue + reportItems.get(moveStackIndex).addMessage(message); /* Also log the message */ if (message.length() > 0) log.info(message); /* Also write it to the report file, if requested */ @@ -130,8 +190,58 @@ wantReport = false; } } + + private void addReportItem(int index, Player player, RoundI round) { + ReportItem newItem = new ReportItem(); + newItem.index = index; + newItem.player = player; + newItem.round = round; + reportItems.put(index, newItem); + Set<Integer> deleteIndices = new HashSet<Integer> + (reportItems.tailMap(index + 1).keySet()); + for (Integer i:deleteIndices) { + reportItems.remove(i); + } + } + /** Movestack calls the report item to update */ + public static void createNewReportItem(int index) { + // check availablity + GameManagerI gm = GameManager.getInstance(); + ReportBuffer instance = null; + if (gm != null) { + instance = gm.getReportBuffer(); + } + if (gm == null || instance == null) { + return; + } + // all there, add new report item + Player player = gm.getCurrentPlayer(); + RoundI round = gm.getCurrentRound(); + instance.addReportItem(index, player, round); + } + + public static String getReportItems() { + int index = GameManager.getInstance().getMoveStack().getIndex(); + ReportBuffer instance = getInstance(); + + StringBuffer s = new StringBuffer(); + s.append("<html>"); + for (ReportItem item:instance.reportItems.values()) { + if (item.index == index-1) { + s.append("<p bgcolor=Yellow>" + ACTIVE_MESSAGE_INDICATOR) ; + } + s.append(item.toHtml()); + if (item.index == (index-1)) { + s.append("</p><"); + } + } + s.append("</html>"); + + return s.toString(); + } + /** Get the current log buffer, and clear it */ public static String get() { ReportBuffer instance = getInstance(); @@ -146,17 +256,25 @@ return result.toString(); } - + /** Add a message to the log buffer (and display it on the console) */ public static void add(String message) { GameManagerI gm = GameManager.getInstance(); ReportBuffer instance = null; - if (gm != null) instance = gm.getReportBuffer(); - if (gm == null || instance == null) { + if (gm != null) { + instance = gm.getReportBuffer(); + } + if (instance == null) { // Queue in a static buffer until the instance is created initialQueue.add(message); } else { - instance.addMessage(message); + // ignore undo and redo for the new reportItems + if (message.equals(LocalText.getText("UNDO")) || message.equals(LocalText.getText("REDO"))) { + instance.reportQueue.add(message); + return; + } + int moveStackIndex = gm.getMoveStack().getIndex(); + instance.addMessage(message, moveStackIndex); } } @@ -169,7 +287,7 @@ else return instance.getReportQueue(); } - + /** clear the current buffer */ public static void clear() { ReportBuffer instance = getInstance(); @@ -184,18 +302,17 @@ return GameManager.getInstance().getReportBuffer(); } - - - public static void addWaiting (String string) { - getInstance().waitQueue.add (string); + public static void addWaiting (String message) { + getInstance().waitQueue.add(message); } public static void getAllWaiting () { ReportBuffer instance = getInstance(); for (String message : instance.waitQueue) { - instance.addMessage (message); + add(message); } instance.waitQueue.clear(); } + } Modified: trunk/18xx/rails/game/move/MoveStack.java =================================================================== --- trunk/18xx/rails/game/move/MoveStack.java 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/rails/game/move/MoveStack.java 2010-08-10 23:08:08 UTC (rev 1378) @@ -68,6 +68,7 @@ moveStack.add(currentMoveSet); lastIndex++; currentMoveSet = null; + ReportBuffer.createNewReportItem(this.getIndex()); return true; } } @@ -112,7 +113,7 @@ MoveSet undoAction; do { ReportBuffer.add(LocalText.getText("UNDO")); - // log.debug ("MoveStack undo index is "+lastIndex); + log.debug ("MoveStack undo index is "+lastIndex); undoAction = moveStack.get(lastIndex--); undoAction.unexecute(); } while (undoAction.isLinkedToPreviousMove()); @@ -129,14 +130,13 @@ public boolean redoMoveSet () { if (currentMoveSet == null && lastIndex < moveStack.size() - 1) { MoveSet redoAction; - redoAction= moveStack.get(++lastIndex); do { + redoAction = moveStack.get(++lastIndex); ReportBuffer.add(LocalText.getText("REDO")); + log.debug ("MoveStack redo index is "+lastIndex); redoAction.reexecute(); if (lastIndex == moveStack.size() - 1) break; - redoAction= moveStack.get(++lastIndex); - } while (redoAction.isLinkedToPreviousMove()); - // log.debug ("MoveStack redo index is "+lastIndex); + } while (moveStack.get(lastIndex + 1).isLinkedToPreviousMove()); return true; } else { log.error("Invalid redo: index=" + lastIndex + " size=" @@ -164,5 +164,21 @@ public int getIndex() { return lastIndex + 1; } - + + /** + * undo/redo to a given moveStack index + */ + public boolean gotoIndex(int index) { + if (getIndex() == index) return true; + else if (getIndex() < index) { + while (getIndex() < index) { + if (!redoMoveSet()) return false; + } + } else { + while (getIndex() > index) { + if (!undoMoveSet(true)) return false; + } + }; + return true; + } } Added: trunk/18xx/rails/ui/swing/AbstractReportWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/AbstractReportWindow.java (rev 0) +++ trunk/18xx/rails/ui/swing/AbstractReportWindow.java 2010-08-10 23:08:08 UTC (rev 1378) @@ -0,0 +1,34 @@ +package rails.ui.swing; + +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.JFrame; + +import rails.util.Config; +import rails.util.LocalText; + +public abstract class AbstractReportWindow extends JFrame { + private static final long serialVersionUID = 1L; + + public void init() { + setSize(400, 400); + setLocation(600, 400); + setTitle(LocalText.getText("GameReportTitle")); + + final JFrame frame = this; + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + StatusWindow.uncheckMenuItemBox(StatusWindow.REPORT_CMD); + frame.dispose(); + } + }); + setVisible("yes".equalsIgnoreCase(Config.get("report.window.open"))); + } + + public abstract void updateLog(); + + public abstract void scrollDown(); + +} \ No newline at end of file Property changes on: trunk/18xx/rails/ui/swing/AbstractReportWindow.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: trunk/18xx/rails/ui/swing/GameUIManager.java =================================================================== --- trunk/18xx/rails/ui/swing/GameUIManager.java 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/rails/ui/swing/GameUIManager.java 2010-08-10 23:08:08 UTC (rev 1378) @@ -29,7 +29,7 @@ public StockChart stockChart; public StatusWindow statusWindow; - public ReportWindow reportWindow; + public AbstractReportWindow reportWindow; public ConfigWindow configWindow; public ORUIManager orUIManager; public ORWindow orWindow; // TEMPORARY @@ -157,7 +157,11 @@ imageLoader = new ImageLoader(); stockChart = new StockChart(this); - reportWindow = new ReportWindow(gameManager); + if (Config.get("report.window.type").equalsIgnoreCase("static")) { + reportWindow = new ReportWindow(gameManager); + } else { + reportWindow = new ReportWindowDynamic(this); + } orWindow = new ORWindow(this); orUIManager = orWindow.getORUIManager(); @@ -223,7 +227,7 @@ // Follow-up the result log.debug("==Result from server: " + result); - reportWindow.addLog(); + reportWindow.updateLog(); /* if (DisplayBuffer.getAutoDisplay()) { if (displayServerMessage()) { @@ -449,6 +453,7 @@ } updateStatus(activeWindow); + } /** Stub, to be overridden in subclasses for special round types */ Modified: trunk/18xx/rails/ui/swing/ORUIManager.java =================================================================== --- trunk/18xx/rails/ui/swing/ORUIManager.java 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/rails/ui/swing/ORUIManager.java 2010-08-10 23:08:08 UTC (rev 1378) @@ -472,7 +472,7 @@ } - gameUIManager.reportWindow.addLog(); + gameUIManager.reportWindow.updateLog(); } /** Stub, can be overridden in subclasses */ Modified: trunk/18xx/rails/ui/swing/ORWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ORWindow.java 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/rails/ui/swing/ORWindow.java 2010-08-10 23:08:08 UTC (rev 1378) @@ -101,7 +101,7 @@ } }); - gameUIManager.reportWindow.addLog(); + gameUIManager.reportWindow.updateLog(); } public ORUIManager getORUIManager() { Modified: trunk/18xx/rails/ui/swing/ReportWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/ReportWindow.java 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/rails/ui/swing/ReportWindow.java 2010-08-10 23:08:08 UTC (rev 1378) @@ -25,7 +25,7 @@ * This is the UI for the LogWindow. It displays logged messages to the user * during the rails.game. */ -public class ReportWindow extends JFrame implements ActionListener, KeyListener { +public class ReportWindow extends AbstractReportWindow implements ActionListener, KeyListener { private static final long serialVersionUID = 1L; private JTextArea reportText; @@ -156,23 +156,16 @@ setContentPane(messagePanel); - setSize(400, 400); - setLocation(600, 400); - setTitle(LocalText.getText("GameReportTitle")); - - final JFrame frame = this; - addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - StatusWindow.uncheckMenuItemBox(StatusWindow.REPORT_CMD); - frame.dispose(); - } - }); addKeyListener(this); - setVisible("yes".equalsIgnoreCase(Config.get("report.window.open"))); + + // default report window settings + super.init(); } - public void addLog() { + /* (non-Javadoc) + * @see rails.ui.swing.ReportWindowI#updateLog() + */ + public void updateLog() { String newText = ReportBuffer.get(); if (newText.length() > 0) { reportText.append(newText); Added: trunk/18xx/rails/ui/swing/ReportWindowDynamic.java =================================================================== --- trunk/18xx/rails/ui/swing/ReportWindowDynamic.java (rev 0) +++ trunk/18xx/rails/ui/swing/ReportWindowDynamic.java 2010-08-10 23:08:08 UTC (rev 1378) @@ -0,0 +1,163 @@ +package rails.ui.swing; + +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.net.URL; +import java.util.List; + +import javax.swing.JEditorPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.UIManager; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.html.HTMLDocument; + +import org.apache.log4j.Logger; + +import rails.game.ReportBuffer; +import rails.game.action.GameAction; +import rails.game.action.PossibleActions; +import rails.game.move.MoveStack; +import rails.ui.swing.elements.ActionButton; +import rails.util.LocalText; + +/** + * Dynamic Report window that acts as linked game history + */ + +public class ReportWindowDynamic extends AbstractReportWindow implements ActionListener, HyperlinkListener { + private static final long serialVersionUID = 1L; + + private GameUIManager gameUIManager; + + private JScrollPane reportPane; + private JEditorPane editorPane; + + private JPanel buttonPanel; + private ActionButton forwardButton; + private ActionButton backwardButton; + + protected static Logger log = + Logger.getLogger(ReportWindowDynamic.class.getPackage().getName()); + + public ReportWindowDynamic(GameUIManager gameUIManager) { + super(); + this.gameUIManager = gameUIManager; + init(); + } + + public void init() { + editorPane = new JEditorPane(); + editorPane.setEditable(false); + editorPane.setContentType("text/html"); + editorPane.addHyperlinkListener(this); + editorPane.setOpaque(false); + editorPane.setBorder(null); + + // add a CSS rule to force body tags to use the default label font + // instead of the value in javax.swing.text.html.default.csss + Font font = UIManager.getFont("Label.font"); + String bodyRule = "body { font-family: " + font.getFamily() + "; " + + "font-size: " + font.getSize() + "pt; }"; + ((HTMLDocument)editorPane.getDocument()).getStyleSheet().addRule(bodyRule); + + reportPane = new JScrollPane(editorPane); + add(reportPane, "Center"); + + buttonPanel = new JPanel(); + add(buttonPanel, "South"); + + + backwardButton = new ActionButton(LocalText.getText("REPORT_MOVE_BACKWARD")); + backwardButton.addActionListener(this); + buttonPanel.add(backwardButton); + + forwardButton = new ActionButton(LocalText.getText("REPORT_MOVE_FORWARD")); + forwardButton.addActionListener(this); + buttonPanel.add(forwardButton); + + super.init(); + } + + @Override + public void updateLog() { + // set the content of the pane to the current + editorPane.setText(ReportBuffer.getReportItems()); + scrollDown(); + + forwardButton.setEnabled(false); + backwardButton.setEnabled(true); + List<GameAction> gameActions = PossibleActions.getInstance().getType(GameAction.class); + for (GameAction action:gameActions) { + switch (action.getMode()) { + case GameAction.UNDO: + case GameAction.FORCED_UNDO: + backwardButton.setPossibleAction(action); + backwardButton.setEnabled(true); + break; + case GameAction.REDO: + forwardButton.setPossibleAction(action); + forwardButton.setEnabled(true); + break; + } + } + } + + @Override + public void scrollDown() { + // only set caret if visible + if (!this.isVisible()) return; + + // find the active message in the parsed html code (not identical to the position in the html string) + // thus the message indicator is used + int caretPosition; + try{ + String docText = editorPane.getDocument().getText(0, editorPane.getDocument().getLength()); + caretPosition = docText.indexOf(ReportBuffer.ACTIVE_MESSAGE_INDICATOR); + } catch (BadLocationException e){ + caretPosition = -1; + }; + final int caretPositionStore = caretPosition; + if (caretPosition != -1) { + editorPane.setCaretPosition(caretPositionStore); + } + } + + public void actionPerformed(ActionEvent e) { + ActionButton button = (ActionButton)e.getSource(); + GameAction action = (GameAction)button.getPossibleActions().get(0); + gameUIManager.processOnServer(action); + } + + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + URL url = e.getURL(); +// String protocol = e.getURL().getProtocol(); + int index = url.getPort(); + gotoIndex(index + 1); + } + } + + private void gotoIndex(int index) { + MoveStack stack = gameUIManager.getGameManager().getMoveStack(); + int currentIndex = stack.getIndex(); + if (index > currentIndex) { // move forward + if (index != currentIndex +1) { + stack.gotoIndex(index - 1); + } + GameAction action = new GameAction(GameAction.REDO); + gameUIManager.processOnServer(action); + } else if (index < currentIndex) { // move backward + if (index != currentIndex - 1) { + stack.gotoIndex(index + 1); + } + GameAction action = new GameAction(GameAction.FORCED_UNDO); + gameUIManager.processOnServer(action); + } + } + +} Property changes on: trunk/18xx/rails/ui/swing/ReportWindowDynamic.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: trunk/18xx/rails/ui/swing/StatusWindow.java =================================================================== --- trunk/18xx/rails/ui/swing/StatusWindow.java 2010-08-10 21:52:19 UTC (rev 1377) +++ trunk/18xx/rails/ui/swing/StatusWindow.java 2010-08-10 23:08:08 UTC (rev 1378) @@ -602,6 +602,7 @@ System.exit(0); } else if (command.equals(REPORT_CMD)) { gameUIManager.reportWindow.setVisible(((JMenuItem) actor.getSource()).isSelected()); + gameUIManager.reportWindow.scrollDown(); return; } else if (command.equals(MARKET_CMD)) { gameUIManager.stockChart.setVisible(((JMenuItem) actor.getSource()).isSelected()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-12 18:46:15
|
Revision: 1380 http://rails.svn.sourceforge.net/rails/?rev=1380&view=rev Author: stefanfrey Date: 2010-08-12 18:46:08 +0000 (Thu, 12 Aug 2010) Log Message: ----------- Added 1856 THB option for token lay and changed blocked hex token lay implementation Modified Paths: -------------- trunk/18xx/data/1830/CompanyManager.xml trunk/18xx/data/1830/Map.xml trunk/18xx/data/1856/CompanyManager.xml trunk/18xx/data/1856/Game.xml trunk/18xx/rails/game/MapHex.java trunk/18xx/rails/game/PublicCompany.java trunk/18xx/rails/game/PublicCompanyI.java Modified: trunk/18xx/data/1830/CompanyManager.xml =================================================================== --- trunk/18xx/data/1830/CompanyManager.xml 2010-08-11 23:21:59 UTC (rev 1379) +++ trunk/18xx/data/1830/CompanyManager.xml 2010-08-12 18:46:08 UTC (rev 1380) @@ -87,7 +87,9 @@ </Company> <Company name="Erie" type="Public" tokens="3" fgColour="000000" bgColour="FFFF00" longname="Erie Railroad"> - <Home hex="E11"/> + <!-- city = 0 implies that this is not yet decided (OO-tiles), blocks means that + in each city one slot has to be available --> + <Home hex="E11" city="0" AllCitiesBlocked="yes"/> </Company> <Company name="B&M" type="Public" tokens="2" fgColour="000000" bgColour="60E060" longname="Boston & Maine"> @@ -104,7 +106,7 @@ <IfOption name="Variant" value="Pere Marquette"> <Company name="PM" type="Public" tokens="3" fgColour="FFFF00" bgColour="000080" longname="Pere Marquette"> - <Home hex="E5"/> + <Home hex="E5" city="0" AllCitiesBlocked="yes" /> </Company> </IfOption> <StartPacket roundClass="rails.game.StartRound_1830"> Modified: trunk/18xx/data/1830/Map.xml =================================================================== --- trunk/18xx/data/1830/Map.xml 2010-08-11 23:21:59 UTC (rev 1379) +++ trunk/18xx/data/1830/Map.xml 2010-08-12 18:46:08 UTC (rev 1380) @@ -36,7 +36,7 @@ <Hex name="E5" tile="-20" label="OO" cost="80"/> <Hex name="E7" tile="-1" impassable="F8"/> <Hex name="E9" tile="-7" orientation="4"/> - <Hex name="E11" tile="-20" label="OO" unlaidHomeBlocksTokens="yes"/> + <Hex name="E11" tile="-20" label="OO"/> <Hex name="E13" tile="0"/> <Hex name="E15" tile="0"/> <Hex name="E17" tile="0" cost="120"/> Modified: trunk/18xx/data/1856/CompanyManager.xml =================================================================== --- trunk/18xx/data/1856/CompanyManager.xml 2010-08-11 23:21:59 UTC (rev 1379) +++ trunk/18xx/data/1856/CompanyManager.xml 2010-08-12 18:46:08 UTC (rev 1380) @@ -113,7 +113,12 @@ <Destination hex="K8"/> </Company> <Company name="THB" type="Public" tokens="2" fgColour="000000" bgColour="B0B040"> - <Home hex="L15" city="0"/><!-- City to be selected in first turn--> + <IfOption name="1856THBHomeBlocked" value="yes"> + <Home hex="L15" city="0" blockedForAllCities = "yes" /> + </IfOption> + <IfOption name="1856THBHomeBlocked" value="no"> + <Home hex="L15" city="0" blockedForAllCities = "no" /> + </IfOption> <Destination hex="J11"/> </Company> <Company name="BBG" type="Public" tokens="3" fgColour="000000" bgColour="FF8080"> Modified: trunk/18xx/data/1856/Game.xml =================================================================== --- trunk/18xx/data/1856/Game.xml 2010-08-11 23:21:59 UTC (rev 1379) +++ trunk/18xx/data/1856/Game.xml 2010-08-12 18:46:08 UTC (rev 1380) @@ -9,7 +9,7 @@ <GameOption name="UnlimitedTiles" type="toggle" default="no"/> <GameOption name="LeaveAuctionOnPass" type="toggle" default="no"/> <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> - <GameOption name="1856THBHomeBlocked" type="toggle" default="no" /> + <GameOption name="1856THBHomeBlocked" type="toggle" default="yes" /> <GameParameters> <StockRound class="rails.game.specific._1856.StockRound_1856" sequence="SellBuyOrBuySell"> Modified: trunk/18xx/rails/game/MapHex.java =================================================================== --- trunk/18xx/rails/game/MapHex.java 2010-08-11 23:21:59 UTC (rev 1379) +++ trunk/18xx/rails/game/MapHex.java 2010-08-12 18:46:08 UTC (rev 1380) @@ -1012,46 +1012,60 @@ /** * @return Returns false if no base tokens may yet be laid on this hex and station. + * * NOTE: this method currently only checks for prohibitions caused * by the presence of unlaid home base tokens. * It does NOT (yet) check for free space. * - * Remark: There are the following cases to check - * A) isBlockedForTokenLays is active for the MapHex => return the state of this - * (Example: Erie home base in 1830) - * otherwise - * B) City is decided => check the city if a slot is left (standard) - * C) City is undecided => check all cities if there is a slot left + * + * There are the following cases to check for each company located there + * + * A) City is decided or there is only one city + * => check if the city has a free slot or not + * (examples: NYNH in 1830 for a two city tile, NYC for a one city tile) + * B) City is not decided (example: Erie in 1830) + * two subcases depending on isHomeBlockedForAllCities + * - (true): all cities of the hex have remaining slots available + * - (false): no city of the hex has remaining slots available + * C) Or the company does not block its home city at all (example:Pr in 1835) + * then isBlockedForTokenLays attribute is used + * + * NOTE: It assumes that not two company share the same home city. + * Undecided companies cannot share the same hex with any other company. + * + * Previously used was the variable isBlockedForTokenLays + * which is set to yes to block the whole hex for the token lays + * until the (home) company laid their token + * */ public boolean isBlockedForTokenLays(PublicCompanyI company, int cityNumber) { - if (isHomeFor(company)) + if (isHomeFor(company)) { // Company can always lay a home base return false; - else if (isBlockedForTokenLays != null) { // case A) - // if true: token lay blocked because a required home base is not yet laid - // if false: token lay allowed if there is any free space - // Free space is not checked here (yet) + } else if (isBlockedForTokenLays != null) { + // Return MapHex attribute if defined return isBlockedForTokenLays.booleanValue(); } else if (homes != null && !homes.isEmpty()) { // Check if this token lay does not block an unlaid home base for (PublicCompanyI comp : homes.keySet()) { if (comp.hasLaidHomeBaseTokens() || comp.isClosed()) continue; + // home base not laid yet, define list of cities to check + List<City> citiesToCheck = new ArrayList<City>(); City homeCity = homes.get(comp); - if (homeCity != null) { // case B) - if (cityNumber == homeCity.getNumber() - // Assume that a city is never home to more than one company - && homeCity.getTokens().isEmpty() - && homeCity.getTokenSlotsLeft() < 2) { - return true; + if (homeCity != null) { + citiesToCheck.add(homeCity); + } else { + citiesToCheck.addAll(cities); + } + int tokenSlotsLeft = 0; + for (City city:cities) { + tokenSlotsLeft += city.getTokenSlotsLeft(); + if (comp.isHomeBlockedForAllCities() & city.getTokenSlotsLeft() < 2) { + return true; } - } else { // case C) - int tokenSlotsLeft = 0; - for (City city:cities) { - tokenSlotsLeft += city.getTokenSlotsLeft(); - } - if (tokenSlotsLeft < 2) return true; // not enough tokens left, assume only one company } + if (tokenSlotsLeft < 2) return true; // not enough tokens left, assume only one company } } return false; Modified: trunk/18xx/rails/game/PublicCompany.java =================================================================== --- trunk/18xx/rails/game/PublicCompany.java 2010-08-11 23:21:59 UTC (rev 1379) +++ trunk/18xx/rails/game/PublicCompany.java 2010-08-12 18:46:08 UTC (rev 1380) @@ -59,6 +59,7 @@ protected String homeHexName = null; protected MapHex homeHex = null; protected int homeCityNumber = 1; + protected boolean homeAllCitiesBlocked = false; /** Destination hex * */ protected String destinationHexName = null; @@ -320,6 +321,7 @@ if (homeBaseTag != null) { homeHexName = homeBaseTag.getAttributeAsString("hex"); homeCityNumber = homeBaseTag.getAttributeAsInteger("city", 1); + homeAllCitiesBlocked = homeBaseTag.getAttributeAsBoolean("allCitiesBlocked", false); } Tag destinationTag = tag.getChild("Destination"); @@ -827,6 +829,15 @@ public void setHomeCityNumber(int number) { this.homeCityNumber = number; } + + /** + * @return true -> requires an open slot in each city of the hex, false -> one slot on the hex + * + */ + public boolean isHomeBlockedForAllCities() { + return homeAllCitiesBlocked; + } + /** * @return Returns the destinationHex. Modified: trunk/18xx/rails/game/PublicCompanyI.java =================================================================== --- trunk/18xx/rails/game/PublicCompanyI.java 2010-08-11 23:21:59 UTC (rev 1379) +++ trunk/18xx/rails/game/PublicCompanyI.java 2010-08-12 18:46:08 UTC (rev 1380) @@ -330,6 +330,7 @@ public int getHomeCityNumber(); public void setHomeCityNumber(int homeCityNumber); + public boolean isHomeBlockedForAllCities(); public MapHex getDestinationHex(); public boolean hasDestination (); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-12 20:58:12
|
Revision: 1381 http://rails.svn.sourceforge.net/rails/?rev=1381&view=rev Author: stefanfrey Date: 2010-08-12 20:58:05 +0000 (Thu, 12 Aug 2010) Log Message: ----------- Fixed and updated implementation of blocked token lays Modified Paths: -------------- trunk/18xx/data/1830/CompanyManager.xml trunk/18xx/rails/game/GameManager.java trunk/18xx/rails/game/MapHex.java Modified: trunk/18xx/data/1830/CompanyManager.xml =================================================================== --- trunk/18xx/data/1830/CompanyManager.xml 2010-08-12 18:46:08 UTC (rev 1380) +++ trunk/18xx/data/1830/CompanyManager.xml 2010-08-12 20:58:05 UTC (rev 1381) @@ -89,7 +89,7 @@ longname="Erie Railroad"> <!-- city = 0 implies that this is not yet decided (OO-tiles), blocks means that in each city one slot has to be available --> - <Home hex="E11" city="0" AllCitiesBlocked="yes"/> + <Home hex="E11" city="0" allCitiesBlocked="yes"/> </Company> <Company name="B&M" type="Public" tokens="2" fgColour="000000" bgColour="60E060" longname="Boston & Maine"> @@ -106,7 +106,7 @@ <IfOption name="Variant" value="Pere Marquette"> <Company name="PM" type="Public" tokens="3" fgColour="FFFF00" bgColour="000080" longname="Pere Marquette"> - <Home hex="E5" city="0" AllCitiesBlocked="yes" /> + <Home hex="E5" city="0" allCitiesBlocked="yes" /> </Company> </IfOption> <StartPacket roundClass="rails.game.StartRound_1830"> Modified: trunk/18xx/rails/game/GameManager.java =================================================================== --- trunk/18xx/rails/game/GameManager.java 2010-08-12 18:46:08 UTC (rev 1380) +++ trunk/18xx/rails/game/GameManager.java 2010-08-12 20:58:05 UTC (rev 1381) @@ -879,14 +879,14 @@ result = save(gameAction); break; case GameAction.UNDO: - moveStack.undoMoveSet(true); + moveStack.undoMoveSet(false); result = true; break; case GameAction.FORCED_UNDO: if (index != -1) { moveStack.gotoIndex(index); } else { - moveStack.undoMoveSet(false); + moveStack.undoMoveSet(true); } result = true; break; Modified: trunk/18xx/rails/game/MapHex.java =================================================================== --- trunk/18xx/rails/game/MapHex.java 2010-08-12 18:46:08 UTC (rev 1380) +++ trunk/18xx/rails/game/MapHex.java 2010-08-12 20:58:05 UTC (rev 1381) @@ -1047,26 +1047,44 @@ // Return MapHex attribute if defined return isBlockedForTokenLays.booleanValue(); } else if (homes != null && !homes.isEmpty()) { - // Check if this token lay does not block an unlaid home base + City cityToLay = this.getCity(cityNumber); + if (cityToLay == null) { // city does not exist, this does not block itself + return false; + } + // check if the city is potential home for other companies + int allBlockCompanies = 0; + int anyBlockCompanies = 0; + int cityBlockCompanies = 0; for (PublicCompanyI comp : homes.keySet()) { if (comp.hasLaidHomeBaseTokens() || comp.isClosed()) continue; - // home base not laid yet, define list of cities to check - List<City> citiesToCheck = new ArrayList<City>(); + // home base not laid yet City homeCity = homes.get(comp); - if (homeCity != null) { - citiesToCheck.add(homeCity); + if (homeCity == null) { + if (comp.isHomeBlockedForAllCities()) { + allBlockCompanies ++; // undecided companies that block all cities + } else { + anyBlockCompanies ++; // undecided companies that block any cities + } + } else if (cityToLay == homeCity) { + cityBlockCompanies ++; // companies which are located in the city in question } else { - citiesToCheck.addAll(cities); + anyBlockCompanies ++; // companies which are located somewhere else } - int tokenSlotsLeft = 0; - for (City city:cities) { - tokenSlotsLeft += city.getTokenSlotsLeft(); - if (comp.isHomeBlockedForAllCities() & city.getTokenSlotsLeft() < 2) { - return true; - } - } - if (tokenSlotsLeft < 2) return true; // not enough tokens left, assume only one company } + log.debug("IsBlockedForTokenLays: allBlockCompanies = " + allBlockCompanies + + ", anyBlockCompanies = " + anyBlockCompanies + " , cityBlockCompanies = " + cityBlockCompanies); + // check if there are sufficient individual city slots + if (allBlockCompanies + cityBlockCompanies + 1 > cityToLay.getTokenSlotsLeft()) { + return true; // the additional token exceeds the number of available slots + } + // check if the overall hex slots are sufficient + int allTokenSlotsLeft = 0; + for (City city:cities) { + allTokenSlotsLeft += city.getTokenSlotsLeft(); + } + if (allBlockCompanies + anyBlockCompanies + cityBlockCompanies + 1 > allTokenSlotsLeft) { + return true; // all located companies plus the additonal token exceeds the available slots + } } return false; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-13 15:58:37
|
Revision: 1383 http://rails.svn.sourceforge.net/rails/?rev=1383&view=rev Author: stefanfrey Date: 2010-08-13 15:58:30 +0000 (Fri, 13 Aug 2010) Log Message: ----------- Fixed problems with TestGame integration tests Modified Paths: -------------- trunk/18xx/data/profiles/test.profile trunk/18xx/rails/util/Config.java trunk/18xx/rails/util/LocalText.java trunk/18xx/test/TestGame.java Modified: trunk/18xx/data/profiles/test.profile =================================================================== --- trunk/18xx/data/profiles/test.profile 2010-08-13 15:57:46 UTC (rev 1382) +++ trunk/18xx/data/profiles/test.profile 2010-08-13 15:58:30 UTC (rev 1383) @@ -17,7 +17,7 @@ # (implying a language variant of that country; no default). # Locale: concatenation of the above. If present, overrides any of the above. # Examples: en, en_US, en_UK, fr_FR, fr_CA. -locale=te_st +locale=te_ST #language= #country= @@ -25,7 +25,7 @@ # Each game has a specific format for monetary amounts (e.g. $100, 100M). # An overriding format can be specified here, but then applies to all games. # The @ character must be present and is replaced by the amount. -# Example: \xA3@ to specify a pound sign prefix: \xA3100. +# Example: �@ to specify a pound sign prefix: �100. #money_format=$@ ### Save file directory Modified: trunk/18xx/rails/util/Config.java =================================================================== --- trunk/18xx/rails/util/Config.java 2010-08-13 15:57:46 UTC (rev 1382) +++ trunk/18xx/rails/util/Config.java 2010-08-13 15:58:30 UTC (rev 1383) @@ -51,8 +51,8 @@ private static String userProfilesFile = "user.profiles"; private static Properties userProfiles = new Properties(); private static boolean profilesLoaded = false; - private static final String TEST_PROFILE_SELECTION = ".test"; - private static final String DEFAULT_PROFILE_SELECTION = "default"; + private static String DEFAULT_PROFILE_SELECTION = "default"; // can be overwritten + private static final String TEST_PROFILE_SELECTION = ".test"; // used as default profile for integration tests private static final String STANDARD_PROFILE_SELECTION = "user"; private static final String DEFAULTPROFILE_PROPERTY = "default.profile"; private static final String PROFILENAME_PROPERTY = "profile.name"; @@ -329,8 +329,11 @@ // delayed setting of logger log = Logger.getLogger(Config.class.getPackage().getName()); + // define settings for testing legacyConfigFile = false; - selectedProfile = TEST_PROFILE_SELECTION; + DEFAULT_PROFILE_SELECTION = TEST_PROFILE_SELECTION; + selectedProfile = null; + initialLoad(); } @@ -447,19 +450,23 @@ userProperties = new Properties(); defaultProperties = new Properties(); - // check if the profile is already defined under userProfiles - String userConfigFile = userProfiles.getProperty(userProfile); - if (Util.hasValue(userConfigFile) && // load user profile - loadPropertyFile(userProperties, userConfigFile, false)) { - // do nothing, only side effects - } else { // if not defined or loadable, define userprofile with file association - userProfiles.setProperty(userProfile, ""); + String userConfigFile = null; + if (Util.hasValue(userProfile)) { + // check if the profile is already defined under userProfiles + userConfigFile = userProfiles.getProperty(userProfile); + if (Util.hasValue(userConfigFile) && // load user profile + loadPropertyFile(userProperties, userConfigFile, false)) { + // do nothing, only side effects + } else { // if not defined or loadable, define userprofile with file association + userProfiles.setProperty(userProfile, ""); + } + + // check if profilename is defined in user properties + if (!Util.hasValue(userProfiles.getProperty(PROFILENAME_PROPERTY))) { + userProperties.setProperty(PROFILENAME_PROPERTY, userProfile); + } } - // check if profilename is defined in user properties - if (!Util.hasValue(userProfiles.getProperty(PROFILENAME_PROPERTY))) { - userProperties.setProperty(PROFILENAME_PROPERTY, userProfile); - } loadDefaultProfile(); setSaveDirDefaults(); } Modified: trunk/18xx/rails/util/LocalText.java =================================================================== --- trunk/18xx/rails/util/LocalText.java 2010-08-13 15:57:46 UTC (rev 1382) +++ trunk/18xx/rails/util/LocalText.java 2010-08-13 15:58:30 UTC (rev 1383) @@ -11,6 +11,8 @@ public class LocalText extends ResourceBundle { + private static final String TEST_LOCALE = "te_ST"; + protected static String language = "en"; protected static String country = ""; @@ -92,8 +94,8 @@ } } - // special treatment for te_ST (test) - if (localeCode.equals("te_ST")) { + // special treatment for test locale + if (localeCode.equals(TEST_LOCALE)) { StringBuffer s = new StringBuffer(key); if (parameters != null) for (Object o:parameters) Modified: trunk/18xx/test/TestGame.java =================================================================== --- trunk/18xx/test/TestGame.java 2010-08-13 15:57:46 UTC (rev 1382) +++ trunk/18xx/test/TestGame.java 2010-08-13 15:58:30 UTC (rev 1383) @@ -2,7 +2,6 @@ import java.io.File; import java.io.FileReader; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ste...@us...> - 2010-08-13 16:04:06
|
Revision: 1385 http://rails.svn.sourceforge.net/rails/?rev=1385&view=rev Author: stefanfrey Date: 2010-08-13 16:03:47 +0000 (Fri, 13 Aug 2010) Log Message: ----------- Remaining changes of THB fix Modified Paths: -------------- trunk/18xx/LocalisedText.properties trunk/18xx/data/1856/Game.xml trunk/18xx/data/GamesList.xml trunk/18xx/rails/game/MapHex.java Modified: trunk/18xx/LocalisedText.properties =================================================================== --- trunk/18xx/LocalisedText.properties 2010-08-13 15:59:03 UTC (rev 1384) +++ trunk/18xx/LocalisedText.properties 2010-08-13 16:03:47 UTC (rev 1385) @@ -1,6 +1,6 @@ # Texts with lowercase keys are intended to be inserted into other messages 1856MergerDialog=Repay loan decision of {0} for CGR merger -1856THBHomeBlocked=THB home hex is blocked for token lays (unless gray tile) +1856THBHomeBlocked=THB home hex is blocked (until gray tile) 1889PrivateBactive=Player {0} (owner of Private B) may lay port tile 1889PrivateCactive=Player {0} (previous owner of Private C) may lay tile on C4 immediately 18ALOptimizeNamedTrains=Optimize named train assignment Modified: trunk/18xx/data/1856/Game.xml =================================================================== --- trunk/18xx/data/1856/Game.xml 2010-08-13 15:59:03 UTC (rev 1384) +++ trunk/18xx/data/1856/Game.xml 2010-08-13 16:03:47 UTC (rev 1385) @@ -9,7 +9,7 @@ <GameOption name="UnlimitedTiles" type="toggle" default="no"/> <GameOption name="LeaveAuctionOnPass" type="toggle" default="no"/> <GameOption name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> - <GameOption name="1856THBHomeBlocked" type="toggle" default="yes" /> + <GameOption name="1856THBHomeBlocked" type="toggle" default="no" /> <GameParameters> <StockRound class="rails.game.specific._1856.StockRound_1856" sequence="SellBuyOrBuySell"> Modified: trunk/18xx/data/GamesList.xml =================================================================== --- trunk/18xx/data/GamesList.xml 2010-08-13 15:59:03 UTC (rev 1384) +++ trunk/18xx/data/GamesList.xml 2010-08-13 16:03:47 UTC (rev 1385) @@ -67,6 +67,7 @@ <Option name="UnlimitedTiles" type="toggle" default="no"/> <Option name="LeaveAuctionOnPass" type="toggle" default="no"/> <Option name="SeparateSalesAtSamePrice" type="toggle" default="yes"/> + <Option name="1856THBHomeBlocked" type="toggle" default="no" /> <Players minimum="3" maximum="6"/> </Game> Modified: trunk/18xx/rails/game/MapHex.java =================================================================== --- trunk/18xx/rails/game/MapHex.java 2010-08-13 15:59:03 UTC (rev 1384) +++ trunk/18xx/rails/game/MapHex.java 2010-08-13 16:03:47 UTC (rev 1385) @@ -1030,10 +1030,10 @@ * C) Or the company does not block its home city at all (example:Pr in 1835) * then isBlockedForTokenLays attribute is used * - * NOTE: It assumes that not two company share the same home city. - * Undecided companies cannot share the same hex with any other company. + * NOTE: It now deals with more than one company with a home base on the + * same hex. * - * Previously used was the variable isBlockedForTokenLays + * Previously there was only the variable isBlockedForTokenLays * which is set to yes to block the whole hex for the token lays * until the (home) company laid their token * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |