]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.export.ui/src/org/simantics/export/ui/ContentSelectionPage.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.export.ui / src / org / simantics / export / ui / ContentSelectionPage.java
index d86484e1fd8ad696f365256dce151f6f1cf4abbe..1473c02026d97dac18ff08c0df9bef522635d334 100644 (file)
-package org.simantics.export.ui;\r
-\r
-import java.net.MalformedURLException;\r
-import java.net.URL;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.TreeMap;\r
-\r
-import org.eclipse.jface.resource.ImageDescriptor;\r
-import org.eclipse.jface.resource.JFaceResources;\r
-import org.eclipse.jface.resource.LocalResourceManager;\r
-import org.eclipse.jface.wizard.WizardPage;\r
-import org.eclipse.nebula.widgets.grid.Grid;\r
-import org.eclipse.nebula.widgets.grid.GridColumn;\r
-import org.eclipse.nebula.widgets.grid.GridItem;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.SelectionAdapter;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.events.SelectionListener;\r
-import org.eclipse.swt.graphics.Color;\r
-import org.eclipse.swt.graphics.Image;\r
-import org.eclipse.swt.graphics.RGB;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.export.core.ExportContext;\r
-import org.simantics.export.core.error.ExportException;\r
-import org.simantics.export.core.intf.ContentType;\r
-import org.simantics.export.core.intf.Discoverer;\r
-import org.simantics.export.core.intf.Exporter;\r
-import org.simantics.export.core.intf.Format;\r
-import org.simantics.export.core.intf.Publisher;\r
-import org.simantics.export.core.manager.Content;\r
-import org.simantics.export.core.manager.ExportWizardResult;\r
-import org.simantics.export.core.util.ExportQueries;\r
-import org.simantics.export.ui.util.ExportUIQueries;\r
-import org.simantics.utils.datastructures.MapList;\r
-import org.simantics.utils.datastructures.ToStringComparator;\r
-import org.simantics.utils.strings.AlphanumComparator;\r
-import org.simantics.utils.ui.workbench.StringMemento;\r
-\r
-/**\r
- * Show wizard page where content and export format is selected.\r
- *\r
- * @author toni.kalajainen@semantum.fi\r
- */\r
-public class ContentSelectionPage extends WizardPage {\r
-       \r
-       /** Key for preference setting that contains sub-mementos for each content URI. */\r
-       public static final String KEY_FORMAT_SELECTIONS = "org.simantics.modeling.ui.export.wizard.formatSelections";\r
-\r
-       // UI stuff\r
-       LocalResourceManager resourceManager;\r
-       Grid grid;\r
-       \r
-       // Initial data\r
-       ExportContext ctx; \r
-       // Hash-code for the initial data\r
-       String initialSelectionKey;\r
-       Set<Content> initialSelection = new HashSet<Content>();\r
-               \r
-       // Previous selections\r
-       StringMemento formatSelections;\r
-       \r
-       // Initializations\r
-       Collection<String> allModels, selectedModels;\r
-       ToStringComparator toStringComparator = new ToStringComparator();\r
-       MapList<ContentType, String> content; // ContentType -> Content[]\r
-       MapList<ContentType, Format> typeToFormatMap; // ContentType -> Format\r
-       MapList<String, ContentType> contentToTypeMap; // uri -> ContentType\r
-       Map<String, Map<String, String>> labels; // ContentType -> URI -> Label\r
-       MapList<String, String> modelContent; // ModelURI -> ContentURI\r
-       \r
-       // User selections\r
-       List<Content> contentSelection = new ArrayList<Content>();\r
-       \r
-       public ContentSelectionPage(ExportContext ctx) throws ExportException {\r
-               super("Select Content", "Select the PDF Pages and the attachments", null);\r
-               this.ctx = ctx;\r
-               \r
-               init();\r
-       }\r
-       \r
-       void init() throws ExportException {\r
-               try {\r
-                       System.out.println("Found Content Types:");\r
-                       for ( ContentType ct : ctx.eep.contentTypes() ) {\r
-                               System.out.println("   "+ct);\r
-                       }\r
-                       System.out.println();\r
-                       \r
-                       System.out.println("Exporters:");\r
-                       for ( Exporter ex : ctx.eep.exporters() ) {\r
-                               System.out.println("   "+ex);\r
-                       }\r
-                       System.out.println();\r
-\r
-                       System.out.println("Formats:");\r
-                       for ( Format format : ctx.eep.formats() ) {\r
-                               System.out.println("   "+format);\r
-                       }\r
-                       System.out.println();\r
-\r
-                       System.out.println("Discoverers:");\r
-                       for ( Discoverer discoverer : ctx.eep.discoverers() ) {\r
-                               System.out.println("   "+discoverer);\r
-                       }\r
-                       System.out.println();\r
-                       \r
-                       System.out.println("Publishers:");\r
-                       for ( Publisher publisher : ctx.eep.publishers() ) {\r
-                               System.out.println("   "+publisher.id());\r
-                       }\r
-                       System.out.println();\r
-                       \r
-                       // Organize formats by content types - Filter out ContentTypes that don't have exporter and format.\r
-                       System.out.println("Mapped ContentTypes to Exporters:");\r
-                       typeToFormatMap = MapList.use( new TreeMap<ContentType, List<Format>>(toStringComparator) );\r
-                       for ( ContentType ct : ctx.eep.contentTypes() ) {\r
-                               for ( Exporter exp : ctx.eep.getExportersForContentType( ct.id() ) ) {\r
-                                       Format format = ctx.eep.getFormat( exp.formatId() );\r
-                                       if ( format==null ) continue;\r
-                                       System.out.println("    "+ct.id()+" -> "+format.fileext());\r
-                                       if (!typeToFormatMap.contains(ct, format)) typeToFormatMap.add(ct, format);\r
-                               }\r
-                       }\r
-                       System.out.println();\r
-                       \r
-                       // Discover the models in the project\r
-                       allModels = ctx.session.syncRequest( ExportUIQueries.models(ctx.project) );\r
-\r
-                       // Calculate hash for the initial selection\r
-                       int initialContentHash = 0x52f3a45;\r
-                       for ( String content : ctx.selection ) {\r
-                               initialContentHash = 13*initialContentHash + content.hashCode();\r
-                       }\r
-                       initialSelectionKey = "InitialSelection-"+initialContentHash;\r
-                       String sel = ctx.store.get(initialSelectionKey, null);\r
-                       if ( sel != null ) {\r
-                               initialSelection = ExportWizardResult.parse(sel);\r
-                       } else {\r
-                               // First time wizard was called with this selection.\r
-                               // Check in\r
-                               for ( String contentUri : ctx.selection ) {\r
-                                       initialSelection.add( new Content(contentUri, null, "all", null, null, null) );\r
-                               }\r
-                       }\r
-                       \r
-                       // Choose the models from user interface selection\r
-                       selectedModels = new ArrayList<String>();\r
-                       StringBuilder modelsStr = new StringBuilder(); \r
-                       for ( String content : ctx.selection ) {\r
-                               for ( String model : allModels ) {\r
-                                       if ( content.equals(model) || content.startsWith(model + "/") ) {\r
-                                               if ( !selectedModels.contains( model ) ) {\r
-                                                       selectedModels.add( model );\r
-                                                       if ( modelsStr.length()>0 ) modelsStr.append(", ");\r
-                                                       modelsStr.append( model );\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-                       // If user has nothing selected, choose active models\r
-                       if ( selectedModels.isEmpty() ) selectedModels.addAll( ctx.activeModels );\r
-                       // If there are no active models, choose all models\r
-                       if ( selectedModels.isEmpty() ) selectedModels.addAll( allModels );\r
-                       // UI labels\r
-                       labels = new HashMap<String, Map<String, String>>();                    \r
-                       labels.put( "model", ctx.session.syncRequest( ExportQueries.labels( selectedModels ) ) ); // Should Model CT be used for labeling? \r
-                       \r
-                       // Discover contents\r
-                       System.out.println("Discovering content: "+modelsStr);\r
-                       content = MapList.use( new TreeMap<ContentType, List<String>>(toStringComparator) );\r
-                       contentToTypeMap = MapList.use( new TreeMap<String, List<ContentType>>(toStringComparator) );\r
-                       modelContent = MapList.use( new TreeMap<String, List<String>>() );\r
-                       \r
-                       for ( ContentType ct : typeToFormatMap.getKeys() ) {\r
-                               System.out.println("    "+ct.label());\r
-                               for ( Discoverer discoverer : ctx.eep.getDiscoverers( ct.id() )) {\r
-                                       System.out.println("         "+discoverer.toString());\r
-                                       \r
-                                       // Get content Uris\r
-                                       Collection<String> contents = discoverer.discoverContent(ctx, selectedModels);\r
-                                       List<String> contentUris = new ArrayList<String>( contents );\r
-\r
-                                       // Get UI Labels\r
-                                       Map<String, String> lbls = ct.getLabels(ctx, contentUris); \r
-                                       labels.put( ct.id(), lbls );\r
-                                       \r
-                                       // Sort content\r
-                                       IndirectComparator comp = new IndirectComparator();\r
-                                       comp.labels = lbls;\r
-                                       Collections.sort( contentUris, comp );\r
-                                       \r
-                                       for ( String contentId : contentUris ) {\r
-                                               content.add( ct, contentId );\r
-                                               contentToTypeMap.add(contentId, ct);\r
-                                               //modelContent.add(key)\r
-                                               System.out.println("            "+contentId);\r
-                                       }\r
-                                       \r
-                               }\r
-                       }\r
-                       System.out.println();\r
-                                               \r
-                               \r
-               } catch (DatabaseException e) {\r
-                       throw new ExportException(e);\r
-               }\r
-\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void createControl(Composite parent) {\r
-           grid = new Grid(parent, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI);\r
-           grid.setHeaderVisible(true);\r
-           \r
-           resourceManager = new LocalResourceManager(JFaceResources.getResources(), grid);\r
-           Color contentTypeColor = resourceManager.createColor( new RGB(245, 245, 252) );\r
-           GridColumn column = new GridColumn(grid,SWT.NONE);\r
-           column.setTree(true);\r
-           column.setText("Name");\r
-           column.setWidth(200);           \r
-\r
-           // "Pagees"\r
-           assertColumnIndex(1);\r
-                   \r
-           Format pdfFormat = ctx.eep.getFormat("pdf");\r
-           \r
-           \r
-           ImageDescriptor folderID = null;\r
-               try {\r
-                       URL folderUrl = new URL("platform:/plugin/com.famfamfam.silk/icons/folder.png");\r
-                   folderID = ImageDescriptor.createFromURL( folderUrl );\r
-               } catch (MalformedURLException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               \r
-               List<GridItem> selectedNodes = new ArrayList<GridItem>();\r
-           \r
-           // Iterate all models\r
-           for ( String modelUri : contentToTypeMap.getKeys() ) {\r
-               ContentType modelContentType = null;\r
-               for ( ContentType ct : contentToTypeMap.getValues(modelUri) ) {\r
-                       if ( ct.isModel() ) {\r
-                               modelContentType = ct;\r
-                               break;\r
-                       }\r
-               }\r
-               if (modelContentType==null) continue;\r
-               \r
-               // Create Model Node\r
-               String modelLabel = labels.get("model").get(modelUri);\r
-                       GridItem modelNode = newLine(grid, modelLabel, modelUri, modelContentType.id()); \r
-                       setIcon(modelNode, 0, modelContentType.icon(modelUri));\r
-                       modelNode.setToolTipText(0, modelUri);\r
-                       \r
-                       if ( ctx.selection.contains( modelUri ) ) selectedNodes.add( modelNode );\r
-\r
-                       // Columns for formats\r
-                       int column1 = 1;\r
-                       for ( ContentType ct : contentToTypeMap.getValues(modelUri) ) {\r
-                               for ( Format format : typeToFormatMap.getValues(ct) ) {\r
-                                       column1++;\r
-                                       assertColumnIndex( column1 );\r
-                                       modelNode.setText(column1, format.fileext());\r
-                                       modelNode.setGrayed(column1, false);\r
-                                       modelNode.setCheckable(column1, true);\r
-                                       modelNode.setData( Integer.toString(column1), \r
-                                                       new Content(modelUri, ct.id(), format.id(), modelLabel, format.fileext(), modelUri ) );\r
-                                   modelNode.setChecked(column1, hasInitialSelection(modelUri, format.id()));\r
-                                   modelNode.setToolTipText(column1, format.label());\r
-\r
-                                       ImageDescriptor id = format.icon();\r
-                                       if ( id!=null ) {\r
-                                               Image icon = resourceManager.createImage(id);\r
-                                               if ( icon!=null) modelNode.setImage(column1, icon);\r
-                                       }\r
-                               }\r
-                       }\r
-                       \r
-                       for ( ContentType ct : content.getKeys() ) \r
-                       {\r
-                               if ( ct.isModel() ) continue;\r
-                               // ContentType Node\r
-                               GridItem ctNode = newLine(modelNode, ct.label(), modelUri, ct.id());\r
-                               ctNode.setExpanded( true );\r
-                               ctNode.setBackground(0, contentTypeColor);\r
-                               ctNode.setBackground(contentTypeColor);\r
-                               setIcon(ctNode, 0, folderID);\r
-                               int contentCount = 0;\r
-                               ArrayList<Format> contentTypesFormats = new ArrayList<Format>();\r
-                               \r
-                               for ( String contentUri : content.getValues(ct) ) {\r
-                                       // WORKAROUND: Should not be based on URI\r
-                                       if ( !contentUri.startsWith(modelUri) ) continue;\r
-                                       // Content Node\r
-                                       String nodeLabel = labels.get(ct.id()).get(contentUri);\r
-                                       GridItem contentNode = newLine(ctNode, nodeLabel, contentUri, ct.id());\r
-                                       contentCount++;\r
-                                       contentNode.setToolTipText(0, contentUri);\r
-                                       setIcon(contentNode, 0, ct.icon(contentUri));\r
-                                       \r
-                                       if ( ctx.selection.contains( contentUri) ) selectedNodes.add( contentNode );\r
-                               \r
-                                       int columnNumber = 0;\r
-                                       \r
-                                       // PDF Column\r
-                                       List<Format> formats = typeToFormatMap.getValues(ct);\r
-                                       if ( formats.contains( pdfFormat )) {\r
-                                               if ( !contentTypesFormats.contains(pdfFormat) ) contentTypesFormats.add(pdfFormat);\r
-                                               columnNumber++;\r
-                                               assertColumnIndex( columnNumber );\r
-                                               \r
-                                               contentNode.setText(columnNumber, "  "+pdfFormat.fileext());\r
-                                               contentNode.setGrayed(columnNumber, false);\r
-                                           contentNode.setCheckable(columnNumber, true);\r
-                                           contentNode.setChecked(columnNumber, hasInitialSelection(contentUri, pdfFormat.id()) );\r
-                                           contentNode.setToolTipText(columnNumber, pdfFormat.label());\r
-                                               setIcon(contentNode, columnNumber, pdfFormat.icon());\r
-                                                                                               \r
-                                               contentNode.setData(\r
-                                                               Integer.toString(columnNumber), \r
-                                                               new Content(contentUri, ct.id(), pdfFormat.id(), nodeLabel, pdfFormat.fileext(), modelUri ) );\r
-                                               \r
-                                       } else {\r
-                                               if ( !contentTypesFormats.contains(null) ) contentTypesFormats.add(null);\r
-                                               columnNumber++;\r
-                                               assertColumnIndex( columnNumber );\r
-                                       }\r
-                                       \r
-                                       // Attachment Columns\r
-                                       for (Format format : formats ) {\r
-                                               if ( format==pdfFormat ) continue;\r
-                                               if ( !contentTypesFormats.contains(format) ) contentTypesFormats.add(format);\r
-                                               columnNumber++;\r
-                                               assertColumnIndex( columnNumber );\r
-                                               contentNode.setText(columnNumber, "  "+format.fileext());\r
-                                               contentNode.setGrayed(columnNumber, false);\r
-                                           contentNode.setCheckable(columnNumber, true);\r
-                                           contentNode.setChecked(columnNumber, hasInitialSelection(contentUri, format.id()) );\r
-                                           contentNode.setToolTipText(columnNumber, format.label());                                           \r
-                                           setIcon(contentNode, columnNumber, format.icon());\r
-\r
-                                               contentNode.setData(\r
-                                                               Integer.toString(columnNumber), \r
-                                                               new Content(contentUri, ct.id(), format.id(), nodeLabel, format.fileext(), modelUri ) );\r
-                                       }\r
-                               }\r
-                               \r
-                               // Add the *.pdf buttons\r
-                               int columnNumber = 0;\r
-                               Set<GridItem> gis = new HashSet<GridItem>();\r
-                               for ( Format format : contentTypesFormats ) {\r
-                                       columnNumber++;\r
-                                       ctNode.setBackground(columnNumber, contentTypeColor);\r
-                                       if ( format == null ) continue;\r
-                                       ctChecks.add( new CTCheck(ctNode, columnNumber, format) );\r
-                                       ctNode.setCheckable(columnNumber, true);\r
-                                       ctNode.setGrayed(columnNumber, true);\r
-                                       //setIcon(ctNode, columnNumber, format.icon());\r
-                                       gis.add(ctNode);\r
-                                       //ctNode.setData(Integer.toString(columnNumber), format );\r
-                                       //ctNode.setText(columnNumber, "*"+format.fileext());\r
-                               }\r
-                       \r
-                               if ( contentCount == 0 ) {\r
-                                       ctNode.dispose();\r
-                               }\r
-                               \r
-                       }\r
-                       modelNode.setExpanded( true );\r
-           }\r
-           grid.setSelection( selectedNodes.toArray( new GridItem[selectedNodes.size()] ) );\r
-           if ( selectedNodes.size()>0 ) {\r
-               GridItem first = selectedNodes.get(0);\r
-               grid.setFocusItem( first );             \r
-           }\r
-\r
-           grid.addSelectionListener(ctChecksListener);\r
-           /*\r
-           grid.addSelectionListener( new SelectionAdapter() {\r
-                       public void widgetSelected(SelectionEvent e) {\r
-                               if ( e.item == null || e.item instanceof GridItem==false ) return;\r
-                               GridItem gi = (GridItem) e.item;\r
-                               GridColumn column = grid.getColumn( new Point(e.x, e.y) );\r
-                               if ( column == null ) return;\r
-                               int columnIndex = -1;\r
-                               int columnCount = grid.getColumnCount();\r
-                               for ( int i=0; i<columnCount; i++) {\r
-                                       GridColumn gc = grid.getColumn(i);\r
-                                       if ( gc == column ) {\r
-                                               columnIndex = i;\r
-                                               break;\r
-                                       }\r
-                               }\r
-                               System.out.println(e.detail);\r
-                               System.out.println(e);\r
-                               System.out.println(columnIndex);\r
-                               String text = gi.getText(columnIndex);\r
-                               System.out.println(text);\r
-                       }\r
-               });*/\r
-           \r
-        setControl(grid);\r
-        setPageComplete(true);\r
-       }\r
-       \r
-       void setIcon(GridItem node, int index, ImageDescriptor icon) {\r
-               if ( icon == null ) return;\r
-               Image image = resourceManager.createImage(icon);\r
-               if ( image == null ) return;\r
-               node.setImage(index, image);\r
-       }\r
-       \r
-       /**\r
-        * Creates column index if doesn't exist.\r
-        * Column=2, is "Pages"\r
-        * Column>=3, is "Attachement"\r
-        * \r
-        * @param columnIndex\r
-        */\r
-       void assertColumnIndex(int columnIndex) {\r
-               while ( columnIndex >= grid.getColumnCount() ) {\r
-                       int cc = grid.getColumnCount();\r
-                       \r
-                   GridColumn column = new GridColumn(grid, SWT.CHECK);\r
-                   column.setText( cc==1?"Pages":"Attachments");\r
-                   column.setWidth( cc==1?150:200 );\r
-                   \r
-                   for (GridItem gi : grid.getItems()) {\r
-                               gi.setGrayed(cc, true);\r
-                               gi.setCheckable(cc, false);\r
-                   }\r
-                       \r
-               }       \r
-       }\r
-       \r
-       boolean hasInitialSelection(String uri, String formatId) {\r
-               for (Content c : initialSelection) {\r
-                       if ( !c.url.equals( uri ) ) continue;\r
-                       if ( c.formatId.equals("all") || c.formatId.equals(formatId) ) return true;\r
-               }\r
-               return false;\r
-       }\r
-       \r
-       GridItem newLine(Object parent, String label, String url, String contentTypeId) {\r
-               GridItem gi = null;\r
-               if (parent instanceof Grid) {\r
-                       gi = new GridItem( (Grid)parent, SWT.NONE);\r
-               } else {\r
-                       gi = new GridItem( (GridItem)parent, SWT.NONE);\r
-               }\r
-               \r
-               gi.setText( label );\r
-               if ( url!=null || contentTypeId!=null ) gi.setData( new Content(url, contentTypeId, null, label, null, null) );\r
-               for ( int columnIndex=0; columnIndex<grid.getColumnCount(); columnIndex++ ) {\r
-                       gi.setGrayed(columnIndex, true);\r
-                       gi.setCheckable(columnIndex, false);\r
-               }\r
-                               \r
-               return gi;              \r
-       }\r
-               \r
-       public void validatePage() {\r
-               List<Content> newContentSelection = new ArrayList<Content>();                           \r
-               // Get list of content.. something must be checked\r
-               int columnWidth = grid.getColumnCount();\r
-       Set<String> checkedFormats = new HashSet<String>();\r
-           for (GridItem gi : grid.getItems()) {\r
-               /*\r
-               checkedFormats.clear();\r
-               GridItem parentItem = gi.getParentItem();\r
-               if ( parentItem!=null ) {\r
-                       for (int c=0; c<columnWidth; c++) {\r
-                               if ( parentItem.getChecked(c) ) {\r
-                                       Object data = parentItem.getData( Integer.toString(c) );\r
-                                       if ( data==null || data instanceof Format == false ) continue;\r
-                                       Format format = (Format) data;\r
-                                       checkedFormats.add( format.id() );\r
-                               }\r
-                       }\r
-               }*/\r
-               \r
-               for (int c=0; c<columnWidth; c++) {                     \r
-                       Object data = gi.getData( Integer.toString(c) );\r
-                       if ( data==null || data instanceof Content == false ) continue;\r
-                       Content content = (Content) data;                       \r
-                       if ( gi.getChecked(c) || checkedFormats.contains(content.formatId) ) {\r
-                               newContentSelection.add( content );\r
-                       }\r
-               }\r
-               \r
-           }\r
-           \r
-           contentSelection = newContentSelection;\r
-       }\r
-       \r
-       public List<Content> getContentSelection() {\r
-               return contentSelection;\r
-       }\r
-\r
-       public void savePrefs() {\r
-               String str = ExportWizardResult.print( getContentSelection() );\r
-               ctx.store.put(initialSelectionKey, str);\r
-       }\r
-       \r
-       static class IndirectComparator implements Comparator<String> {\r
-               Map<String, String> labels;\r
-\r
-               @Override\r
-               public int compare(String o1, String o2) {\r
-                       String l1 = null, l2 = null;\r
-                       if ( labels != null ) {\r
-                               l1 = labels.get(o1);\r
-                               l2 = labels.get(o2);\r
-                       } \r
-                       if ( l1 == null ) l1 = o1;\r
-                       if ( l2 == null ) l2 = o2;\r
-                       return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(l1, l2);\r
-               }\r
-       }\r
-       \r
-       //// Code for following clicks on ContentType format specific checkboxes\r
-       List<CTCheck> ctChecks = new ArrayList<CTCheck>();\r
-       static class CTCheck {\r
-               GridItem gi;\r
-               int columnNumber;\r
-               Format format;\r
-               boolean lastKnownCheckedStatus = false;\r
-               CTCheck(GridItem gi, int columnNumber, Format format) {\r
-                       this.gi = gi;\r
-                       this.columnNumber = columnNumber;\r
-                       this.format = format;\r
-               }\r
-               boolean previousSelection;\r
-               boolean checkStatus() {\r
-                       return gi.getChecked(columnNumber);\r
-               }\r
-               void setCheck(boolean checked) {\r
-                       gi.setChecked(columnNumber, checked);\r
-               }\r
-       }\r
-       \r
-    SelectionListener ctChecksListener = new SelectionAdapter() {\r
-               public void widgetSelected(SelectionEvent e) {\r
-                       if ( e.item == null || e.item instanceof GridItem==false ) return;\r
-                       int columnWidth = grid.getColumnCount();\r
-                       for ( CTCheck cc : ctChecks ) {\r
-                               boolean checked = cc.checkStatus();\r
-                               if ( checked == cc.lastKnownCheckedStatus ) continue;\r
-                               cc.lastKnownCheckedStatus = checked;\r
-                               \r
-                               for ( GridItem gi : cc.gi.getItems() ) {\r
-                                       for ( int columnNumber = 0; columnNumber<columnWidth; columnNumber++ ) {\r
-                                       Object data = gi.getData( Integer.toString( columnNumber ) );\r
-                                       if ( data==null || data instanceof Content == false ) continue;\r
-                                       Content content = (Content) data;                       \r
-                                               if ( !content.formatId.equals( cc.format.id() )) continue;\r
-                                               gi.setChecked(columnNumber, checked);\r
-                                       }\r
-                               }                               \r
-                       }\r
-                       \r
-               }\r
-       };\r
-       \r
-\r
-       \r
-}\r
+package org.simantics.export.ui;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.nebula.widgets.grid.Grid;
+import org.eclipse.nebula.widgets.grid.GridColumn;
+import org.eclipse.nebula.widgets.grid.GridItem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.export.core.ExportContext;
+import org.simantics.export.core.error.ExportException;
+import org.simantics.export.core.intf.ContentType;
+import org.simantics.export.core.intf.Discoverer;
+import org.simantics.export.core.intf.Exporter;
+import org.simantics.export.core.intf.Format;
+import org.simantics.export.core.intf.Publisher;
+import org.simantics.export.core.manager.Content;
+import org.simantics.export.core.manager.ExportWizardResult;
+import org.simantics.export.core.util.ExportQueries;
+import org.simantics.export.ui.util.ExportUIQueries;
+import org.simantics.utils.datastructures.MapList;
+import org.simantics.utils.datastructures.ToStringComparator;
+import org.simantics.utils.strings.AlphanumComparator;
+import org.simantics.utils.ui.workbench.StringMemento;
+
+/**
+ * Show wizard page where content and export format is selected.
+ *
+ * @author toni.kalajainen@semantum.fi
+ */
+public class ContentSelectionPage extends WizardPage {
+       
+       /** Key for preference setting that contains sub-mementos for each content URI. */
+       public static final String KEY_FORMAT_SELECTIONS = "org.simantics.modeling.ui.export.wizard.formatSelections";
+
+       // UI stuff
+       LocalResourceManager resourceManager;
+       Grid grid;
+       
+       // Initial data
+       ExportContext ctx; 
+       // Hash-code for the initial data
+       String initialSelectionKey;
+       Set<Content> initialSelection = new HashSet<Content>();
+               
+       // Previous selections
+       StringMemento formatSelections;
+       
+       // Initializations
+       Collection<String> allModels, selectedModels;
+       ToStringComparator toStringComparator = new ToStringComparator();
+       MapList<ContentType, String> content; // ContentType -> Content[]
+       MapList<ContentType, Format> typeToFormatMap; // ContentType -> Format
+       MapList<String, ContentType> contentToTypeMap; // uri -> ContentType
+       Map<String, Map<String, String>> labels; // ContentType -> URI -> Label
+       MapList<String, String> modelContent; // ModelURI -> ContentURI
+       
+       // User selections
+       List<Content> contentSelection = new ArrayList<Content>();
+       
+       public ContentSelectionPage(ExportContext ctx) throws ExportException {
+               super("Select Content", "Select the PDF Pages and the attachments", null);
+               this.ctx = ctx;
+               
+               init();
+       }
+       
+       void init() throws ExportException {
+               try {
+                       System.out.println("Found Content Types:");
+                       for ( ContentType ct : ctx.eep.contentTypes() ) {
+                               System.out.println("   "+ct);
+                       }
+                       System.out.println();
+                       
+                       System.out.println("Exporters:");
+                       for ( Exporter ex : ctx.eep.exporters() ) {
+                               System.out.println("   "+ex);
+                       }
+                       System.out.println();
+
+                       System.out.println("Formats:");
+                       for ( Format format : ctx.eep.formats() ) {
+                               System.out.println("   "+format);
+                       }
+                       System.out.println();
+
+                       System.out.println("Discoverers:");
+                       for ( Discoverer discoverer : ctx.eep.discoverers() ) {
+                               System.out.println("   "+discoverer);
+                       }
+                       System.out.println();
+                       
+                       System.out.println("Publishers:");
+                       for ( Publisher publisher : ctx.eep.publishers() ) {
+                               System.out.println("   "+publisher.id());
+                       }
+                       System.out.println();
+                       
+                       // Organize formats by content types - Filter out ContentTypes that don't have exporter and format.
+                       System.out.println("Mapped ContentTypes to Exporters:");
+                       typeToFormatMap = MapList.use( new TreeMap<ContentType, List<Format>>(toStringComparator) );
+                       for ( ContentType ct : ctx.eep.contentTypes() ) {
+                               for ( Exporter exp : ctx.eep.getExportersForContentType( ct.id() ) ) {
+                                       Format format = ctx.eep.getFormat( exp.formatId() );
+                                       if ( format==null ) continue;
+                                       System.out.println("    "+ct.id()+" -> "+format.fileext());
+                                       if (!typeToFormatMap.contains(ct, format)) typeToFormatMap.add(ct, format);
+                               }
+                       }
+                       System.out.println();
+                       
+                       // Discover the models in the project
+                       allModels = ctx.session.syncRequest( ExportUIQueries.models(ctx.project) );
+
+                       // Calculate hash for the initial selection
+                       int initialContentHash = 0x52f3a45;
+                       for ( String content : ctx.selection ) {
+                               initialContentHash = 13*initialContentHash + content.hashCode();
+                       }
+                       initialSelectionKey = "InitialSelection-"+initialContentHash;
+                       String sel = ctx.store.get(initialSelectionKey, null);
+                       if ( sel != null ) {
+                               initialSelection = ExportWizardResult.parse(sel);
+                       } else {
+                               // First time wizard was called with this selection.
+                               // Check in
+                               for ( String contentUri : ctx.selection ) {
+                                       initialSelection.add( new Content(contentUri, null, "all", null, null, null) );
+                               }
+                       }
+                       
+                       // Choose the models from user interface selection
+                       selectedModels = new ArrayList<String>();
+                       StringBuilder modelsStr = new StringBuilder(); 
+                       for ( String content : ctx.selection ) {
+                               for ( String model : allModels ) {
+                                       if ( content.equals(model) || content.startsWith(model + "/") ) {
+                                               if ( !selectedModels.contains( model ) ) {
+                                                       selectedModels.add( model );
+                                                       if ( modelsStr.length()>0 ) modelsStr.append(", ");
+                                                       modelsStr.append( model );
+                                               }
+                                       }
+                               }
+                       }
+                       // If user has nothing selected, choose active models
+                       if ( selectedModels.isEmpty() ) selectedModels.addAll( ctx.activeModels );
+                       // If there are no active models, choose all models
+                       if ( selectedModels.isEmpty() ) selectedModels.addAll( allModels );
+                       // UI labels
+                       labels = new HashMap<String, Map<String, String>>();                    
+                       labels.put( "model", ctx.session.syncRequest( ExportQueries.labels( selectedModels ) ) ); // Should Model CT be used for labeling? 
+                       
+                       // Discover contents
+                       System.out.println("Discovering content: "+modelsStr);
+                       content = MapList.use( new TreeMap<ContentType, List<String>>(toStringComparator) );
+                       contentToTypeMap = MapList.use( new TreeMap<String, List<ContentType>>(toStringComparator) );
+                       modelContent = MapList.use( new TreeMap<String, List<String>>() );
+                       
+                       for ( ContentType ct : typeToFormatMap.getKeys() ) {
+                               System.out.println("    "+ct.label());
+                               for ( Discoverer discoverer : ctx.eep.getDiscoverers( ct.id() )) {
+                                       System.out.println("         "+discoverer.toString());
+                                       
+                                       // Get content Uris
+                                       Collection<String> contents = discoverer.discoverContent(ctx, selectedModels);
+                                       List<String> contentUris = new ArrayList<String>( contents );
+
+                                       // Get UI Labels
+                                       Map<String, String> lbls = ct.getLabels(ctx, contentUris); 
+                                       labels.put( ct.id(), lbls );
+                                       
+                                       // Sort content
+                                       IndirectComparator comp = new IndirectComparator();
+                                       comp.labels = lbls;
+                                       Collections.sort( contentUris, comp );
+                                       
+                                       for ( String contentId : contentUris ) {
+                                               content.add( ct, contentId );
+                                               contentToTypeMap.add(contentId, ct);
+                                               //modelContent.add(key)
+                                               System.out.println("            "+contentId);
+                                       }
+                                       
+                               }
+                       }
+                       System.out.println();
+                                               
+                               
+               } catch (DatabaseException e) {
+                       throw new ExportException(e);
+               }
+
+               
+       }
+       
+       @Override
+       public void createControl(Composite parent) {
+           grid = new Grid(parent, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI);
+           grid.setHeaderVisible(true);
+           
+           resourceManager = new LocalResourceManager(JFaceResources.getResources(), grid);
+           Color contentTypeColor = resourceManager.createColor( new RGB(245, 245, 252) );
+           GridColumn column = new GridColumn(grid,SWT.NONE);
+           column.setTree(true);
+           column.setText("Name");
+           column.setWidth(200);           
+
+           // "Pagees"
+           assertColumnIndex(1);
+                   
+           Format pdfFormat = ctx.eep.getFormat("pdf");
+           
+           
+           ImageDescriptor folderID = null;
+               try {
+                       URL folderUrl = new URL("platform:/plugin/com.famfamfam.silk/icons/folder.png");
+                   folderID = ImageDescriptor.createFromURL( folderUrl );
+               } catch (MalformedURLException e) {
+                       e.printStackTrace();
+               }
+               
+               List<GridItem> selectedNodes = new ArrayList<GridItem>();
+           
+           // Iterate all models
+           for ( String modelUri : contentToTypeMap.getKeys() ) {
+               ContentType modelContentType = null;
+               for ( ContentType ct : contentToTypeMap.getValues(modelUri) ) {
+                       if ( ct.isModel() ) {
+                               modelContentType = ct;
+                               break;
+                       }
+               }
+               if (modelContentType==null) continue;
+               
+               // Create Model Node
+               String modelLabel = labels.get("model").get(modelUri);
+                       GridItem modelNode = newLine(grid, modelLabel, modelUri, modelContentType.id()); 
+                       setIcon(modelNode, 0, modelContentType.icon(modelUri));
+                       modelNode.setToolTipText(0, modelUri);
+                       
+                       if ( ctx.selection.contains( modelUri ) ) selectedNodes.add( modelNode );
+
+                       // Columns for formats
+                       int column1 = 1;
+                       for ( ContentType ct : contentToTypeMap.getValues(modelUri) ) {
+                               for ( Format format : typeToFormatMap.getValues(ct) ) {
+                                       column1++;
+                                       assertColumnIndex( column1 );
+                                       modelNode.setText(column1, format.fileext());
+                                       modelNode.setGrayed(column1, false);
+                                       modelNode.setCheckable(column1, true);
+                                       modelNode.setData( Integer.toString(column1), 
+                                                       new Content(modelUri, ct.id(), format.id(), modelLabel, format.fileext(), modelUri ) );
+                                   modelNode.setChecked(column1, hasInitialSelection(modelUri, format.id()));
+                                   modelNode.setToolTipText(column1, format.label());
+
+                                       ImageDescriptor id = format.icon();
+                                       if ( id!=null ) {
+                                               Image icon = resourceManager.createImage(id);
+                                               if ( icon!=null) modelNode.setImage(column1, icon);
+                                       }
+                               }
+                       }
+                       
+                       for ( ContentType ct : content.getKeys() ) 
+                       {
+                               if ( ct.isModel() ) continue;
+                               // ContentType Node
+                               GridItem ctNode = newLine(modelNode, ct.label(), modelUri, ct.id());
+                               ctNode.setExpanded( true );
+                               ctNode.setBackground(0, contentTypeColor);
+                               ctNode.setBackground(contentTypeColor);
+                               setIcon(ctNode, 0, folderID);
+                               int contentCount = 0;
+                               ArrayList<Format> contentTypesFormats = new ArrayList<Format>();
+                               
+                               for ( String contentUri : content.getValues(ct) ) {
+                                       // WORKAROUND: Should not be based on URI
+                                       if ( !contentUri.startsWith(modelUri) ) continue;
+                                       // Content Node
+                                       String nodeLabel = labels.get(ct.id()).get(contentUri);
+                                       GridItem contentNode = newLine(ctNode, nodeLabel, contentUri, ct.id());
+                                       contentCount++;
+                                       contentNode.setToolTipText(0, contentUri);
+                                       setIcon(contentNode, 0, ct.icon(contentUri));
+                                       
+                                       if ( ctx.selection.contains( contentUri) ) selectedNodes.add( contentNode );
+                               
+                                       int columnNumber = 0;
+                                       
+                                       // PDF Column
+                                       List<Format> formats = typeToFormatMap.getValues(ct);
+                                       if ( formats.contains( pdfFormat )) {
+                                               if ( !contentTypesFormats.contains(pdfFormat) ) contentTypesFormats.add(pdfFormat);
+                                               columnNumber++;
+                                               assertColumnIndex( columnNumber );
+                                               
+                                               contentNode.setText(columnNumber, "  "+pdfFormat.fileext());
+                                               contentNode.setGrayed(columnNumber, false);
+                                           contentNode.setCheckable(columnNumber, true);
+                                           contentNode.setChecked(columnNumber, hasInitialSelection(contentUri, pdfFormat.id()) );
+                                           contentNode.setToolTipText(columnNumber, pdfFormat.label());
+                                               setIcon(contentNode, columnNumber, pdfFormat.icon());
+                                                                                               
+                                               contentNode.setData(
+                                                               Integer.toString(columnNumber), 
+                                                               new Content(contentUri, ct.id(), pdfFormat.id(), nodeLabel, pdfFormat.fileext(), modelUri ) );
+                                               
+                                       } else {
+                                               if ( !contentTypesFormats.contains(null) ) contentTypesFormats.add(null);
+                                               columnNumber++;
+                                               assertColumnIndex( columnNumber );
+                                       }
+                                       
+                                       // Attachment Columns
+                                       for (Format format : formats ) {
+                                               if ( format==pdfFormat ) continue;
+                                               if ( !contentTypesFormats.contains(format) ) contentTypesFormats.add(format);
+                                               columnNumber++;
+                                               assertColumnIndex( columnNumber );
+                                               contentNode.setText(columnNumber, "  "+format.fileext());
+                                               contentNode.setGrayed(columnNumber, false);
+                                           contentNode.setCheckable(columnNumber, true);
+                                           contentNode.setChecked(columnNumber, hasInitialSelection(contentUri, format.id()) );
+                                           contentNode.setToolTipText(columnNumber, format.label());                                           
+                                           setIcon(contentNode, columnNumber, format.icon());
+
+                                               contentNode.setData(
+                                                               Integer.toString(columnNumber), 
+                                                               new Content(contentUri, ct.id(), format.id(), nodeLabel, format.fileext(), modelUri ) );
+                                       }
+                               }
+                               
+                               // Add the *.pdf buttons
+                               int columnNumber = 0;
+                               Set<GridItem> gis = new HashSet<GridItem>();
+                               for ( Format format : contentTypesFormats ) {
+                                       columnNumber++;
+                                       ctNode.setBackground(columnNumber, contentTypeColor);
+                                       if ( format == null ) continue;
+                                       ctChecks.add( new CTCheck(ctNode, columnNumber, format) );
+                                       ctNode.setCheckable(columnNumber, true);
+                                       ctNode.setGrayed(columnNumber, true);
+                                       //setIcon(ctNode, columnNumber, format.icon());
+                                       gis.add(ctNode);
+                                       //ctNode.setData(Integer.toString(columnNumber), format );
+                                       //ctNode.setText(columnNumber, "*"+format.fileext());
+                               }
+                       
+                               if ( contentCount == 0 ) {
+                                       ctNode.dispose();
+                               }
+                               
+                       }
+                       modelNode.setExpanded( true );
+           }
+           grid.setSelection( selectedNodes.toArray( new GridItem[selectedNodes.size()] ) );
+           if ( selectedNodes.size()>0 ) {
+               GridItem first = selectedNodes.get(0);
+               grid.setFocusItem( first );             
+           }
+
+           grid.addSelectionListener(ctChecksListener);
+           /*
+           grid.addSelectionListener( new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               if ( e.item == null || e.item instanceof GridItem==false ) return;
+                               GridItem gi = (GridItem) e.item;
+                               GridColumn column = grid.getColumn( new Point(e.x, e.y) );
+                               if ( column == null ) return;
+                               int columnIndex = -1;
+                               int columnCount = grid.getColumnCount();
+                               for ( int i=0; i<columnCount; i++) {
+                                       GridColumn gc = grid.getColumn(i);
+                                       if ( gc == column ) {
+                                               columnIndex = i;
+                                               break;
+                                       }
+                               }
+                               System.out.println(e.detail);
+                               System.out.println(e);
+                               System.out.println(columnIndex);
+                               String text = gi.getText(columnIndex);
+                               System.out.println(text);
+                       }
+               });*/
+           
+        setControl(grid);
+        setPageComplete(true);
+       }
+       
+       void setIcon(GridItem node, int index, ImageDescriptor icon) {
+               if ( icon == null ) return;
+               Image image = resourceManager.createImage(icon);
+               if ( image == null ) return;
+               node.setImage(index, image);
+       }
+       
+       /**
+        * Creates column index if doesn't exist.
+        * Column=2, is "Pages"
+        * Column>=3, is "Attachement"
+        * 
+        * @param columnIndex
+        */
+       void assertColumnIndex(int columnIndex) {
+               while ( columnIndex >= grid.getColumnCount() ) {
+                       int cc = grid.getColumnCount();
+                       
+                   GridColumn column = new GridColumn(grid, SWT.CHECK);
+                   column.setText( cc==1?"Pages":"Attachments");
+                   column.setWidth( cc==1?150:200 );
+                   
+                   for (GridItem gi : grid.getItems()) {
+                               gi.setGrayed(cc, true);
+                               gi.setCheckable(cc, false);
+                   }
+                       
+               }       
+       }
+       
+       boolean hasInitialSelection(String uri, String formatId) {
+               for (Content c : initialSelection) {
+                       if ( !c.url.equals( uri ) ) continue;
+                       if ( c.formatId.equals("all") || c.formatId.equals(formatId) ) return true;
+               }
+               return false;
+       }
+       
+       GridItem newLine(Object parent, String label, String url, String contentTypeId) {
+               GridItem gi = null;
+               if (parent instanceof Grid) {
+                       gi = new GridItem( (Grid)parent, SWT.NONE);
+               } else {
+                       gi = new GridItem( (GridItem)parent, SWT.NONE);
+               }
+               
+               gi.setText( label );
+               if ( url!=null || contentTypeId!=null ) gi.setData( new Content(url, contentTypeId, null, label, null, null) );
+               for ( int columnIndex=0; columnIndex<grid.getColumnCount(); columnIndex++ ) {
+                       gi.setGrayed(columnIndex, true);
+                       gi.setCheckable(columnIndex, false);
+               }
+                               
+               return gi;              
+       }
+               
+       public void validatePage() {
+               List<Content> newContentSelection = new ArrayList<Content>();                           
+               // Get list of content.. something must be checked
+               int columnWidth = grid.getColumnCount();
+       Set<String> checkedFormats = new HashSet<String>();
+           for (GridItem gi : grid.getItems()) {
+               /*
+               checkedFormats.clear();
+               GridItem parentItem = gi.getParentItem();
+               if ( parentItem!=null ) {
+                       for (int c=0; c<columnWidth; c++) {
+                               if ( parentItem.getChecked(c) ) {
+                                       Object data = parentItem.getData( Integer.toString(c) );
+                                       if ( data==null || data instanceof Format == false ) continue;
+                                       Format format = (Format) data;
+                                       checkedFormats.add( format.id() );
+                               }
+                       }
+               }*/
+               
+               for (int c=0; c<columnWidth; c++) {                     
+                       Object data = gi.getData( Integer.toString(c) );
+                       if ( data==null || data instanceof Content == false ) continue;
+                       Content content = (Content) data;                       
+                       if ( gi.getChecked(c) || checkedFormats.contains(content.formatId) ) {
+                               newContentSelection.add( content );
+                       }
+               }
+               
+           }
+           
+           contentSelection = newContentSelection;
+       }
+       
+       public List<Content> getContentSelection() {
+               return contentSelection;
+       }
+
+       public void savePrefs() {
+               String str = ExportWizardResult.print( getContentSelection() );
+               ctx.store.put(initialSelectionKey, str);
+       }
+       
+       static class IndirectComparator implements Comparator<String> {
+               Map<String, String> labels;
+
+               @Override
+               public int compare(String o1, String o2) {
+                       String l1 = null, l2 = null;
+                       if ( labels != null ) {
+                               l1 = labels.get(o1);
+                               l2 = labels.get(o2);
+                       } 
+                       if ( l1 == null ) l1 = o1;
+                       if ( l2 == null ) l2 = o2;
+                       return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(l1, l2);
+               }
+       }
+       
+       //// Code for following clicks on ContentType format specific checkboxes
+       List<CTCheck> ctChecks = new ArrayList<CTCheck>();
+       static class CTCheck {
+               GridItem gi;
+               int columnNumber;
+               Format format;
+               boolean lastKnownCheckedStatus = false;
+               CTCheck(GridItem gi, int columnNumber, Format format) {
+                       this.gi = gi;
+                       this.columnNumber = columnNumber;
+                       this.format = format;
+               }
+               boolean previousSelection;
+               boolean checkStatus() {
+                       return gi.getChecked(columnNumber);
+               }
+               void setCheck(boolean checked) {
+                       gi.setChecked(columnNumber, checked);
+               }
+       }
+       
+    SelectionListener ctChecksListener = new SelectionAdapter() {
+               public void widgetSelected(SelectionEvent e) {
+                       if ( e.item == null || e.item instanceof GridItem==false ) return;
+                       int columnWidth = grid.getColumnCount();
+                       for ( CTCheck cc : ctChecks ) {
+                               boolean checked = cc.checkStatus();
+                               if ( checked == cc.lastKnownCheckedStatus ) continue;
+                               cc.lastKnownCheckedStatus = checked;
+                               
+                               for ( GridItem gi : cc.gi.getItems() ) {
+                                       for ( int columnNumber = 0; columnNumber<columnWidth; columnNumber++ ) {
+                                       Object data = gi.getData( Integer.toString( columnNumber ) );
+                                       if ( data==null || data instanceof Content == false ) continue;
+                                       Content content = (Content) data;                       
+                                               if ( !content.formatId.equals( cc.format.id() )) continue;
+                                               gi.setChecked(columnNumber, checked);
+                                       }
+                               }                               
+                       }
+                       
+               }
+       };
+       
+
+       
+}