From: <aki...@us...> - 2013-10-17 19:34:43
|
Revision: 9470 http://sourceforge.net/p/gridarta/code/9470 Author: akirschbaum Date: 2013-10-17 19:34:38 +0000 (Thu, 17 Oct 2013) Log Message: ----------- Add ProjectSettings to ProjectModel. Modified Paths: -------------- trunk/src/gridarta/src/main/java/net/sf/gridarta/maincontrol/GUIMainControl.java trunk/src/gridarta/src/main/java/net/sf/gridarta/maincontrol/GridartaEditor.java trunk/src/project/src/main/java/net/sf/gridarta/project/ProjectModel.java Modified: trunk/src/gridarta/src/main/java/net/sf/gridarta/maincontrol/GUIMainControl.java =================================================================== --- trunk/src/gridarta/src/main/java/net/sf/gridarta/maincontrol/GUIMainControl.java 2013-10-17 19:21:38 UTC (rev 9469) +++ trunk/src/gridarta/src/main/java/net/sf/gridarta/maincontrol/GUIMainControl.java 2013-10-17 19:34:38 UTC (rev 9470) @@ -193,7 +193,6 @@ import net.sf.gridarta.model.scripts.ScriptedEventFactory; import net.sf.gridarta.model.settings.DefaultVolatileSettings; import net.sf.gridarta.model.settings.EditorSettings; -import net.sf.gridarta.model.settings.ProjectSettings; import net.sf.gridarta.model.settings.VolatileSettings; import net.sf.gridarta.plugin.PluginModel; import net.sf.gridarta.project.ProjectModel; @@ -297,7 +296,6 @@ /** * Creates a new instance. * @param projectModel the project model to edit - * @param projectSettings the project settings instance * @param mapViewSettings the map view settings * @param editorSettings the editor settings instance * @param errorView the error view for reporting errors @@ -309,7 +307,7 @@ * @param rendererFactory the renderer factory instance * @param filterControl the filter control instance */ - public GUIMainControl(@NotNull final ProjectModel<G, A, R> projectModel, @NotNull final ProjectSettings projectSettings, @NotNull final MapViewSettings mapViewSettings, @NotNull final EditorSettings editorSettings, @NotNull final ErrorView errorView, @NotNull final GUIUtils guiUtils, @NotNull final PluginModel<G, A, R> pluginModel, @NotNull final EditorFactory<G, A, R> editorFactory, @NotNull final SystemIcons systemIcons, @NotNull final ConfigSourceFactory configSourceFactory, @NotNull final RendererFactory<G, A, R> rendererFactory, @NotNull final FilterControl<G, A, R> filterControl) { + public GUIMainControl(@NotNull final ProjectModel<G, A, R> projectModel, @NotNull final MapViewSettings mapViewSettings, @NotNull final EditorSettings editorSettings, @NotNull final ErrorView errorView, @NotNull final GUIUtils guiUtils, @NotNull final PluginModel<G, A, R> pluginModel, @NotNull final EditorFactory<G, A, R> editorFactory, @NotNull final SystemIcons systemIcons, @NotNull final ConfigSourceFactory configSourceFactory, @NotNull final RendererFactory<G, A, R> rendererFactory, @NotNull final FilterControl<G, A, R> filterControl) { this.projectModel = projectModel; final MapViewFactory<G, A, R> mapViewFactory = editorFactory.newMapViewFactory(rendererFactory, projectModel.getPathManager()); scriptExtension = editorFactory.getScriptExtension(); @@ -319,7 +317,7 @@ final ExitConnectorModel exitConnectorModel = new DefaultExitConnectorModel(); final ShortcutsManager shortcutsManager = new ShortcutsManager(ACTION_BUILDER); final ImageCreator<G, A, R> imageCreator = new ImageCreator<G, A, R>(projectModel.getMapManager(), rendererFactory); - final VolatileSettings volatileSettings = new DefaultVolatileSettings(projectSettings.getMapsDirectory()); + final VolatileSettings volatileSettings = new DefaultVolatileSettings(projectModel.getProjectSettings().getMapsDirectory()); final ImageCreator2<G, A, R> imageCreator2 = new ImageCreator2<G, A, R>(volatileSettings, imageCreator); final String spellFile = editorFactory.getSpellFile(); final SpellsUtils spellUtils = spellFile != null ? new SpellsUtils(spellFile) : null; @@ -327,7 +325,7 @@ final MapViewManager<G, A, R> mapViewManager = new MapViewManager<G, A, R>(); final StatusBar<G, A, R> statusBar = new StatusBar<G, A, R>(projectModel.getMapManager(), mapViewManager, projectModel.getArchetypeSet(), projectModel.getFaceObjects()); final MapImageCache<G, A, R> mapImageCache = new MapImageCache<G, A, R>(projectModel.getMapManager(), systemIcons.getDefaultIcon(), systemIcons.getDefaultPreview(), rendererFactory, editorFactory.getCacheFiles()); - final MapFolderTree<G, A, R> mapFolderTree = new MapFolderTree<G, A, R>(projectSettings.getPickmapDir()); + final MapFolderTree<G, A, R> mapFolderTree = new MapFolderTree<G, A, R>(projectModel.getProjectSettings().getPickmapDir()); final ImageIcon icon = systemIcons.getAppIcon(); mainViewFrame = new JFrame(ACTION_BUILDER.format("mainWindow.title", getBuildNumberAsString())); final Frame parent = mainViewFrame; @@ -340,33 +338,33 @@ final SelectedSquareModel<G, A, R> selectedSquareModel = new SelectedSquareModel<G, A, R>(); final GameObjectMatcher floorMatcher = projectModel.getGameObjectMatchers().getMatcher("system_floor", "floor"); final GameObjectMatcher wallMatcher = projectModel.getGameObjectMatchers().getMatcher("system_wall", "wall"); - final ErrorViewCollector gameObjectMatchersErrorViewCollector = new ErrorViewCollector(errorView, new File(projectSettings.getConfigurationDirectory(), "GameObjectMatchers.xml")); + final ErrorViewCollector gameObjectMatchersErrorViewCollector = new ErrorViewCollector(errorView, new File(projectModel.getProjectSettings().getConfigurationDirectory(), "GameObjectMatchers.xml")); final GameObjectMatcher belowFloorMatcher = projectModel.getGameObjectMatchers().getMatcherWarn(gameObjectMatchersErrorViewCollector, "system_below_floor", "below_floor"); final GameObjectMatcher systemObjectMatcher = projectModel.getGameObjectMatchers().getMatcher("system_system_object"); final InsertionModeSet<G, A, R> insertionModeSet = new InsertionModeSet<G, A, R>(projectModel.getTopmostInsertionMode(), floorMatcher, wallMatcher, belowFloorMatcher, systemObjectMatcher); final CopyBuffer<G, A, R> copyBuffer = new CopyBuffer<G, A, R>(mapViewSettings, projectModel.getGameObjectFactory(), projectModel.getMapArchObjectFactory(), projectModel.getMapModelFactory(), insertionModeSet); final FindDialogManager<G, A, R> findDialogManager = new FindDialogManager<G, A, R>(parent, mapViewManager); final Exiter exiter = new DefaultExiter(parent); - scriptEditControl = new ScriptEditControl(editorFactory.getScriptFileFilter(), scriptExtension, parent, projectSettings.getMapsDirectory(), preferences, exiter); + scriptEditControl = new ScriptEditControl(editorFactory.getScriptFileFilter(), scriptExtension, parent, projectModel.getProjectSettings().getMapsDirectory(), preferences, exiter); final TextAreaDefaults textAreaDefaults = new TextAreaDefaults(scriptEditControl); scriptEditControl.setTextAreaDefaults(textAreaDefaults); - final GameObjectAttributesDialogFactory<G, A, R> gameObjectAttributesDialogFactory = new GameObjectAttributesDialogFactory<G, A, R>(projectModel.getArchetypeTypeSet(), parent, treasureListTree, projectModel.getFaceObjectProviders(), projectModel.getAnimationObjects(), projectSettings, editorFactory.getMapFileFilter(), editorFactory.getScriptFileFilter(), projectModel.getFaceObjects(), projectModel.getGameObjectSpells(), projectModel.getNumberSpells(), editorFactory.getUndefinedSpellIndex(), projectModel.getTreasureTree(), noFaceSquareIcon, unknownSquareIcon, textAreaDefaults, projectModel.getMapManager()); - final ScriptedEventEditor<G, A, R> scriptedEventEditor = new ScriptedEventEditor<G, A, R>(projectSettings, scriptEditControl); + final GameObjectAttributesDialogFactory<G, A, R> gameObjectAttributesDialogFactory = new GameObjectAttributesDialogFactory<G, A, R>(projectModel.getArchetypeTypeSet(), parent, treasureListTree, projectModel.getFaceObjectProviders(), projectModel.getAnimationObjects(), projectModel.getProjectSettings(), editorFactory.getMapFileFilter(), editorFactory.getScriptFileFilter(), projectModel.getFaceObjects(), projectModel.getGameObjectSpells(), projectModel.getNumberSpells(), editorFactory.getUndefinedSpellIndex(), projectModel.getTreasureTree(), noFaceSquareIcon, unknownSquareIcon, textAreaDefaults, projectModel.getMapManager()); + final ScriptedEventEditor<G, A, R> scriptedEventEditor = new ScriptedEventEditor<G, A, R>(projectModel.getProjectSettings(), scriptEditControl); final ScriptArchUtils scriptArchUtils = DefaultMainControl.loadScriptArchUtils(errorView, editorFactory, projectModel.getArchetypeTypeSet()); final ScriptedEventFactory<G, A, R> scriptedEventFactory = editorFactory.newScriptedEventFactory(scriptArchUtils, projectModel.getGameObjectFactory(), scriptedEventEditor, projectModel.getArchetypeSet()); - final ScriptArchEditor<G, A, R> scriptArchEditor = new ScriptArchEditor<G, A, R>(scriptedEventFactory, editorFactory.getScriptExtension(), editorFactory.getScriptName(), scriptArchUtils, editorFactory.getScriptFileFilter(), projectSettings, projectModel.getMapManager(), projectModel.getPathManager(), scriptEditControl); + final ScriptArchEditor<G, A, R> scriptArchEditor = new ScriptArchEditor<G, A, R>(scriptedEventFactory, editorFactory.getScriptExtension(), editorFactory.getScriptName(), scriptArchUtils, editorFactory.getScriptFileFilter(), projectModel.getProjectSettings(), projectModel.getMapManager(), projectModel.getPathManager(), scriptEditControl); final ScriptArchDataUtils<G, A, R> scriptArchDataUtils = editorFactory.newScriptArchDataUtils(scriptArchUtils, scriptedEventFactory, scriptedEventEditor); final GameObjectMatcher monsterMatcherTmp = projectModel.getGameObjectMatchers().getMatcherWarn(gameObjectMatchersErrorViewCollector, "system_monster", "monster"); final GameObjectMatcher monsterMatcher = monsterMatcherTmp == null ? new TypeNrsGameObjectMatcher() : monsterMatcherTmp; final GameObjectMatcher exitGameObjectMatcherTmp = projectModel.getGameObjectMatchers().getMatcherWarn(gameObjectMatchersErrorViewCollector, "system_exit", "exit"); final GameObjectMatcher exitGameObjectMatcher = exitGameObjectMatcherTmp == null ? new TypeNrsGameObjectMatcher() : exitGameObjectMatcherTmp; final ExitMatcher<G, A, R> exitMatcher = new ExitMatcher<G, A, R>(exitGameObjectMatcher); - final MapPathNormalizer mapPathNormalizer = new MapPathNormalizer(projectSettings); - final MapPropertiesDialogFactory<G, A, R> mapPropertiesDialogFactory = editorFactory.newMapPropertiesDialogFactory(projectSettings, projectModel.getMapManager(), mapPathNormalizer); + final MapPathNormalizer mapPathNormalizer = new MapPathNormalizer(projectModel.getProjectSettings()); + final MapPropertiesDialogFactory<G, A, R> mapPropertiesDialogFactory = editorFactory.newMapPropertiesDialogFactory(projectModel.getProjectSettings(), projectModel.getMapManager(), mapPathNormalizer); final DelayedMapModelListenerManager<G, A, R> delayedMapModelListenerManager = new DelayedMapModelListenerManager<G, A, R>(projectModel.getMapManager(), exiter); final Control<?, G, A, R> lockedItemsControl = new LockedItemsControl<G, A, R>(mapViewManager, delayedMapModelListenerManager, editorFactory.getLockedItemsTypeNumbers()); final GameObjectAttributesModel<G, A, R> gameObjectAttributesModel = new GameObjectAttributesModel<G, A, R>(); - final File scriptsFile = new File(projectSettings.getMapsDirectory(), editorFactory.getScriptsDir()); + final File scriptsFile = new File(projectModel.getProjectSettings().getMapsDirectory(), editorFactory.getScriptsDir()); updaterManager = new UpdaterManager(exiter, projectModel.getMapManager(), parent, editorFactory.getGridartaJarFilename()); final TextEditorTab<G, A, R> textEditorTab = new TextEditorTab<G, A, R>(gameObjectAttributesModel, projectModel.getArchetypeTypeSet()); final EditorAction undoControl = new UndoControl<G, A, R>(projectModel.getMapManager(), projectModel.getGameObjectFactory(), projectModel.getGameObjectMatchers()); @@ -377,7 +375,7 @@ final ArchetypeChooserControl<G, A, R> archetypeChooserControl = new ArchetypeChooserControl<G, A, R>(projectModel.getArchetypeChooserModel(), archetypeChooserView); mapViewsManager = new MapViewsManager<G, A, R>(mapViewSettings, mapViewFactory, projectModel.getMapManager(), projectModel.getPickmapManager()); newMapDialogFactory = editorFactory.newNewMapDialogFactory(mapViewsManager, projectModel.getMapArchObjectFactory(), pickmapChooserView, parent); - fileControl = new DefaultFileControl<G, A, R>(projectSettings, volatileSettings, mapImageCache, projectModel.getMapManager(), mapViewsManager, parent, GuiFileFilters.mapFileFilter, editorFactory.getScriptFileFilter(), newMapDialogFactory, scriptExtension, scriptEditControl); + fileControl = new DefaultFileControl<G, A, R>(projectModel.getProjectSettings(), volatileSettings, mapImageCache, projectModel.getMapManager(), mapViewsManager, parent, GuiFileFilters.mapFileFilter, editorFactory.getScriptFileFilter(), newMapDialogFactory, scriptExtension, scriptEditControl); mapViewsManager.setFileControl(fileControl); final PickmapChooserControl<G, A, R> pickmapChooserControl = new PickmapChooserControl<G, A, R>(pickmapChooserModel, pickmapSettings, newMapDialogFactory, mapFolderTree, projectModel.getMapManager(), parent, mapViewsManager, fileControl, pickmapChooserView); final DefaultObjectChooser<G, A, R> objectChooser = new DefaultObjectChooser<G, A, R>(archetypeChooserControl, pickmapChooserControl, projectModel.getArchetypeChooserModel(), pickmapChooserModel, projectModel.getArchetypeTypeSet()); @@ -485,20 +483,20 @@ createAction("expandEmptySelection", "Map/Selection", mainActions); createAction("growSelection", "Map/Selection", new GrowSelectionAction<G, A, R>(mapViewManager)); createAction("shrinkSelection", "Map/Selection", new ShrinkSelectionAction<G, A, R>(mapViewManager)); - createAction("collectArches", "Tool", new CollectArchesAction<G, A, R>(projectSettings, projectModel.getResources(), exiter, mainViewFrame)); + createAction("collectArches", "Tool", new CollectArchesAction<G, A, R>(projectModel.getProjectSettings(), projectModel.getResources(), exiter, mainViewFrame)); createAction("reloadFaces", "Image,Tool", new ReloadFacesAction<G, A, R>(projectModel.getArchetypeSet(), projectModel.getFaceObjectProviders())); createAction("validateMap", "Map,Tool", new ValidateMapAction<G, A, R>(projectModel.getValidators(), projectModel.getMapManager())); createAction("showHelp", "Help", new ShowHelpAction(parent)); createAction("tipOfTheDay", "Help", new TipOfTheDayAction(parent)); createAction("newMap", "Map", new NewMapAction<G, A, R>(newMapDialogFactory)); - createAction("goMap", "Map", new GoMapDialogManager<G, A, R>(parent, projectModel.getMapManager(), mapViewsManager, projectSettings, exiter)); + createAction("goMap", "Map", new GoMapDialogManager<G, A, R>(parent, projectModel.getMapManager(), mapViewsManager, projectModel.getProjectSettings(), exiter)); createAction("goExit", "Map Navigation", new GoExitDialogManager<G, A, R>(parent, projectModel.getMapManager(), mapViewManager, exitGameObjectMatcher, projectModel.getPathManager(), enterMap, projectModel.getFaceObjectProviders())); createAction("cleanCompletelyBlockedSquares", "Tool", new CleanCompletelyBlockedSquaresAction<G, A, R>(projectModel.getMapManager())); - createAction("collectSpells", "Tool", new CollectSpellsAction(spellUtils, projectSettings, parent)); + createAction("collectSpells", "Tool", new CollectSpellsAction(spellUtils, projectModel.getProjectSettings(), parent)); createAction("controlClient", "Tool", new ControlClientAction(appPreferencesModel, mainViewFrame)); createAction("controlServer", "Tool", new ControlServerAction(appPreferencesModel, mainViewFrame)); createAction("gc", "Tool", new GcAction(statusBar)); - createAction("options", "Tool", new OptionsAction<G, A, R>(editorFactory, projectSettings, editorSettings, projectModel.getValidators(), appPreferencesModel, exitConnectorModel, configSourceFactory, parent)); + createAction("options", "Tool", new OptionsAction<G, A, R>(editorFactory, projectModel.getProjectSettings(), editorSettings, projectModel.getValidators(), appPreferencesModel, exitConnectorModel, configSourceFactory, parent)); createAction("shortcuts", "Tool", new ShortcutsAction(shortcutsManager, parent)); createAction("zoom", "Tool", new ZoomAction<G, A, R>(projectModel.getMapManager(), rendererFactory, parent)); createAction("moveCursorNorth", "Map Cursor,Map/Selection", mapCursorActions); Modified: trunk/src/gridarta/src/main/java/net/sf/gridarta/maincontrol/GridartaEditor.java =================================================================== --- trunk/src/gridarta/src/main/java/net/sf/gridarta/maincontrol/GridartaEditor.java 2013-10-17 19:21:38 UTC (rev 9469) +++ trunk/src/gridarta/src/main/java/net/sf/gridarta/maincontrol/GridartaEditor.java 2013-10-17 19:34:38 UTC (rev 9470) @@ -212,12 +212,12 @@ final RendererFactory<G, A, R> rendererFactory = editorFactory.newRendererFactory(mapViewSettings, filterControl, projectModel.getGameObjectParser(), projectModel.getFaceObjectProviders(), systemIcons, projectModel.getSmoothFaces()); final NamedFilter defaultFilterList = new NamedFilter(Collections.<NamedGameObjectMatcher>emptyList()); - final PluginParameterFactory<G, A, R> pluginParameterFactory = new PluginParameterFactory<G, A, R>(projectModel.getArchetypeSet(), projectModel.getMapManager(), defaultFilterList, projectSettings); + final PluginParameterFactory<G, A, R> pluginParameterFactory = new PluginParameterFactory<G, A, R>(projectModel.getArchetypeSet(), projectModel.getMapManager(), defaultFilterList, projectModel.getProjectSettings()); final PluginModelParser<G, A, R> pluginModelParser = new PluginModelParser<G, A, R>(pluginParameterFactory); final PluginModel<G, A, R> pluginModel = PluginModelLoader.loadPlugins(pluginParameterFactory, pluginModelParser, errorView, projectModel.getScriptsFile()); pluginModel.addPluginParameter("archetypeSet", projectModel.getArchetypeSet()); - pluginModel.addPluginParameter("projectSettings", projectSettings); - pluginModel.addPluginParameter("globalSettings", projectSettings); // XXX: for compatibility with existing scripts; should be replaced with "projectSettings" + pluginModel.addPluginParameter("projectSettings", projectModel.getProjectSettings()); + pluginModel.addPluginParameter("globalSettings", projectModel.getProjectSettings()); // XXX: for compatibility with existing scripts; should be replaced with "projectSettings" pluginModel.addPluginParameter("mapManager", projectModel.getMapManager()); pluginModel.addPluginParameter("validators", projectModel.getValidators()); pluginModel.addPluginParameter("rendererFactory", rendererFactory); @@ -229,7 +229,7 @@ try { switch (mode) { case NORMAL: - returnCode = runNormal(args2, editorFactory, errorView, guiUtils, configSourceFactory, rendererFactory, filterControl, pluginModel, projectModel, projectSettings, mapViewSettings, editorSettings, systemIcons); + returnCode = runNormal(args2, editorFactory, errorView, guiUtils, configSourceFactory, rendererFactory, filterControl, pluginModel, projectModel, mapViewSettings, editorSettings, systemIcons); break; case BATCH_PNG: @@ -245,7 +245,7 @@ break; case COLLECT_ARCHES: - returnCode = new CollectArchesCommand(projectModel.getResources(), projectSettings).execute(); + returnCode = new CollectArchesCommand(projectModel.getResources(), projectModel.getProjectSettings()).execute(); break; default: @@ -316,19 +316,18 @@ * @param filterControl the filter control to use * @param pluginModel the plugin model to use * @param projectModel the project model to use - * @param projectSettings the project settings * @param mapViewSettings the map view settings * @param editorSettings the editor settings * @param systemIcons the system icons for creating icons * @return return code suitable for passing to {@link System#exit(int)} */ - private int runNormal(@NotNull final Iterable<String> args, @NotNull final EditorFactory<G, A, R> editorFactory, @NotNull final ErrorView errorView, @NotNull final GUIUtils guiUtils, @NotNull final ConfigSourceFactory configSourceFactory, @NotNull final RendererFactory<G, A, R> rendererFactory, @NotNull final FilterControl<G, A, R> filterControl, @NotNull final PluginModel<G, A, R> pluginModel, @NotNull final ProjectModel<G, A, R> projectModel, @NotNull final ProjectSettings projectSettings, @NotNull final MapViewSettings mapViewSettings, @NotNull final EditorSettings editorSettings, @NotNull final SystemIcons systemIcons) { + private int runNormal(@NotNull final Iterable<String> args, @NotNull final EditorFactory<G, A, R> editorFactory, @NotNull final ErrorView errorView, @NotNull final GUIUtils guiUtils, @NotNull final ConfigSourceFactory configSourceFactory, @NotNull final RendererFactory<G, A, R> rendererFactory, @NotNull final FilterControl<G, A, R> filterControl, @NotNull final PluginModel<G, A, R> pluginModel, @NotNull final ProjectModel<G, A, R> projectModel, @NotNull final MapViewSettings mapViewSettings, @NotNull final EditorSettings editorSettings, @NotNull final SystemIcons systemIcons) { final GUIMainControl<?, ?, ?>[] guiMainControl = new GUIMainControl<?, ?, ?>[1]; final Runnable runnable = new Runnable() { @Override public void run() { - guiMainControl[0] = new GUIMainControl<G, A, R>(projectModel, projectSettings, mapViewSettings, editorSettings, errorView, guiUtils, pluginModel, editorFactory, systemIcons, configSourceFactory, rendererFactory, filterControl); + guiMainControl[0] = new GUIMainControl<G, A, R>(projectModel, mapViewSettings, editorSettings, errorView, guiUtils, pluginModel, editorFactory, systemIcons, configSourceFactory, rendererFactory, filterControl); } }; Modified: trunk/src/project/src/main/java/net/sf/gridarta/project/ProjectModel.java =================================================================== --- trunk/src/project/src/main/java/net/sf/gridarta/project/ProjectModel.java 2013-10-17 19:21:38 UTC (rev 9469) +++ trunk/src/project/src/main/java/net/sf/gridarta/project/ProjectModel.java 2013-10-17 19:34:38 UTC (rev 9470) @@ -126,6 +126,9 @@ private static final Category log = Logger.getLogger(ProjectModel.class); @NotNull + private final ProjectSettings projectSettings; + + @NotNull private final ArchetypeTypeSet archetypeTypeSet; @NotNull @@ -195,6 +198,7 @@ private final PathManager pathManager; public ProjectModel(@NotNull final ErrorView errorView, @NotNull final ProjectSettings projectSettings, @NotNull final ProjectFactory<G, A, R> projectFactory, @NotNull final SystemIcons systemIcons, @NotNull final ConfigSource configSource) { + this.projectSettings = projectSettings; final XmlHelper xmlHelper; try { xmlHelper = new XmlHelper(); @@ -451,6 +455,11 @@ } @NotNull + public ProjectSettings getProjectSettings() { + return projectSettings; + } + + @NotNull public ArchetypeTypeSet getArchetypeTypeSet() { return archetypeTypeSet; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |