r132 - in trunk/msm/src/main: java/org/nuiton/mapstoragemanager java/org/nuiton/mapstoragemanager/plugins java/org/nuiton/mapstoragemanager/ui java/org/nuiton/mapstoragemanager/ui/gui resources resources/i18n resources/icons
Author: fgilet Date: 2010-02-27 01:45:14 +0100 (Sat, 27 Feb 2010) New Revision: 132 Added: trunk/msm/src/main/resources/icons/action-connect.png trunk/msm/src/main/resources/icons/action-disconnect.png Modified: trunk/msm/src/main/java/org/nuiton/mapstoragemanager/Main.java trunk/msm/src/main/java/org/nuiton/mapstoragemanager/MsmConfig.java trunk/msm/src/main/java/org/nuiton/mapstoragemanager/plugins/OurHashMap2.java trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/MainUI.css trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/MainUI.jaxx trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/ApplicationEngine.java trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/MSMNavigationListener.java trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/TableModel.java trunk/msm/src/main/resources/i18n/msm-en_GB.properties trunk/msm/src/main/resources/i18n/msm-fr_FR.properties trunk/msm/src/main/resources/msm.properties Log: Ajout d'images dans le menu. menu "aide", "visitez site" et "?\195?\160 propos" fait partiellement. menu connect et disconnect mis ?\195?\160 jour. contenu d'une table mis ?\195?\160 jour dans un jscrollpane. (donc vu des colonnes) Modified: trunk/msm/src/main/java/org/nuiton/mapstoragemanager/Main.java =================================================================== --- trunk/msm/src/main/java/org/nuiton/mapstoragemanager/Main.java 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/java/org/nuiton/mapstoragemanager/Main.java 2010-02-27 00:45:14 UTC (rev 132) @@ -80,10 +80,10 @@ private void init() { MainUI ui = MainUI.getInstance(); - Locale locale = Main.locale; - if (locale.equals(Locale.FRANCE)){ + Locale localeTemp = Main.locale; + if (localeTemp.equals(Locale.FRANCE)){ ui.getMenuFileLanguageFR().setEnabled(false); - } else if (locale.equals(Locale.UK)){ + } else if (localeTemp.equals(Locale.UK)){ ui.getMenuFileLanguageUK().setEnabled(false); } String message = n_("messageEntry"); Modified: trunk/msm/src/main/java/org/nuiton/mapstoragemanager/MsmConfig.java =================================================================== --- trunk/msm/src/main/java/org/nuiton/mapstoragemanager/MsmConfig.java 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/java/org/nuiton/mapstoragemanager/MsmConfig.java 2010-02-27 00:45:14 UTC (rev 132) @@ -22,6 +22,7 @@ * to use log facility, just put in your code: log.info(\"...\"); */ static private Log log = LogFactory.getLog(MsmConfig.class); + /** * le fichier de configuration de l'application avec les informations sur * le projet (version, license,...) et la configuration des ui (icons, ...) @@ -30,6 +31,8 @@ public MsmConfig() { + //setConfigFileName(APPLICATION_PROPERTIES); + // chargement de la configuration interne InputStream stream = getClass().getResourceAsStream( APPLICATION_PROPERTIES); Modified: trunk/msm/src/main/java/org/nuiton/mapstoragemanager/plugins/OurHashMap2.java =================================================================== --- trunk/msm/src/main/java/org/nuiton/mapstoragemanager/plugins/OurHashMap2.java 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/java/org/nuiton/mapstoragemanager/plugins/OurHashMap2.java 2010-02-27 00:45:14 UTC (rev 132) @@ -41,8 +41,8 @@ @Override public void createColumn(String table, String column) { - mapColumn.put(column, new ArrayList<String>()); if(mapTable.containsKey(table)){ + mapColumn.put(column, new ArrayList<String>()); ArrayList<String> list; list = mapTable.get(table); list.add(column); @@ -53,9 +53,6 @@ @Override public void deleteColumn(String table, String column) { if(mapTable.containsKey(table)){ - /*ArrayList<String> list = mapTable.get(table); - list.remove(column); - mapTable.put(table,list);*/ mapTable.get(table).remove(column); } } @@ -70,11 +67,10 @@ public void put(String table, String column, String key, String content) { if(mapTable.containsKey(table)){ if(mapColumn.containsKey(column)){ - /*ArrayList<String> list; + ArrayList<String> list; list = mapColumn.get(column); list.add(key); - mapColumn.put(column,list);*/ - mapColumn.get(column).add(key); + mapColumn.put(column,list); mapData.put(key, content); } } @@ -108,16 +104,14 @@ @Override public Set<String> getKeys(String table) { - Set<String> keys = null; + Set<String> keys = new HashSet(); Set<String> column = new HashSet(mapTable.get(table)); Iterator i = column.iterator(); while(i.hasNext()){ String columnName = (String)i.next(); - System.out.println("columnName : "+columnName); ArrayList<String> al = mapColumn.get(columnName); - for(String str : al){ - System.out.println("str : "+str); - keys.add(str); + for(int j=0;j<al.size();j++){ + keys.add(al.get(j)); } } return keys; Modified: trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/MainUI.css =================================================================== --- trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/MainUI.css 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/MainUI.css 2010-02-27 00:45:14 UTC (rev 132) @@ -38,12 +38,14 @@ #menuConnect { text:"mapstoragemanager.action.connect"; toolTipText:"mapstoragemanager.action.connect.tip"; + actionIcon:"connect"; mnemonic:C; } #menuDisconnect { text:"mapstoragemanager.action.disconnect"; toolTipText:"mapstoragemanager.action.disconnect.tip"; + actionIcon:"disconnect"; mnemonic:D; } @@ -114,6 +116,11 @@ title:"Map Storage Manager"; } +#toolBar { + visible:false; +} + + JLabel.boldUnderline { font-weight: bold; } Modified: trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/MainUI.jaxx =================================================================== --- trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/MainUI.jaxx 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/MainUI.jaxx 2010-02-27 00:45:14 UTC (rev 132) @@ -8,6 +8,7 @@ import javax.swing.tree.*; import static org.nuiton.i18n.I18n.n_; import javax.swing.JLabel; + import org.nuiton.mapstoragemanager.MsmConfig; ApplicationEngine engine = ApplicationEngine.getInstance(); @@ -36,6 +37,14 @@ } /** + * Access to the config. + * @return instance of the class + */ + public MsmConfig getConfig() { + return getContextValue(MsmConfig.class); + } + + /** * Dispose UI. */ public void dispose(){ @@ -51,17 +60,18 @@ */ public void displayMessage(String message, int code){ this.getMessagesPanel().removeAll(); - JLabel label = new JLabel(message); + /* if (code==0){ - ImageIcon = new ImageIcon("ok_16.png"); + ImageIcon icon = new ImageIcon(getClass().getResource("ok_16.png")); }else if (code==1){ - ImageIcon = new ImageIcon("warning_16.png"); + ImageIcon icon = new ImageIcon(getClass().getResource("warning_16.png")); }else if (code==2){ - ImageIcon = new ImageIcon("cancel_16.png"); + ImageIcon icon = new ImageIcon(getClass().getResource("cancel_16.png")); } */ - //label.setIcon(icon); + //JLabel label = new JLabel(message, icon, SwingConstants.CENTER); + JLabel label = new JLabel(message); this.getMessagesPanel().add(label); } @@ -77,9 +87,9 @@ <JMenuBar> <JMenu id='menuFile'> <JMenuItem id='menuConnect' - onActionPerformed='engine.doSomething()'/> - <JMenuItem id='menuDisconnect' - onActionPerformed='engine.doSomething()'/> + onActionPerformed='engine.showToolBar()'/> + <JMenuItem id='menuDisconnect' enabled='false' + onActionPerformed='engine.disposeToolBar()'/> <JSeparator/> <JMenuItem id='menuExit' onActionPerformed='engine.close()'/> @@ -100,47 +110,46 @@ <JMenu id='menuHelp'> <JMenuItem id='menuHelpHelp' - onActionPerformed='engine.doSomething()'/> + onActionPerformed='engine.showHelp()'/> <JMenuItem id='menuHelpSite' - onActionPerformed='engine.doSomething()'/> + onActionPerformed='engine.gotoSite()'/> <JMenuItem id='menuHelpAbout' - onActionPerformed='engine.doSomething()'/> + onActionPerformed='engine.showAbout()'/> </JMenu> - </JMenuBar> <JPanel layout='{new BorderLayout()}' constraints='BorderLayout.CENTER'> - <JPanel layout='{new BorderLayout()}' id='mainPanel'> - <JToolBar constraints='BorderLayout.NORTH' opaque='true'> - <JLabel text="name base :" actionIcon='database_16' styleClass='boldUnderline' /> - <JAXXComboBox id='nameBase' onActionPerformed='engine.doSomething()' > - <item value='OurHashMap' selected='true'/> - <item value='HBase'/> - <item value='Cassandra'/> - <item value='Other'/> - </JAXXComboBox> - <JLabel text="login :" actionIcon='login_16' styleClass='boldUnderline'/> - <JTextField id='login'/> - <JLabel text="password :" actionIcon='password_16' styleClass='boldUnderline'/> - <JPasswordField id='password'/> - <JButton text="ok" actionIcon='ok_16' onActionPerformed='engine.connection()'/> - </JToolBar> + <JPanel layout='{new BorderLayout()}' id='mainPanel'> + <JToolBar id='toolBar' constraints='BorderLayout.NORTH' opaque='true' > + <JLabel text="name base :" actionIcon='database_16' styleClass='boldUnderline' /> + <JAXXComboBox id='nameBase' onActionPerformed='engine.doSomething()' > + <item value='OurHashMap' selected='true'/> + <item value='HBase'/> + <item value='Cassandra'/> + <item value='Other'/> + </JAXXComboBox> + <JLabel text="login :" actionIcon='login_16' styleClass='boldUnderline'/> + <JTextField id='login'/> + <JLabel text="password :" actionIcon='password_16' styleClass='boldUnderline'/> + <JPasswordField id='password'/> + <JButton text="ok" actionIcon='ok_16' onActionPerformed='engine.connection()'/> + </JToolBar> - <JSplitPane constraints='BorderLayout.CENTER' dividerLocation='200' > - <JScrollPane> - <JTree id='navigation' - model='{new DefaultTreeModel(new DefaultMutableTreeNode("Empty"))}' /> - </JScrollPane> - <JScrollPane > - <JPanel layout='{new BorderLayout()}'> - <JPanel id='tableName' constraints='BorderLayout.NORTH'/> - <JPanel id='tableContent' constraints='BorderLayout.CENTER'/> - <JPanel id='tableTips' constraints='BorderLayout.SOUTH'/> - </JPanel> - </JScrollPane> - </JSplitPane> + <JSplitPane constraints='BorderLayout.CENTER' dividerLocation='200' > + <JScrollPane> + <JTree id='navigation' + model='{new DefaultTreeModel(new DefaultMutableTreeNode(n_("Empty")))}' /> + </JScrollPane> + <JScrollPane> + <JPanel layout='{new BorderLayout()}'> + <JPanel id='tableName' constraints='BorderLayout.NORTH'/> + <JPanel id='tableContent' constraints='BorderLayout.CENTER'/> + <JPanel id='tableTips' constraints='BorderLayout.SOUTH'/> + </JPanel> + </JScrollPane> + </JSplitPane> + </JPanel> + <JPanel id='messagesPanel' constraints='BorderLayout.SOUTH'/> </JPanel> - <JPanel id='messagesPanel' constraints='BorderLayout.SOUTH'/> - </JPanel> </Application> Modified: trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/ApplicationEngine.java =================================================================== --- trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/ApplicationEngine.java 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/ApplicationEngine.java 2010-02-27 00:45:14 UTC (rev 132) @@ -1,5 +1,7 @@ package org.nuiton.mapstoragemanager.ui.gui; +import java.awt.Desktop; +import java.net.URL; import java.util.Iterator; import java.util.Locale; import java.util.Properties; @@ -10,12 +12,15 @@ import javax.swing.JOptionPane; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; +import jaxx.runtime.swing.ErrorDialogUI; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.mapstoragemanager.Main; +import org.nuiton.mapstoragemanager.MsmConfig; import org.nuiton.mapstoragemanager.plugins.OurHashMap2; import org.nuiton.mapstoragemanager.ui.MainUI; import static org.nuiton.i18n.I18n.n_; +import static org.nuiton.i18n.I18n._; /** * Engine Class with methods for application user interface. @@ -26,7 +31,7 @@ /** * Logger. */ - private static final Log LOG = LogFactory.getLog(ApplicationEngine.class); + private static final Log log = LogFactory.getLog(ApplicationEngine.class); /** * current Locale. @@ -48,8 +53,6 @@ */ private static ApplicationEngine instance = null; - //public ImageIcon imgOk = new ImageIcon(getClass().getResource("ok.png")); - /** * Constructor. */ @@ -68,7 +71,7 @@ ohm.put("table1", "column1", "1", "content1"); ohm.put("table1", "column1", "2", "content2"); - ohm.put("table1", "column2", "1", "content3"); + ohm.put("table1", "column2", "3", "content3"); ohm.put("table1", "column2", "4", "content4"); ohm.put("table2", "column3", "5", "content1"); @@ -80,13 +83,6 @@ } /** - * Show the developers. - */ - public final void showGreeting() { - JOptionPane.showMessageDialog(null, "CODE LUTIN"); - } - - /** * Method to close the application. */ public final void close() { @@ -112,11 +108,42 @@ this.application = application; }*/ + /** + * Show toolBar in order to connect. + */ + public void showToolBar(){ + MainUI ui = MainUI.getInstance(); + ui.getToolBar().setVisible(true); + } + + /** + * Hide toolBar in order to disconnect. + */ + public void disposeToolBar(){ + MainUI ui = MainUI.getInstance(); + ui.getToolBar().setVisible(false); + clean(ui); + } + + /** + * Clean the application. + */ + public void clean(MainUI ui){ + ui.getNavigation().setVisible(false); + ui.getTableContent().setVisible(false); + ui.getTableName().setVisible(false); + ui.getTableTips().setVisible(false); + } + /** * Try to connect the user to a database. */ public void connection(){ MainUI ui = MainUI.getInstance(); + + //update menu + ui.getMenuDisconnect().setEnabled(true); + String nameBase = ui.getNameBase().getSelectedJaxxItem().getValue().toString(); String login = ui.getLogin().getText(); char[] password = ui.getPassword().getPassword(); @@ -145,7 +172,7 @@ ui.getNavigation().revalidate(); }else{ //display error - JOptionPane.showMessageDialog(null, n_("jaxxdemo.tree.component")); + JOptionPane.showMessageDialog(null, n_("connectionError")); } } @@ -168,13 +195,66 @@ instance = null; } + /** + * Show help. + */ + public void showHelp() { + String message=n_("No help today, sorry !"); + JOptionPane.showMessageDialog(null, message); + } + /** + * Redirection to site. + */ + public void gotoSite() { + MainUI ui = MainUI.getInstance(); + MsmConfig config = ui.getConfig(); + + URL siteURL = config.getOptionAsURL("application.site.url"); + + log.info(_("jaxxdemo.message.goto.site", siteURL)); + + if (log.isDebugEnabled()) { + log.debug("goto " + siteURL); + } + if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { + try { + Desktop.getDesktop().browse(siteURL.toURI()); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + ErrorDialogUI.showError(ex); + } + } + } + + /** + * Informations about team. + */ + public void showAbout() { + String message="Developers :"+"\n"; + message+=" Gilles Crieloue"+"\n"; + message+=" Amaury Fages"+"\n"; + message+=" Florent Gilet"+"\n"; + message+=" Langlais Dorian"+"\n"; + message+="Version 1.0 Codelutin @ 2009-2010"; + JOptionPane.showMessageDialog(null, message); + } + + //GETTERS AND SETTERS + /** + * + * @return + */ public OurHashMap2 getOurHashMap(){ return ohm; } + /** + * + * @param ohm + */ public void setOurHashMap(OurHashMap2 ohm){ this.ohm = ohm; } Modified: trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/MSMNavigationListener.java =================================================================== --- trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/MSMNavigationListener.java 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/MSMNavigationListener.java 2010-02-27 00:45:14 UTC (rev 132) @@ -5,9 +5,14 @@ package org.nuiton.mapstoragemanager.ui.gui; +import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Dimension; import javax.swing.JLabel; +import javax.swing.JScrollPane; import javax.swing.JTable; +import javax.swing.ScrollPaneLayout; +import javax.swing.SwingUtilities; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.table.TableColumn; @@ -22,9 +27,11 @@ @Override public void valueChanged(TreeSelectionEvent e) { - DefaultMutableTreeNode node = (DefaultMutableTreeNode)MainUI.getInstance().getNavigation().getLastSelectedPathComponent(); - MainUI.getInstance().getTableContent().removeAll(); - MainUI.getInstance().getTableName().removeAll(); + MainUI ui = MainUI.getInstance(); + + DefaultMutableTreeNode node = (DefaultMutableTreeNode)ui.getNavigation().getLastSelectedPathComponent(); + ui.getTableContent().removeAll(); + ui.getTableName().removeAll(); /* if nothing is selected */ if (node == null || node.isRoot()) { @@ -34,16 +41,19 @@ TableModel model = new TableModel(node); JTable jTable = new JTable(model); + JScrollPane scrollPane = new JScrollPane(jTable); + jTable.setFillsViewportHeight(true); + //we check attributes and values of the select table //and display the result into the JPanel named 'tableContent' - MainUI.getInstance().getTableContent().add(jTable); + ui.getTableContent().add(scrollPane); } - MainUI.getInstance().getTableName().add(new JLabel("<html><b><u>"+node.toString()+"</b></u></html>")); - MainUI.getInstance().getTableContent().repaint(); - MainUI.getInstance().getTableContent().revalidate(); + ui.getTableName().add(new JLabel("<html><b><u>"+node.toString()+"</b></u></html>")); + ui.getTableContent().repaint(); + ui.getTableContent().revalidate(); } Modified: trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/TableModel.java =================================================================== --- trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/TableModel.java 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/java/org/nuiton/mapstoragemanager/ui/gui/TableModel.java 2010-02-27 00:45:14 UTC (rev 132) @@ -39,33 +39,28 @@ titres = new String[set.size()]; //content + Set<String> keySetTable = testHashmap2.getKeys(table); Iterator i = set.iterator(); int j=0; int k=0; + System.out.println("set.size() : "+set.size()+" | keySet.size() : "+keySetTable.size()); + data = new String[set.size()][keySetTable.size()]; while(i.hasNext()){ String titreTemp = (String)i.next(); titres[j]=titreTemp; - //content of data - Set<String> keySet = testHashmap2.getKeys(table,titres[j]); + Set<String> keySet = testHashmap2.getKeys(table,titres[j]); Iterator i2 = keySet.iterator(); - - System.out.println(set.size()+" | "+keySet.size()); - if(j==0){ - data = new String[set.size()][keySet.size()]; - } while(i2.hasNext()){ + System.out.println("table = "+table); + System.out.println("titreTemp = "+titreTemp); String str = testHashmap2.get(table,titreTemp,(String)i2.next()); data[j][k]=str; System.out.println("data["+j+"]["+k+"] = "+data[j][k]); k++; - }; + } j++; - k=0; } - - - } Modified: trunk/msm/src/main/resources/i18n/msm-en_GB.properties =================================================================== --- trunk/msm/src/main/resources/i18n/msm-en_GB.properties 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/resources/i18n/msm-en_GB.properties 2010-02-27 00:45:14 UTC (rev 132) @@ -1,9 +1,10 @@ +Empty= Map\ Storage\ Manager=Map Storage Manager -TABLE\ NAME\ \:\ TODO= +No\ help\ today,\ sorry\ \!=No help today, sorry \! connectionError=The connection attempt to failed, please retry \! +jaxxdemo.message.goto.site=Visit site jaxxdemo.tree.component= login\ \:=Login -map\ Storage\ Manager= mapstoragemanager.action.aboutUs=About us mapstoragemanager.action.aboutUs.tip=About Code Lutin mapstoragemanager.action.connect=Connect Modified: trunk/msm/src/main/resources/i18n/msm-fr_FR.properties =================================================================== --- trunk/msm/src/main/resources/i18n/msm-fr_FR.properties 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/resources/i18n/msm-fr_FR.properties 2010-02-27 00:45:14 UTC (rev 132) @@ -1,9 +1,10 @@ +Empty=Vide Map\ Storage\ Manager=Map Storage Manager -TABLE\ NAME\ \:\ TODO= +No\ help\ today,\ sorry\ \!=Pas d'aide pour l'instant, d\u00E9sol\u00E9 \! connectionError=La connexion \u00E0 \u00E9chou\u00E9e, r\u00E9essayez s'il vous pla\u00EEt \! +jaxxdemo.message.goto.site=Visitez le site jaxxdemo.tree.component= login\ \:=Identifiant -map\ Storage\ Manager= mapstoragemanager.action.aboutUs=A propos mapstoragemanager.action.aboutUs.tip=A propos de Code Lutin mapstoragemanager.action.connect=Connexion Added: trunk/msm/src/main/resources/icons/action-connect.png =================================================================== (Binary files differ) Property changes on: trunk/msm/src/main/resources/icons/action-connect.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/msm/src/main/resources/icons/action-disconnect.png =================================================================== (Binary files differ) Property changes on: trunk/msm/src/main/resources/icons/action-disconnect.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/msm/src/main/resources/msm.properties =================================================================== --- trunk/msm/src/main/resources/msm.properties 2010-02-26 14:37:51 UTC (rev 131) +++ trunk/msm/src/main/resources/msm.properties 2010-02-27 00:45:14 UTC (rev 132) @@ -11,4 +11,7 @@ icon.action.exit=action-exit.png icon.action.config=action-config.png icon.action.i18n-fr=action-i18n-fr.png -icon.action.i18n-uk=action-i18n-uk.png \ No newline at end of file +icon.action.i18n-uk=action-i18n-uk.png +icon.action.connect=action-connect.png +icon.action.disconnect=action-disconnect.png +application.site.url=http\://www.nuiton.org/projects/show/mapstoragemanager \ No newline at end of file
participants (1)
-
fgilet@users.nuiton.org