Changeset 25765 in osm for applications/editors/josm


Ignore:
Timestamp:
2011-04-01T16:47:35+02:00 (14 years ago)
Author:
guardian
Message:

video part now fuly functional

Location:
applications/editors/josm/plugins/videomapping
Files:
5 added
1 deleted
4 edited
4 moved

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/videomapping/src/org/openstreetmap/josm/plugins/videomapping/VideoPlugin.java

    r25742 r25765  
    4949
    5050//Here we manage properties and start the other classes
    51 public class VideoMappingPlugin extends Plugin implements LayerChangeListener{
    52       private JMenu VMenu,VDeinterlacer;
    53       private GpxLayer GpsLayer;
    54       private JosmAction VAdd,VRemove,VStart,Vbackward,Vforward,VJump,Vfaster,Vslower,Vloop;
    55       private JRadioButtonMenuItem VIntBob,VIntNone,VIntLinear;
    56       private JCheckBoxMenuItem VCenterIcon,VSubTitles;
    57       private JMenuItem VJumpLength,VLoopLength;
    58       private GPSVideoPlayer player;
    59       private PositionLayer layer;
    60       private final String VM_DEINTERLACER="videomapping.deinterlacer"; //where we store settings
    61       private final String VM_MRU="videomapping.mru";
    62       private final String VM_AUTOCENTER="videomapping.autocenter";
    63       private final String VM_JUMPLENGTH="videomapping.jumplength";
    64       private final String VM_LOOPLENGTH="videomapping.looplength";
    65       private String deinterlacer;
    66       private boolean autocenter;
    67       private Integer jumplength,looplength;
    68       private String mru;
    69       //TODO What more to store during sessions? Size/Position
     51public class VideoPlugin extends Plugin implements LayerChangeListener{
     52
     53        public VideoPlugin(PluginInformation info) {
     54                super(info);
     55                // TODO Auto-generated constructor stub
     56        }
     57
     58        public void activeLayerChange(Layer arg0, Layer arg1) {
     59                // TODO Auto-generated method stub
     60               
     61        }
     62
     63        public void layerAdded(Layer arg0) {
     64                // TODO Auto-generated method stub
     65               
     66        }
     67
     68        public void layerRemoved(Layer arg0) {
     69                // TODO Auto-generated method stub
     70               
     71        }
    7072     
    71 
    72     public VideoMappingPlugin(PluginInformation info) {
    73         super(info);
    74        
    75         MapView.addLayerChangeListener(this);
    76         //Register for GPS menu
    77         VMenu = Main.main.menu.addMenu(" Video", KeyEvent.VK_V, Main.main.menu.defaultMenuPos,ht("/Plugin/Videomapping"));//TODO no more ugly " video" hack
    78         VMenu.setEnabled(false);
    79         addMenuItems();
    80         enableControlMenus(false);
    81         loadSettings();
    82         applySettings();
    83         //further plugin informations are provided by build.xml properties
    84         //NativeLibrary.addSearchPath("vlc", "C:\\Programme\\Video\\VLC"); // this should be the directory that contains libvlc.dll
    85         NativeLibrary.addSearchPath("libvlc", WindowsRuntimeUtil.getVlcInstallDir());
    86     }
    87            
    88     //only use with GPS and own layers
    89     public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    90         VMenu.setEnabled(true);
    91         if (newLayer instanceof GpxLayer)
    92         {
    93             VAdd.setEnabled(true);
    94             GpsLayer=((GpxLayer) newLayer);           
    95             //TODO append to GPS Layer menu
    96         }       
    97     }
    98 
    99     public void layerAdded(Layer arg0) {
    100         activeLayerChange(null,arg0);
    101     }
    102 
    103     public void layerRemoved(Layer arg0) {
    104         if(Main.main.getActiveLayer()==null)    VMenu.setEnabled(false);
    105     } //well ok we have allready a local copy of the GPS track....
    106 
    107     //register main controls
    108     private void addMenuItems() {
    109         VAdd= new JosmAction(tr("Import Video"),"videomapping",tr("Sync a video against this GPS track"),null,false) {
    110             private static final long serialVersionUID = 1L;
    111 
    112             public void actionPerformed(ActionEvent arg0) {                 
    113                     JFileChooser fc = new JFileChooser(mru);
    114                     fc.setSelectedFile(new File(mru));
    115                     if(fc.showOpenDialog(Main.main.parent)!=JFileChooser.CANCEL_OPTION)
    116                     {
    117                         //save selected path
    118                         mru=fc.getSelectedFile().getAbsolutePath();
    119                         Main.pref.put(VM_MRU, mru);
    120                         enableControlMenus(true);
    121                         layer = new PositionLayer(fc.getSelectedFile(),GpsLayer);
    122                         Main.main.addLayer(layer);
    123                         //TODO Check here if we can sync allready now
    124                         VAdd.setEnabled(false);
    125                         VRemove.setEnabled(true);
    126                         layer.getVideoPlayer().setSubtitleAction(VSubTitles);
    127                         player=layer.getVideoPlayer();
    128                     }
    129                 }
    130        
    131         };
    132         VRemove= new JosmAction(tr("Remove Video"),"videomapping",tr("removes current video from layer"),null,false) {
    133             private static final long serialVersionUID = 1L;
    134 
    135             public void actionPerformed(ActionEvent arg0) {
    136                 player.removeVideo();
    137             }
    138         };
    139        
    140         VStart = new JosmAction(tr("Play/Pause"), "audio-playpause", tr("starts/pauses video playback"),
    141                 Shortcut.registerShortcut("videomapping:startstop","Video: "+tr("Play/Pause"),KeyEvent.VK_NUMPAD5, Shortcut.GROUP_DIRECT), false) {
    142            
    143             public void actionPerformed(ActionEvent e) {                               
    144                 if(player.playing()) player.pause(); else player.play();
    145             }
    146         };
    147         Vbackward = new JosmAction(tr("Backward"), "audio-prev", tr("jumps n sec back"),
    148                 Shortcut.registerShortcut("videomapping:backward","Video: "+tr("Backward"),KeyEvent.VK_NUMPAD4, Shortcut.GROUP_DIRECT), false) {
    149             public void actionPerformed(ActionEvent e) {
    150                 player.backward();
    151             }
    152         };
    153         Vforward= new JosmAction(tr("Forward"), "audio-next", tr("jumps n sec forward"),
    154                 Shortcut.registerShortcut("videomapping:forward","Video: "+tr("Forward"),KeyEvent.VK_NUMPAD6, Shortcut.GROUP_DIRECT), false) {
    155            
    156             public void actionPerformed(ActionEvent e) {
    157                 player.forward();
    158                            
    159             }
    160         };
    161         Vfaster= new JosmAction(tr("Faster"), "audio-faster", tr("faster playback"),
    162                 Shortcut.registerShortcut("videomapping:faster","Video: "+tr("Faster"),KeyEvent.VK_NUMPAD8, Shortcut.GROUP_DIRECT), false) {
    163            
    164             public void actionPerformed(ActionEvent e) {
    165                 player.faster();
    166                            
    167             }
    168         };
    169         Vslower= new JosmAction(tr("Slower"), "audio-slower", tr("slower playback"),
    170                 Shortcut.registerShortcut("videomapping:slower","Video: "+tr("Slower"),KeyEvent.VK_NUMPAD2, Shortcut.GROUP_DIRECT), false) {
    171            
    172             public void actionPerformed(ActionEvent e) {
    173                 player.slower();
    174                            
    175             }
    176         };
    177         VJump= new JosmAction(tr("Jump To"), "jumpto", tr("jumps to the entered gps time"),null, false) {         
    178             public void actionPerformed(ActionEvent e) {
    179                 String s;
    180                 try {
    181                 JOptionPane d=new JOptionPane(tr("Jump to"), JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
    182                 final JFormattedTextField inp = new JFormattedTextField(new MaskFormatter("##:##:##"));
    183                 inp.setText(layer.getGPSTime());
    184                 inp.setInputVerifier(new InputVerifier() {                                     
    185                                         @Override
    186                                         public boolean verify(JComponent input) {
    187                                                 return false;
    188                                         }
    189                                 });
    190                 //hack to set the focus
    191                 SwingUtilities.invokeLater(new Runnable() {
    192                     public void run() {
    193                         inp.requestFocus();
    194                     }
    195                 });
    196                 //TODO here we should show the GPS time range to the user
    197                 if(d.showConfirmDialog(Main.main.panel,inp, tr("Jump to"),JOptionPane.OK_CANCEL_OPTION)==JOptionPane.OK_OPTION)
    198                 {
    199                         Date t;
    200                         SimpleDateFormat sdf= new SimpleDateFormat("HH:mm:ss");
    201                         t = sdf.parse(inp.getText());
    202                         if (t!=null)
    203                         {
    204                             player.jumpToGPSTime(t);
    205                         }                       
    206                 }
    207                 } catch (ParseException e1) {
    208                             // TODO Auto-generated catch block
    209                             e1.printStackTrace();
    210                     }
    211 
    212             }
    213                            
    214            
    215         };
    216         Vloop= new JosmAction(tr("Loop"), "loop", tr("loops n sec around current position"),
    217                 Shortcut.registerShortcut("videomapping:loop","Video: "+tr("loop"),KeyEvent.VK_NUMPAD7, Shortcut.GROUP_DIRECT), false) {
    218            
    219             public void actionPerformed(ActionEvent e) {
    220                 player.loop();
    221                            
    222             }
    223         };
    224        
    225         //now the options menu
    226         VCenterIcon = new JCheckBoxMenuItem(new JosmAction(tr("Keep centered"), null, tr("follows the video icon automaticly"),null, false) {
    227            
    228             public void actionPerformed(ActionEvent e) {
    229                 autocenter=VCenterIcon.isSelected();
    230                 player.setAutoCenter(autocenter);
    231                 applySettings();
    232                 saveSettings();
    233                            
    234             }
    235         });
    236         //now the options menu
    237         VSubTitles = new JCheckBoxMenuItem(new JosmAction(tr("Subtitles"), null, tr("Show subtitles in video"),null, false) {
    238            
    239             public void actionPerformed(ActionEvent e) {
    240                 player.toggleSubtitles();
    241                            
    242             }
    243         });
    244        
    245         VJumpLength = new JMenuItem(new JosmAction(tr("Jump length"), null, tr("Set the length of a jump"),null, false) {
    246            
    247             public void actionPerformed(ActionEvent e) {
    248                 Object[] possibilities = {"200", "500", "1000", "2000", "10000"};
    249                 String s = (String)JOptionPane.showInputDialog(Main.parent,tr("Jump in video for x ms"),tr("Jump length"),JOptionPane.QUESTION_MESSAGE,null,possibilities,jumplength);
    250                 jumplength=Integer.getInteger(s);
    251                 applySettings();
    252                 saveSettings();         
    253             }
    254         });
    255        
    256         VLoopLength = new JMenuItem(new JosmAction(tr("Loop length"), null, tr("Set the length around a looppoint"),null, false) {
    257            
    258             public void actionPerformed(ActionEvent e) {
    259                 Object[] possibilities = {"500", "1000", "3000", "5000", "10000"};
    260                 String s = (String)JOptionPane.showInputDialog(Main.parent,tr("Jump in video for x ms"),tr("Loop length"),JOptionPane.QUESTION_MESSAGE,null,possibilities,looplength);
    261                 looplength=Integer.getInteger(s);
    262                 applySettings();
    263                 saveSettings();
    264                            
    265             }
    266         });
    267        
    268         VDeinterlacer= new JMenu("Deinterlacer");
    269         VIntNone= new JRadioButtonMenuItem(new JosmAction(tr("none"), null, tr("no deinterlacing"),null, false) {
    270            
    271             public void actionPerformed(ActionEvent e) {
    272                 deinterlacer=null;
    273                 applySettings();
    274                 saveSettings();
    275             }
    276         });
    277         VIntBob= new JRadioButtonMenuItem(new JosmAction("bob", null, tr("deinterlacing using line doubling"),null, false) {
    278            
    279             public void actionPerformed(ActionEvent e) {
    280                 deinterlacer="bob";
    281                 applySettings();
    282                 saveSettings();
    283             }
    284         });
    285         VIntLinear= new JRadioButtonMenuItem(new JosmAction("linear", null, tr("deinterlacing using linear interpolation"),null, false) {
    286            
    287             public void actionPerformed(ActionEvent e) {
    288                 deinterlacer="linear";
    289                 applySettings();
    290                 saveSettings();
    291             }
    292         });
    293         VDeinterlacer.add(VIntNone);
    294         VDeinterlacer.add(VIntBob);
    295         VDeinterlacer.add(VIntLinear);
    296        
    297         VMenu.add(VAdd);       
    298         VMenu.add(VStart);
    299         VMenu.add(Vbackward);
    300         VMenu.add(Vforward);
    301         VMenu.add(Vfaster);
    302         VMenu.add(Vslower);
    303         VMenu.add(Vloop);
    304         VMenu.add(VJump);
    305         VMenu.addSeparator();
    306         VMenu.add(VCenterIcon);
    307         VMenu.add(VJumpLength);
    308         VMenu.add(VLoopLength);
    309         VMenu.add(VDeinterlacer);
    310         VMenu.add(VSubTitles);
    311        
    312     }
    313    
    314    
    315     //we can only work on our own layer
    316     private void enableControlMenus(boolean enabled)
    317     {
    318         VStart.setEnabled(enabled);
    319         Vbackward.setEnabled(enabled);
    320         Vforward.setEnabled(enabled);
    321         Vloop.setEnabled(enabled);
    322         Vfaster.setEnabled(enabled);
    323         Vslower.setEnabled(enabled);
    324         VJump.setEnabled(enabled);
    325        
    326     }
    327    
    328     //load all properties or set defaults
    329     private void loadSettings() {
    330         String temp;       
    331         temp=Main.pref.get(VM_AUTOCENTER);
    332         if((temp!=null)&&(temp.length()!=0))autocenter=Boolean.getBoolean(temp); else autocenter=false;
    333         temp=Main.pref.get(VM_DEINTERLACER);
    334         if((temp!=null)&&(temp.length()!=0)) deinterlacer=Main.pref.get(temp);
    335         temp=Main.pref.get(VM_JUMPLENGTH);
    336         if((temp!=null)&&(temp.length()!=0)) jumplength=Integer.valueOf(temp); else jumplength=1000;
    337         temp=Main.pref.get(VM_LOOPLENGTH);
    338         if((temp!=null)&&(temp.length()!=0)) looplength=Integer.valueOf(temp); else looplength=6000;
    339         temp=Main.pref.get(VM_MRU);
    340         if((temp!=null)&&(temp.length()!=0)) mru=Main.pref.get(VM_MRU);else mru=System.getProperty("user.home");       
    341     }
    342    
    343     private void applySettings(){
    344         //Internals
    345         if(player!=null)
    346         {
    347             player.setAutoCenter(autocenter);
    348             player.setDeinterlacer(deinterlacer);
    349             player.setJumpLength(jumplength);
    350             player.setLoopLength(looplength);
    351         }
    352         //GUI
    353         VCenterIcon.setSelected(autocenter);
    354         VIntNone.setSelected(true);
    355         if(deinterlacer=="bob")VIntBob.setSelected(true);
    356         if(deinterlacer=="linear")VIntLinear.setSelected(true);
    357        
    358     }
    359    
    360     private void saveSettings(){
    361         Main.pref.put(VM_AUTOCENTER, autocenter);
    362         Main.pref.put(VM_DEINTERLACER, deinterlacer);
    363         Main.pref.put(VM_JUMPLENGTH, jumplength.toString());
    364         Main.pref.put(VM_LOOPLENGTH, looplength.toString());       
    365     }
    36673   
    36774   
  • applications/editors/josm/plugins/videomapping/src/org/openstreetmap/josm/plugins/videomapping/VideoPositionLayer.java

    r25742 r25765  
    3636
    3737//Basic rendering and GPS layer interaction
    38 public class PositionLayer extends Layer implements MouseListener,MouseMotionListener {
    39     private List<WayPoint> ls;
    40     private List<WayPoint> ipos;
    41     public GpsPlayer gps;
    42     private boolean dragIcon=false; //do we move the icon by hand?
    43     private WayPoint iconPosition;
    44     private Point mouse;
    45     private ImageIcon icon;
    46     private SimpleDateFormat gpsTimeCode;
    47     public GPSVideoPlayer gpsVP;
    48        
    49     public PositionLayer(File video, GpxLayer GpsLayer) {
    50         super(video.getName());
    51         ls=copyGPSLayer(GpsLayer.data); //TODO This might be outsourced to a seperated track       
    52         gps= new GpsPlayer(ls);       
    53         icon = new ImageIcon("images/videomapping.png");
    54         gpsTimeCode= new SimpleDateFormat("HH:mm:ss");//TODO replace with DF small
    55         Main.map.mapView.addMouseListener(this);
    56         Main.map.mapView.addMouseMotionListener(this);                         
    57         gpsVP = new GPSVideoPlayer(video, gps);
    58         gps.goTo(0);
    59         ipos=gps.interpolate();
    60         iconPosition=gps.getCurr();       
    61     }
    62    
    63     //make a flat copy
    64     private List<WayPoint> copyGPSLayer(GpxData route)
    65     {
    66         ls = new LinkedList<WayPoint>();
    67         for (GpxTrack trk : route.tracks) {
    68             for (GpxTrackSegment segment : trk.getSegments()) {
    69                 ls.addAll(segment.getWayPoints());
    70             }
    71         }
    72         Collections.sort(ls); //sort basing upon time
    73         return ls;
    74     }
     38public class VideoPositionLayer extends Layer implements MouseListener,MouseMotionListener {
    7539
    76 
    77     @Override
    78     public Icon getIcon() {
    79         return icon;
    80     }
    81 
    82     @Override
    83     public Object getInfoComponent() {
    84         String temp;
    85         String sep=System.getProperty("line.separator");
    86         temp=tr("{0} {1}% of GPS track",gpsVP.getVideo().getName(),gpsVP.getCoverage()*10+sep);
    87         temp=temp+gpsVP.getNativePlayerInfos();
    88         return temp;
    89     }
    90 
    91     @Override
    92         public Action[] getMenuEntries() {
    93         return new Action[]{
    94                 LayerListDialog.getInstance().createActivateLayerAction(this),
    95                 LayerListDialog.getInstance().createShowHideLayerAction(),
    96                 LayerListDialog.getInstance().createDeleteLayerAction(),
    97                 SeparatorLayerAction.INSTANCE,
    98                 //TODO here my stuff
    99                 SeparatorLayerAction.INSTANCE,
    100                 new LayerListPopup.InfoAction(this)};//TODO here infos about the linked videos
     40        public VideoPositionLayer(String name) {
     41                super(name);
     42                // TODO Auto-generated constructor stub
    10143        }
    10244
    103      
     45        @Override
     46        public Icon getIcon() {
     47                // TODO Auto-generated method stub
     48                return null;
     49        }
    10450
     51        @Override
     52        public Object getInfoComponent() {
     53                // TODO Auto-generated method stub
     54                return null;
     55        }
    10556
    106     @Override
    107     public String getToolTipText() {
    108         return tr("Shows current position in the video");
    109     }
     57        @Override
     58        public Action[] getMenuEntries() {
     59                // TODO Auto-generated method stub
     60                return null;
     61        }
    11062
    111     // no merging necessary
    112     @Override
    113     public boolean isMergable(Layer arg0) {
    114         return false;
    115     }
     63        @Override
     64        public String getToolTipText() {
     65                // TODO Auto-generated method stub
     66                return null;
     67        }
    11668
    117     @Override
    118     public void mergeFrom(Layer arg0) {
    119        
    120     }
     69        @Override
     70        public boolean isMergable(Layer arg0) {
     71                // TODO Auto-generated method stub
     72                return false;
     73        }
    12174
    122    
    123    
    124     @Override
    125     //Draw the current position, infos, waypoints
    126     public void paint(Graphics2D g, MapView map, Bounds bound) {
    127         Point p;
    128         //TODO Source out redundant calculations
    129         //draw all GPS points
    130         g.setColor(Color.YELLOW); //new Color(0,255,0,128)
    131         for(WayPoint n: ls) {
    132             p = Main.map.mapView.getPoint(n.getEastNorth());
    133             g.drawOval(p.x - 2, p.y - 2, 4, 4);
    134         }
    135         //draw synced points
    136         g.setColor(Color.GREEN);
    137         for(WayPoint n: ls) {
    138             if(n.attr.containsKey("synced"))
    139             {
    140                 p = Main.map.mapView.getPoint(n.getEastNorth());
    141                 g.drawOval(p.x - 2, p.y - 2, 4, 4);
    142             }
    143         }
    144         //draw current segment points
    145         g.setColor(Color.YELLOW);
    146         if(gps.getPrev()!=null)
    147         {
    148             p = Main.map.mapView.getPoint(gps.getPrev().getEastNorth());
    149             g.drawOval(p.x - 2, p.y - 2, 4, 4);
    150             Point p2 = Main.map.mapView.getPoint(gps.getCurr().getEastNorth());
    151             g.drawLine(p.x, p.y, p2.x, p2.y);
    152         }
    153         if(gps.getNext()!=null)
    154         {
    155             p = Main.map.mapView.getPoint(gps.getNext().getEastNorth());
    156             g.drawOval(p.x - 2, p.y - 2, 4, 4);
    157             Point p2 = Main.map.mapView.getPoint(gps.getCurr().getEastNorth());
    158             g.drawLine(p.x, p.y, p2.x, p2.y);
    159         }
    160         //draw interpolated points
    161         g.setColor(Color.CYAN);
    162         g.setBackground(Color.CYAN);
    163         //LinkedList<WayPoint> ipo=(LinkedList<WayPoint>) gps.getInterpolatedLine(5);
    164         for (WayPoint wp : ipos) {
    165             p=Main.map.mapView.getPoint(wp.getEastNorth());
    166             g.fillArc(p.x, p.y, 4, 4, 0, 360);
    167             //g.drawOval(p.x - 2, p.y - 2, 4, 4);
    168         }
    169         //draw cam icon
    170         g.setColor(Color.RED);
    171         if(dragIcon)
    172         {
    173             if(iconPosition!=null)
    174             {
    175                 p=Main.map.mapView.getPoint(iconPosition.getEastNorth());
    176                 icon.paintIcon(null, g, p.x-icon.getIconWidth()/2, p.y-icon.getIconHeight()/2);             
    177                 //g.drawString(mins.format(iconPosition.getTime()),p.x-10,p.y-10); //TODO when synced we might wan't to use a different layout
    178                 g.drawString(gpsTimeCode.format(iconPosition.getTime()),p.x-15,p.y-15);
    179             }
    180         }
    181         else
    182         {
    183             if (gps.getCurr()!=null){
    184             p=Main.map.mapView.getPoint(gps.getIPO().getEastNorth());
    185             icon.paintIcon(null, g, p.x-icon.getIconWidth()/2, p.y-icon.getIconHeight()/2);         
    186             g.drawString(gpsTimeCode.format(gps.getCurr().getTime()),p.x-15,p.y-15);
    187             }
    188         }
    189     }
    190    
    191     //finds the first waypoint that is nearby the given point
    192     private WayPoint getNearestWayPoint(Point mouse)
    193     {
    194         final int MAX=10;
    195         Point p;
    196         Rectangle rect = new Rectangle(mouse.x-MAX/2,mouse.y-MAX/2,MAX,MAX);
    197         //iterate through all possible notes
    198         for(WayPoint n : ls) //TODO this is not very clever, what better way to find this WP? Hashmaps? Divide and Conquer?
    199         {
    200             p = Main.map.mapView.getPoint(n.getEastNorth());
    201             if (rect.contains(p))
    202             {               
    203                 return n;
    204             }
    205            
    206         }
    207         return null;
    208        
    209     }
    210    
    211     //upper left corner like rectangle
    212     private Rectangle getIconRect()
    213     {
    214         Point p = Main.map.mapView.getPoint(gps.getCurr().getEastNorth());
    215         return new Rectangle(p.x-icon.getIconWidth()/2,p.y-icon.getIconHeight()/2,icon.getIconWidth(),icon.getIconHeight());
    216     }
    217 
    218 
    219     @Override
    220     public void visitBoundingBox(BoundingXYVisitor arg0) {
    221         // TODO don't know what to do here
    222 
    223     }
    224 
    225     public void mouseClicked(MouseEvent e) {       
    226     }
    227 
    228     public void mouseEntered(MouseEvent arg0) {
    229     }
    230 
    231     public void mouseExited(MouseEvent arg0) {
    232     }
    233 
    234     //init drag&drop
    235     public void mousePressed(MouseEvent e) {
    236         if(e.getButton() == MouseEvent.BUTTON1) {
    237             //is it on the cam icon?
    238             if (gps.getCurr()!=null)
    239             {
    240                 if (getIconRect().contains(e.getPoint()))
    241                 {
    242                     mouse=e.getPoint();
    243                     dragIcon=true;
    244                 }
    245             }
    246         }
    247        
    248     }
    249    
    250     //
    251     public void mouseReleased(MouseEvent e) {       
    252         //only leftclicks on our layer
    253         if(e.getButton() == MouseEvent.BUTTON1) {
    254             if(dragIcon)
    255             {
    256                 dragIcon=false;
    257             }
    258             else
    259             {                   
    260                 //simple click
    261                 WayPoint wp = getNearestWayPoint(e.getPoint());                 
    262                 if(wp!=null)
    263                 {
    264                         //jump if unsynced
    265                         if (gpsVP.isSynced())
    266                         {
    267                                 //jump if we know position
    268                         if(wp.attr.containsKey("synced"))
    269                         {
    270                                 gps.goTo(wp);
    271                             if(gpsVP!=null) gpsVP.jumpToGPSTime(new Date(gps.getRelativeTime())); //call videoplayers to set right position
    272                         }
    273                         }
    274                         else
    275                         {
    276                                 //otherwise let user mark possible sync point
    277                                 gps.goTo(wp);
    278                         }
    279                    
    280                 }
    281             }
    282             Main.map.mapView.repaint();
    283         }
    284        
    285     }
    286    
    287     //slide and restrict during movement
    288     public void mouseDragged(MouseEvent e) {       
    289         if(dragIcon)
    290         {           
    291             mouse=e.getPoint();
    292             //restrict to GPS track
    293             iconPosition=gps.getInterpolatedWaypoint(mouse);
    294             Main.map.mapView.repaint();
    295         }
    296     }
    297 
    298     //visualize drag&drop
    299     public void mouseMoved(MouseEvent e) {     
    300         if (gps.getCurr()!=null)
    301         {                       
    302             if (getIconRect().contains(e.getPoint()))
    303             {
    304                 Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    305             }
    306             else
    307             {
    308                 Main.map.mapView.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    309             }
    310         }
    311        
    312     }
    313 
    314         public  void setVideopPlayer(GPSVideoPlayer player) {
    315                 gpsVP=player;
     75        @Override
     76        public void mergeFrom(Layer arg0) {
     77                // TODO Auto-generated method stub
    31678               
    31779        }
    318        
    319         public GPSVideoPlayer getVideoPlayer()
    320         {
    321                 return gpsVP;
     80
     81        @Override
     82        public void paint(Graphics2D arg0, MapView arg1, Bounds arg2) {
     83                // TODO Auto-generated method stub
     84               
    32285        }
    323        
    324         public String getGPSTime()
    325         {
    326                 return gpsTimeCode.format(iconPosition.getTime());
     86
     87        @Override
     88        public void visitBoundingBox(BoundingXYVisitor arg0) {
     89                // TODO Auto-generated method stub
     90               
    32791        }
     92
     93        public void mouseClicked(MouseEvent arg0) {
     94                // TODO Auto-generated method stub
     95               
     96        }
     97
     98        public void mouseEntered(MouseEvent arg0) {
     99                // TODO Auto-generated method stub
     100               
     101        }
     102
     103        public void mouseExited(MouseEvent arg0) {
     104                // TODO Auto-generated method stub
     105               
     106        }
     107
     108        public void mousePressed(MouseEvent arg0) {
     109                // TODO Auto-generated method stub
     110               
     111        }
     112
     113        public void mouseReleased(MouseEvent arg0) {
     114                // TODO Auto-generated method stub
     115               
     116        }
     117
     118        public void mouseDragged(MouseEvent arg0) {
     119                // TODO Auto-generated method stub
     120               
     121        }
     122
     123        public void mouseMoved(MouseEvent arg0) {
     124                // TODO Auto-generated method stub
     125               
     126        }
     127   
    328128}
  • applications/editors/josm/plugins/videomapping/src/org/openstreetmap/josm/plugins/videomapping/video/GPSVideo.java

    r25244 r25765  
    33
    44// a specific synced video
    5 public class GPSVideoFile extends File{
    6     public long offset; //time difference in ms between GPS and Video track
    7    
    8     public GPSVideoFile(File f, long offset) {
    9         super(f.getAbsoluteFile().toString());
    10         this.offset=offset;
    11     }
     5public class GPSVideo {
     6   
    127
    138}
  • applications/editors/josm/plugins/videomapping/src/org/openstreetmap/josm/plugins/videomapping/video/GPSVideoPlayer.java

    r25742 r25765  
    2222public class GPSVideoPlayer
    2323{
    24     Timer t;
    25     TimerTask updateGPS; //sync GPS position here
    26     private GpsPlayer gps;
    27     private SimpleVideoPlayer video;
    28     private JButton syncBtn;
    29     private GPSVideoFile file;
    30     private boolean synced=false; //do we playback the players together?
    31     private JCheckBoxMenuItem subtTitleComponent;
    3224   
    33 
    34     public GPSVideoPlayer(File f, final GpsPlayer pl) {
    35         super();
    36         this.gps = pl;
    37         //test sync
    38         video = new SimpleVideoPlayer();
    39         /*
    40         long gpsT=(9*60+20)*1000;
    41         long videoT=10*60*1000+5*1000;
    42         setFile(new GPSVideoFile(f, gpsT-videoT)); */
    43         setFile(new GPSVideoFile(f, 0L));
    44         //add Sync Button to the Player
    45         syncBtn= new JButton("sync");
    46         syncBtn.setBackground(Color.RED);
    47         syncBtn.addActionListener(new ActionListener() {
    48             //do a sync
    49             public void actionPerformed(ActionEvent e) {
    50                 if (!synced)
    51                 {
    52                         //FIXME doesn't work correctly after a resync
    53                         //determine time offset
    54                         long diff=gps.getRelativeTime()-video.getTime(); //FIXME differenzierter betrachten
    55                         file= new GPSVideoFile(file, diff);
    56                         syncBtn.setBackground(Color.GREEN);
    57                         synced=true;
    58                         markSyncedPoints();
    59                         video.play();
    60                         //gps.play();
    61                 }
    62                 else
    63                 {
    64                         //let user resync again
    65                         synced=false;
    66                         syncBtn.setBackground(null);
    67                 }
    68             }
    69         });
    70         setAsyncMode(true);
    71         video.addComponent(syncBtn);
    72         //a observer to communicate
    73         SimpleVideoPlayer.addObserver(new VideoObserver() { //TODO has o become this
    74 
    75             public void playing(long time) {
    76                 //sync the GPS back
    77                 if(synced) {
    78                         gps.jump(getGPSTime(time));
    79                         gps.jumpIPO(getGPSTime(time));
    80                 }
    81                
    82             }
    83 
    84             public void jumping(long time) {
    85            
    86             }
    87 
    88             //a push way to set video attirbutes
    89             public void metadata(long time, boolean subtitles) {
    90                 if(subtTitleComponent!=null) subtTitleComponent.setSelected(subtitles);             
    91             }
    92            
    93         });
    94         t = new Timer();       
    95     }
    96    
    97     //marks all points that are covered by video AND GPS track
    98     private void markSyncedPoints() {
    99         //GPS or video stream starts first in time?
    100         WayPoint start,end;
    101         long t;
    102         if(gps.getLength()<video.getLength())
    103         {
    104             //GPS is within video timeperiod
    105             start=gps.getWaypoint(0);
    106             end=gps.getWaypoint(gps.getLength());           
    107         }
    108         else
    109         {
    110             //video is within gps timeperiod
    111             t=getGPSTime(0);
    112             if(t<0) t=0;
    113             start=gps.getWaypoint(t);
    114             end=gps.getWaypoint(getGPSTime(video.getLength()));
    115         }
    116         //mark as synced
    117         List<WayPoint> ls = gps.getTrack().subList(gps.getTrack().indexOf(start), gps.getTrack().indexOf(end));
    118        
    119         for (WayPoint wp : ls) {
    120                 wp.attr.clear();
    121             wp.attr.put("synced", "true");
    122         }   
    123     }
    124 
    125     public void setAsyncMode(boolean b)
    126     {
    127         if(b)
    128         {
    129             syncBtn.setVisible(true);
    130         }
    131         else
    132         {
    133             syncBtn.setVisible(false);
    134         }
    135     }
    136    
    137        
    138     public void setFile(GPSVideoFile f)
    139     {
    140        
    141         file=f;
    142         video.setFile(f.getAbsoluteFile());
    143         //video.play();
    144     }
    145    
    146     /*
    147     public void play(long gpsstart)
    148     {
    149         //video is already playing
    150         jumpToGPSTime(gpsstart);
    151         gps.jump(gpsstart);
    152         //gps.play();
    153     }
    154     */
    155    
    156     public void play()
    157     {
    158         video.play();
    159     }
    160    
    161     public void pause()
    162     {
    163         video.pause();
    164     }
    165    
    166    
    167     //jumps in video to the corresponding GPS time(xx:yy:zz) not date (external triggered)
    168     public void jumpToGPSTime(java.util.Date date)
    169     {
    170         if(!synced)
    171         {
    172             //when not synced we can just move the icon to the right position           
    173             gps.jump(date);
    174             Main.map.mapView.repaint();
    175         }
    176         video.jump(getVideoTime(date.getTime()));
    177     }
    178    
    179     //calc synced timecode from video
    180     private long getVideoTime(long GPStime)
    181     {
    182         return GPStime-file.offset;
    183     }
    184    
    185     //calc corresponding GPS time
    186     private long getGPSTime(long videoTime)
    187     {
    188         return videoTime+file.offset;
    189     }
    190 
    191    
    192 
    193     public void setJumpLength(Integer integer) {
    194         video.setJumpLength(integer);
    195        
    196     }
    197 
    198     public void setLoopLength(Integer integer) {
    199         video.setLoopLength(integer);
    200        
    201     }
    202    
    203     public boolean isSynced()
    204     {
    205         return synced;
    206     }
    207 
    208     public void loop() {
    209         video.loop();
    210        
    211     }
    212 
    213     public void forward() {
    214         video.forward();
    215        
    216     }
    217 
    218     public void backward() {
    219         video.backward();
    220        
    221     }
    222 
    223     public void removeVideo() {
    224         video.removeVideo();
    225        
    226     }
    227 
    228     public File getVideo() {
    229         return file;
    230     }
    231 
    232     public float getCoverage() {
    233         return gps.getLength()/video.getLength();
    234     }
    235 
    236     public void setDeinterlacer(String string) {
    237         video.setDeinterlacer(string);
    238        
    239     }
    240 
    241     public void setAutoCenter(boolean selected) {
    242         gps.setAutoCenter(selected);
    243        
    244     }
    245 
    246    
    247     //not called by GPS
    248     public boolean playing() {
    249         return video.playing();
    250     }
    251 
    252    
    253     public String getNativePlayerInfos() {
    254         return video.getNativePlayerInfos();
    255     }
    256 
    257     public void faster() {
    258         video.faster();
    259        
    260     }
    261 
    262     public void slower() {
    263         video.slower();
    264        
    265     }
    266 
    267 
    268     public void toggleSubtitles() {
    269         video.toggleSubs();
    270        
    271     }
    272    
    273     public boolean hasSubtitles(){
    274         return video.hasSubtitles();
    275     }
    276 
    277     public void setSubtitleAction(JCheckBoxMenuItem a)
    278     {
    279         subtTitleComponent=a;
    280     }
    281    
    282     public void close()
    283     {
    284         video.windowClosing(new WindowEvent(video,1));
    285     }
    28625   
    28726
  • applications/editors/josm/plugins/videomapping/src/org/openstreetmap/josm/plugins/videomapping/video/VideoPlayer.java

    r25742 r25765  
    99import java.awt.Dimension;
    1010import java.awt.FlowLayout;
     11import java.awt.HeadlessException;
    1112import java.awt.event.ActionEvent;
    1213import java.awt.event.ActionListener;
     
    2122import java.util.HashSet;
    2223import java.util.Hashtable ;
     24import java.util.LinkedList;
     25import java.util.List;
    2326import java.util.Set;
    2427import java.util.TimeZone;
     
    5659
    5760//basic class of a videoplayer for one video
    58 public class SimpleVideoPlayer extends JFrame implements MediaPlayerEventListener, WindowListener{
    59     private EmbeddedMediaPlayer mp;
    60     private Timer t;
    61     private JPanel screenPanel,controlsPanel;
     61public class VideoPlayer extends JFrame implements WindowListener, VideosObserver, VideoPlayerObserver{
     62        private static final int notificationIntervall = 1000;
     63        private JPanel screenPanel,controlsPanel,canvasPanel;
    6264    private JSlider timeline;
    6365    private JButton play,back,forward;
    6466    private JToggleButton loop,mute;
    6567    private JSlider speed;
    66     private Canvas scr;
    67     private final String[] mediaOptions = {""};
    68     private boolean syncTimeline=false;
    69     private boolean looping=false;
    70     private SimpleDateFormat ms;
    71     private static final Logger LOG = Logger.getLogger(MediaPlayerFactory.class);
    72     private int jumpLength=1000;
    73     private int  loopLength=6000;
    74     private static Set<VideoObserver> observers = new HashSet<VideoObserver>(); //we have to implement our own Observer pattern
    75    
    76     public SimpleVideoPlayer() {
    77         super();
    78         try
    79         {
    80                 //some workarounds to detect libVLC and DNA on windows       
    81                 if(RuntimeUtil.isWindows()) {
    82                         System.setProperty("jna.library.path",WindowsRuntimeUtil.getVlcInstallDir());  //FIXME doesn't work even with this workaround!
    83             }
    84                 System.setProperty("logj4.configuration","file:log4j.xml"); //TODO still unsure if we can't link this to the JOSM log4j instance                       
    85             //we don't need any options
    86             String[] libvlcArgs = {""};
    87             String[] standardMediaOptions = {""};
    88             //System.out.println("libvlc version: " + LibVlc.INSTANCE.libvlc_get_version());
    89             //setup Media Player
    90             //TODO we have to deal with unloading things again ....
    91             MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory(libvlcArgs);
    92             FullScreenStrategy fullScreenStrategy = new DefaultFullScreenStrategy(this);
    93             mp = mediaPlayerFactory.newMediaPlayer(fullScreenStrategy);
    94             mp.setStandardMediaOptions(standardMediaOptions);
    95             //setup GUI
    96             setSize(400, 300); //later we apply movie size
    97             setAlwaysOnTop(true);
    98             createUI();
    99             setLayout();
    100             addListeners(); //registering shortcuts is task of the outer plugin class!
    101             //embed vlc player
    102             scr.setVisible(true);
    103             setVisible(true);
    104             mp.setVideoSurface(scr);
    105             mp.addMediaPlayerEventListener(this);
    106             //mp.pause();
    107             //jump(0);
    108             //create updater
    109             ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    110             executorService.scheduleAtFixedRate(new Runnable() {
    111                                 //We have to do syncing in the main thread
    112                                 public void run() {
    113                                         SwingUtilities.invokeLater(new Runnable() {
    114                                           //here we update
    115                                         public void run() {
    116                                             if (isPlaying()) updateTime(); //if the video is seeking we get a mess
    117                                         }
    118                                       });
    119                                 }
    120                         }, 0L, 500L, TimeUnit.MILLISECONDS);
    121             //setDefaultCloseOperation(EXIT_ON_CLOSE);
    122             addWindowListener(this);
     68    private DateFormat videoTimeFormat;
     69    private VideoEngine videoengine;
     70    private long jumpLength;
     71    private long loopLength;
     72        private Timer loopingTimer;
     73        private boolean isManualJump;
     74        private Timer notificationTimer;
     75        private List<VideoPlayerObserver> observers;
     76       
     77        public VideoPlayer(DateFormat videoTimeFormat) throws HeadlessException {
     78                super();               
     79                this.videoTimeFormat=videoTimeFormat;
     80                //setup playback notifications
     81                videoengine=new VideoEngine(this);
     82                videoengine.addObserver(this);
     83                observers=new LinkedList<VideoPlayerObserver>();               
     84                addObserver(this);
     85                //setup GUI
     86            setSize(400, 300); //later we apply movie size
     87            setAlwaysOnTop(true);
     88            createUI();
     89            addUI();
     90            addUIListeners();   
     91            setVisible(true);
     92            setAlwaysOnTop(true);           
     93            this.addWindowListener(this);
     94        }
     95       
     96        public void addVideo(File Videofile)
     97        {
     98                Video video = new Video(Videofile,new Canvas());
     99                canvasPanel.add(video.canvas);
     100                video.canvas.setSize(new Dimension(300, 300)); // will be updated by the video engine itself
     101                videoengine.add(video);
     102        pack();
     103        startNotificationTimer();
     104        }
     105
     106        protected void play() {
     107                videoengine.play();
     108               
     109        }
     110       
     111        protected void pause(){
     112                videoengine.pause();
     113        }
     114
     115        protected void backward() {
     116                videoengine.jump(-jumpLength); 
     117        }
     118
     119        protected void forward() {
     120                videoengine.jump(jumpLength);   
     121        }
     122
     123        protected void toggleLooping() {
     124                if(loopingTimer==null)
     125                {
     126                        //do reset after loop time experienced
     127                        final long videoResetTime=(long) videoengine.getCurrentVideoTime()-loopLength/2;
     128                        TimerTask reset=new TimerTask() {               
     129                @Override
     130                public void run() {
     131                    videoengine.jumpTo(videoResetTime);
     132                }
     133            };
     134            loopingTimer= new Timer();
     135            loopingTimer.schedule(reset,loopLength/2,loopLength);
    123136        }
    124         catch (NoClassDefFoundError e)
    125         {
    126             System.err.println(tr("Unable to find JNA Java library!"));
    127         }
    128         catch (UnsatisfiedLinkError e)
    129         {
    130             System.err.println(tr("Unable to find native libvlc library!"));
    131         }
    132        
    133     }
    134 
    135     private void createUI() {
     137                else
     138                {
     139                        loopingTimer.cancel();
     140                        loopingTimer=null;
     141                }
     142               
     143        }
     144
     145        //create all normal player controls
     146        private void createUI() {
    136147        //setIconImage();
    137         ms = new SimpleDateFormat("hh:mm:ss");
    138         scr=new Canvas();
    139148        timeline = new JSlider(0,100,0);
    140         timeline.setMajorTickSpacing(10);
    141149        timeline.setMajorTickSpacing(5);
     150        timeline.setMinorTickSpacing(1);
    142151        timeline.setPaintTicks(true);
    143         //TODO we need Icons instead
    144152        play= new JButton(tr("play"));
    145153        back= new JButton("<");
     
    147155        loop= new JToggleButton(tr("loop"));
    148156        mute= new JToggleButton(tr("mute"));
    149         speed = new JSlider(-200,200,0);
    150         speed.setMajorTickSpacing(100);
     157        speed = new JSlider(0,200,100);
     158        speed.setMajorTickSpacing(50);
    151159        speed.setPaintTicks(true);         
    152160        speed.setOrientation(Adjustable.VERTICAL);
    153161        Hashtable labelTable = new Hashtable ();
    154         labelTable.put( new Integer( 0 ), new JLabel("1x") );
    155         labelTable.put( new Integer( -200 ), new JLabel("-2x") );
     162        labelTable.put( new Integer( 100 ), new JLabel("1x") );
     163        labelTable.put( new Integer( 50 ), new JLabel("-2x") );
    156164        labelTable.put( new Integer( 200 ), new JLabel("2x") );
    157165        speed.setLabelTable( labelTable );
    158166        speed.setPaintLabels(true);
    159167    }
    160    
    161     //creates a layout like the most mediaplayers are...
    162     private void setLayout() {
     168       
     169        //puts all player controls to screen
     170        private void addUI() {
     171                //create layouts
    163172        this.setLayout(new BorderLayout());
    164173        screenPanel=new JPanel();
     
    166175        controlsPanel=new JPanel();
    167176        controlsPanel.setLayout(new FlowLayout());
     177        canvasPanel=new JPanel();
     178        canvasPanel.setLayout(new FlowLayout());
    168179        add(screenPanel,BorderLayout.CENTER);
    169180        add(controlsPanel,BorderLayout.SOUTH);
    170181        //fill screen panel
    171         screenPanel.add(scr,BorderLayout.CENTER);
     182        screenPanel.add(canvasPanel,BorderLayout.CENTER);
    172183        screenPanel.add(timeline,BorderLayout.SOUTH);
    173184        screenPanel.add(speed,BorderLayout.EAST);
     
    180191        mute.setSelected(false);
    181192    }
    182 
    183     //add UI functionality
    184     private void addListeners() {
     193       
     194        //add UI functionality
     195    private void addUIListeners() {       
     196       
     197        play.addActionListener(new ActionListener() {           
     198            public void actionPerformed(ActionEvent arg0) {
     199            pause();               
     200            }
     201        });
     202       
     203        back.addActionListener(new ActionListener() {
     204           
     205            public void actionPerformed(ActionEvent arg0) {
     206                backward();
     207            }
     208        });
     209       
     210        forward.addActionListener(new ActionListener() {
     211           
     212            public void actionPerformed(ActionEvent arg0) {
     213                forward();
     214            }
     215        });
     216       
     217        loop.addActionListener(new ActionListener() {
     218
     219            public void actionPerformed(ActionEvent arg0) {
     220                toggleLooping();
     221            }
     222        });
     223       
     224        mute.addActionListener(new ActionListener() {
     225
     226            public void actionPerformed(ActionEvent arg0) {
     227                videoengine.mute();
     228            }
     229        });
     230       
    185231        timeline.addChangeListener(new ChangeListener() {
    186232            public void stateChanged(ChangeEvent e) {
    187                 if(!syncTimeline) //only if user moves the slider by hand
    188                 {
    189                     if(!timeline.getValueIsAdjusting()) //and the slider is fixed
    190                     {
    191                         //recalc to 0.x percent value
    192                         mp.setPosition((float)timeline.getValue()/100.0f);
    193                     }                   
    194                 }
    195             }
    196             });
    197        
    198         play.addActionListener(new ActionListener() {
    199            
    200             public void actionPerformed(ActionEvent arg0) {
    201                 if(mp.isPlaying()) mp.pause(); else mp.play();             
    202             }
    203         });
    204        
    205         back.addActionListener(new ActionListener() {
    206            
    207             public void actionPerformed(ActionEvent arg0) {
    208                 backward();
    209             }
    210         });
    211        
    212         forward.addActionListener(new ActionListener() {
    213            
    214             public void actionPerformed(ActionEvent arg0) {
    215                 forward();
    216             }
    217         });
    218        
    219         loop.addActionListener(new ActionListener() {
    220 
    221             public void actionPerformed(ActionEvent arg0) {
    222                 loop();
    223             }
    224         });
    225        
    226         mute.addActionListener(new ActionListener() {
    227 
    228             public void actionPerformed(ActionEvent arg0) {
    229                 mute();
    230             }
    231         });
    232        
    233         speed.addChangeListener(new ChangeListener() {
    234            
     233                        //skip events, fired by this sliede, one cycle ago             
     234                if(!isManualJump)
     235                {
     236                        isManualJump=true;
     237                        videoengine.jumpToPosition((timeline.getValue()));
     238                }
     239            }
     240               
     241        });
     242       
     243        speed.addChangeListener(new ChangeListener() {           
    235244            public void stateChanged(ChangeEvent arg0) {
    236                 if(!speed.getValueIsAdjusting()&&(mp.isPlaying()))
    237                 {
    238                     int perc = speed.getValue();
    239                     float ratio= (float) (perc/400f*1.75);
    240                     ratio=ratio+(9/8);
    241                     mp.setRate(ratio);
    242                 }
    243                
    244             }
    245         });
    246        
    247     }   
    248 
    249     public void finished(MediaPlayer arg0) {
    250            
    251     }
    252 
    253     public void lengthChanged(MediaPlayer arg0, long arg1) {
    254 
    255     }
    256 
    257     public void metaDataAvailable(MediaPlayer arg0, VideoMetaData data) {
    258         final float perc = 0.5f;
    259         Dimension org=data.getVideoDimension();
    260         scr.setSize(new Dimension((int)(org.width*perc), (int)(org.height*perc)));
    261         pack();
    262         //send out metadatas to all observers
    263         for (VideoObserver o : observers) {
    264             o.metadata(0, hasSubtitles());
    265         }
    266     }
    267 
    268     public void paused(MediaPlayer arg0) {
    269 
    270     }
    271 
    272     public void playing(MediaPlayer arg0) {
    273 
    274     }
    275 
    276     public void positionChanged(MediaPlayer arg0, float arg1) {
    277        
    278     }
    279 
    280     public void stopped(MediaPlayer arg0) {
    281                
    282     }
    283 
    284     public void timeChanged(MediaPlayer arg0, long arg1) {
    285 
    286     }
    287    
    288 
    289     public void windowActivated(WindowEvent arg0) { }
    290 
    291     public void windowClosed(WindowEvent arg0) {    }
    292 
    293     //we have to unload and disconnect to the VLC engine
    294     public void windowClosing(WindowEvent evt) {
    295         if(LOG.isDebugEnabled()) {LOG.debug("windowClosing(evt=" + evt + ")");}
    296         pause();
    297         //FIXME stop timers etc.
    298         mp.release();
    299         mp = null;
    300       }
    301 
    302     public void windowDeactivated(WindowEvent arg0) {   }
    303 
    304     public void windowDeiconified(WindowEvent arg0) {   }
    305 
    306     public void windowIconified(WindowEvent arg0) { }
    307 
    308     public void windowOpened(WindowEvent arg0) {    }   
    309    
    310     public void setFile(File f)
     245                if(!speed.getValueIsAdjusting())
     246                {
     247                        videoengine.setSpeed(speed.getValue());
     248                }
     249            }
     250        });
     251       
     252    }
     253   
     254    public void setJumpLength(long ms)
    311255    {
    312         String mediaPath = f.getAbsoluteFile().toString();
    313         mp.playMedia(mediaPath, mediaOptions);
    314         pack();
    315     }
    316    
    317     public void play()
     256        jumpLength=ms;
     257    }
     258   
     259    public void setLoopLength(long ms)
    318260    {
    319         mp.play();
    320     }
    321    
    322     public void jump(long time)
     261        loopLength=ms;
     262    }
     263   
     264    public void addObserver(VideoPlayerObserver observer)
    323265    {
    324         /*float pos = (float)mp.getLength()/(float)time;
    325         mp.setPosition(pos);*/
    326         mp.setTime(time);
    327     }
    328    
    329     public long getTime()
    330     {
    331         return mp.getTime();
    332     }
    333    
    334     public float getPosition()
    335     {
    336         return mp.getPosition();
    337     }
    338    
    339     public boolean isPlaying()
    340     {
    341         return mp.isPlaying();
    342     }
    343    
    344     //gets called by the Syncer thread to update all observers
    345     public void updateTime ()
    346     {
    347         if(mp.isPlaying())
    348         {
    349                 long millis=mp.getTime();
    350                 String s = String.format("%02d:%02d:%02d", //dont know why normal Java date utils doesn't format the time right
    351                       TimeUnit.MILLISECONDS.toHours(millis),
    352                       TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
    353                       TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
    354                     );
    355             //setTitle(ms.format(new Time(sec)));
    356                 setTitle(s);
    357             syncTimeline=true;
    358             timeline.setValue(Math.round(mp.getPosition()*100));
    359             syncTimeline=false;
    360             notifyObservers(mp.getTime());
    361         }
    362     }
    363    
    364     //allow externals to extend the ui
    365     public void addComponent(JComponent c)
    366     {
    367         controlsPanel.add(c);
    368         pack();
    369     }
    370 
    371     public long getLength() {       
    372         return mp.getLength();
    373     }
    374 
    375     public void setDeinterlacer(String string) {
    376         mp.setDeinterlace(string);
    377        
    378     }
    379 
    380     public void setJumpLength(Integer integer) {
    381         jumpLength=integer;
    382        
    383     }
    384 
    385     public void setLoopLength(Integer integer) {
    386         loopLength = integer;
    387        
    388     }
    389 
    390     public void loop() {
    391         if(looping)
    392         {
    393             t.cancel();
    394             looping=false;
    395         }
    396         else           
    397         {
    398             final long resetpoint=(long) mp.getTime()-loopLength/2;
    399             TimerTask ani=new TimerTask() {
    400                
    401                 @Override
    402                 public void run() {
    403                     mp.setTime(resetpoint);
    404                 }
    405             };
    406             t= new Timer();
    407             t.schedule(ani,loopLength/2,loopLength); //first run a half looptime till reset
    408             looping=true;
    409             }
    410        
    411     }
    412    
    413     protected void mute() {
    414         mp.mute();
    415        
    416     }
    417 
    418     public void forward() {
    419         mp.setTime((long) (mp.getTime()+jumpLength));
    420     }
    421 
    422     public void backward() {
    423         mp.setTime((long) (mp.getTime()-jumpLength));
    424        
    425     }
    426 
    427     public void removeVideo() {
    428         if (mp.isPlaying()) mp.stop();
    429         mp.release();
    430        
    431     }
    432    
    433     public void toggleSubs()
    434     {
    435         //vlc manages it's subtitles in a own list so we have to cycle trough
    436         int spu = mp.getSpu();
    437         if(spu > -1) {
    438           spu++;
    439           if(spu > mp.getSpuCount()) {
    440             spu = -1;
    441           }
    442         }
    443         else {
    444           spu = 0;
    445         }
    446         mp.setSpu(spu);
    447     }
    448 
    449     public static void addObserver(VideoObserver observer) {
    450 
    451             observers.add(observer);
    452 
    453         }
    454 
    455      
    456 
    457         public static void removeObserver(VideoObserver observer) {
    458 
    459             observers.remove(observer);
    460 
    461         }
    462 
    463         private static void notifyObservers(long newTime) {
    464 
    465             for (VideoObserver o : observers) {
    466                 o.playing(newTime);
    467             }
    468 
    469         }
    470 
    471         public String getNativePlayerInfos() {
    472             return "VLC "+LibVlc.INSTANCE.libvlc_get_version();
    473         }
    474 
    475         public void faster() {
    476             speed.setValue(speed.getValue()+100);
    477            
    478         }
    479 
    480         public void slower() {
    481             speed.setValue(speed.getValue()-100);
    482            
    483         }
    484 
    485         public void pause() {
    486             if (mp.isPlaying()) mp.pause();
    487            
    488         }
    489 
    490         public boolean playing() {
    491             return mp.isPlaying();
    492         }
    493 
    494         public void error(MediaPlayer arg0) {
    495             // TODO Auto-generated method stub
    496            
    497         }
    498 
    499         public void mediaChanged(MediaPlayer arg0) {
    500             // TODO Auto-generated method stub
    501            
    502         }
    503 
    504         public boolean hasSubtitles() {
    505             if (mp.getSpuCount()==0) return false; else   return true;
    506         }
    507 
    508                 public void backward(MediaPlayer arg0) {
    509                         // TODO Auto-generated method stub
    510                        
     266        observers.add(observer);
     267    }
     268       
     269       
     270        private void startNotificationTimer() {
     271                if(notificationTimer==null)
     272                {
     273                        notificationTimer= new Timer();
     274                    notificationTimer.schedule(new TimerTask() {                               
     275                                @Override
     276                                public void run() {
     277                                        notifyObservers();
     278                                       
     279                                }
     280                        },notificationIntervall,notificationIntervall);
    511281                }
    512 
    513                 public void buffering(MediaPlayer arg0) {
    514                         System.out.println("buffering!");
    515                        
     282        }
     283       
     284        private void  notifyObservers() {
     285                for (VideoPlayerObserver observer : observers) {
     286                        observer.update_plays();//TODO hier müssten gleich die Zeiten übergeben werden
    516287                }
    517 
    518                 public void forward(MediaPlayer arg0) {
    519                         // TODO Auto-generated method stub
    520                        
    521                 }
    522 
    523                 public void opening(MediaPlayer arg0) {
    524                         // TODO Auto-generated method stub
    525                         System.out.println("opening!");
    526                        
    527                 }
    528 
    529                 public void pausableChanged(MediaPlayer arg0, int arg1) {
    530                         // TODO Auto-generated method stub
    531                        
    532                 }
    533 
    534                 public void seekableChanged(MediaPlayer arg0, int arg1) {
    535                         System.out.println("seeking!");
    536                        
    537                 }
    538 
    539                 public void snapshotTaken(MediaPlayer arg0, String arg1) {
    540                         // TODO Auto-generated method stub
    541                        
    542                 }
    543 
    544                 public void titleChanged(MediaPlayer arg0, int arg1) {
    545                         // TODO Auto-generated method stub
    546                        
    547                 }
     288        }
     289
     290        public void windowActivated(WindowEvent arg0) {
     291                // TODO Auto-generated method stub
     292               
     293        }
     294
     295        public void windowClosed(WindowEvent arg0) {
     296               
     297        }
     298
     299        public void windowClosing(WindowEvent arg0) {   
     300                videoengine.unload();
     301        }
     302
     303        public void windowDeactivated(WindowEvent arg0) {
     304                // TODO Auto-generated method stub
     305               
     306        }
     307
     308        public void windowDeiconified(WindowEvent arg0) {
     309                // TODO Auto-generated method stub
     310               
     311        }
     312
     313        public void windowIconified(WindowEvent arg0) {
     314                // TODO Auto-generated method stub
     315               
     316        }
     317
     318        public void windowOpened(WindowEvent arg0) {
     319                // TODO Auto-generated method stub
     320               
     321        }
     322
     323        public void update(VideoObserversEvents event) {
     324                switch (event)
     325                {               
     326                        case resizing:
     327                        {
     328                                pack();
     329                                break;
     330                        }
     331                        case speeding:
     332                        {
     333                                speed.setValue(videoengine.getSpeed());
     334                        }
     335                        case jumping:
     336                        {                               
     337                        }
     338                }               
     339        }
     340
     341        //keep internal controls up to date during playback
     342        public void update_plays() {
     343                timeline.setValue(videoengine.getPosition());
     344                System.out.println(videoengine.getPosition());
     345                isManualJump=false;
     346               
     347        }
     348   
    548349
    549350   
  • applications/editors/josm/plugins/videomapping/test/videotest.java

    r23193 r25765  
    55import java.awt.event.ActionListener;
    66import java.io.File;
     7import java.text.SimpleDateFormat;
    78
    89import javax.swing.JButton;
     
    1415import javax.swing.event.ChangeListener;
    1516
    16 import org.openstreetmap.josm.plugins.videomapping.video.SimpleVideoPlayer;
     17import org.openstreetmap.josm.plugins.videomapping.video.VideoEngine;
     18import org.openstreetmap.josm.plugins.videomapping.video.VideoPlayer;
    1719
    1820import uk.co.caprica.vlcj.player.*;
    1921
    2022
     23//simple app to test videoplayer alone
    2124public class videotest {
    22 
    23     /**
    24      * @param args
    25      */
    2625    public static void main(String[] args) {
    27         final SimpleVideoPlayer sVP = new SimpleVideoPlayer();
    28         sVP.setFile(new File("C:\\TEMP\\122_0159.MOV"));
    29         //sVP.play(); //FIXME We have a bug so we get out of sync if we jump before the video is up (and this we CAN'T DETECT!!!)
    30         /*
    31         JButton b = new JButton("jump");
    32         b.addActionListener(new ActionListener() {
    33            
    34             public void actionPerformed(ActionEvent e) {
    35                 sVP.jump(610000);               
    36             }
    37         });
    38         sVP.add(b);
    39         */
     26        VideoEngine.setupPlayer();
     27        VideoPlayer testplayer= new VideoPlayer(new SimpleDateFormat("hh:mm:ss"));
     28        testplayer.setJumpLength(1000);
     29        testplayer.setLoopLength(3000);
     30        testplayer.addVideo(new File("C:\\TEMP\\test.mpg"));
     31       
    4032    }
    4133
  • applications/editors/josm/plugins/videomapping/uml/refactoring.uml

    r25742 r25765  
    4242  </packagedElement>
    4343  <packagedElement xmi:type="uml:Class" xmi:id="_PlPfAFRsEeCQNNgUSH7L8A" name="GPSVideo">
     44    <generalization xmi:id="_Chj2IFomEeClo8qtmvnTtw" general="_n4H5YFolEeClo8qtmvnTtw"/>
    4445    <ownedAttribute xmi:id="_S4Pg0FRsEeCQNNgUSH7L8A" name="synced" aggregation="composite"/>
    45     <ownedAttribute xmi:id="_TrDd0FRsEeCQNNgUSH7L8A" name="filepath" aggregation="composite"/>
    4646    <ownedAttribute xmi:id="_UmDtgFRsEeCQNNgUSH7L8A" name="syncWP" aggregation="composite"/>
    4747    <ownedAttribute xmi:id="_WVXvAFRsEeCQNNgUSH7L8A" name="syncVideoTime" aggregation="composite"/>
     
    6262    <ownedOperation xmi:id="_Q_fIEFRvEeCQNNgUSH7L8A" name="operation3"/>
    6363  </packagedElement>
    64   <packagedElement xmi:type="uml:Class" xmi:id="_Zzy2UFRvEeCQNNgUSH7L8A" name="MediaPlayer">
     64  <packagedElement xmi:type="uml:Class" xmi:id="_Zzy2UFRvEeCQNNgUSH7L8A" name="VideoPlayer" clientDependency="_OyCWkFqlEeC9SaX6k5fY1Q _VjNvcFqlEeC9SaX6k5fY1Q">
    6565    <ownedAttribute xmi:id="_2wMrsFSlEeCQNNgUSH7L8A" name="logger" aggregation="composite"/>
    6666    <ownedAttribute xmi:id="_oQVTYFSmEeCQNNgUSH7L8A" name="screenPanel" aggregation="composite"/>
    6767    <ownedAttribute xmi:id="_pLfUEFSmEeCQNNgUSH7L8A" name="controlsPanel" aggregation="composite"/>
    68     <ownedAttribute xmi:id="_SBMnYFVZEeCOu_gAbBroWQ" name="players" aggregation="composite"/>
    69     <ownedOperation xmi:id="_b4aZcFRvEeCQNNgUSH7L8A" name="setupMediaPlayer">
    70       <ownedParameter xmi:id="_fB4EwFRvEeCQNNgUSH7L8A" direction="return"/>
     68    <ownedAttribute xmi:id="_J0hIEFtzEeCcNedtTKlFGg" name="jumpLength" aggregation="composite"/>
     69    <ownedOperation xmi:id="_nSHcoFRvEeCQNNgUSH7L8A" name="loop">
     70      <ownedParameter xmi:id="_n-OUsFRvEeCQNNgUSH7L8A" direction="return"/>
    7171    </ownedOperation>
    72     <ownedOperation xmi:id="_fStWEFRvEeCQNNgUSH7L8A" name="addFile">
    73       <ownedParameter xmi:id="_gJGykFRvEeCQNNgUSH7L8A" direction="return"/>
     72    <ownedOperation xmi:id="_iJa4IFSpEeCQNNgUSH7L8A" name="createUI">
     73      <ownedParameter xmi:id="_jLlfwFSpEeCQNNgUSH7L8A" direction="return"/>
    7474    </ownedOperation>
    75     <ownedOperation xmi:id="_iEVJIFRvEeCQNNgUSH7L8A" name="play">
    76       <ownedParameter xmi:id="_itT0sFRvEeCQNNgUSH7L8A" direction="return"/>
    77     </ownedOperation>
    78     <ownedOperation xmi:id="_i4CeAFRvEeCQNNgUSH7L8A" name="pause">
    79       <ownedParameter xmi:id="_jPIvYFRvEeCQNNgUSH7L8A" direction="return"/>
     75    <ownedOperation xmi:id="_OVaAEFRyEeCQNNgUSH7L8A" name="addFile">
     76      <ownedParameter xmi:id="_O2fT4FRyEeCQNNgUSH7L8A" direction="return"/>
    8077    </ownedOperation>
    8178    <ownedOperation xmi:id="_jVP-cFRvEeCQNNgUSH7L8A" name="jumpForward">
     
    8481    <ownedOperation xmi:id="_kYdH4FRvEeCQNNgUSH7L8A" name="jumpBackward">
    8582      <ownedParameter xmi:id="_lK-J8FRvEeCQNNgUSH7L8A" direction="return"/>
    86     </ownedOperation>
    87     <ownedOperation xmi:id="_lSj_sFRvEeCQNNgUSH7L8A" name="jumpTo">
    88       <ownedParameter xmi:id="_nK9rwFRvEeCQNNgUSH7L8A" direction="return"/>
    89     </ownedOperation>
    90     <ownedOperation xmi:id="_nSHcoFRvEeCQNNgUSH7L8A" name="loop">
    91       <ownedParameter xmi:id="_n-OUsFRvEeCQNNgUSH7L8A" direction="return"/>
    92     </ownedOperation>
    93     <ownedOperation xmi:id="_oFrnkFRvEeCQNNgUSH7L8A" name="jumpToSynced">
    94       <ownedParameter xmi:id="_pXChwFRvEeCQNNgUSH7L8A" direction="return"/>
    95     </ownedOperation>
    96     <ownedOperation xmi:id="_pdcrwFRvEeCQNNgUSH7L8A" name="operation"/>
    97     <ownedOperation xmi:id="_qOxbAFRvEeCQNNgUSH7L8A" name="setSubtitles">
    98       <ownedParameter xmi:id="_sINo4FRvEeCQNNgUSH7L8A" direction="return"/>
    99     </ownedOperation>
    100     <ownedOperation xmi:id="_qvaC4FRvEeCQNNgUSH7L8A" name="setSpeed">
    101       <ownedParameter xmi:id="_rV2X0FRvEeCQNNgUSH7L8A" direction="return"/>
    102     </ownedOperation>
    103     <ownedOperation xmi:id="_sm6XEFRvEeCQNNgUSH7L8A" name="setDeinterlacer">
    104       <ownedParameter xmi:id="_uJ2wgFRvEeCQNNgUSH7L8A" direction="return"/>
    105     </ownedOperation>
    106     <ownedOperation xmi:id="_J3w9AFSnEeCQNNgUSH7L8A" name="metaDataAvailable">
    107       <ownedParameter xmi:id="_KdwmAFSnEeCQNNgUSH7L8A" direction="return"/>
    108     </ownedOperation>
    109     <ownedOperation xmi:id="_SLcDYFSnEeCQNNgUSH7L8A" name="mute">
    110       <ownedParameter xmi:id="_TVWRwFSnEeCQNNgUSH7L8A" direction="return"/>
    111     </ownedOperation>
    112     <ownedOperation xmi:id="_iJa4IFSpEeCQNNgUSH7L8A" name="createUI">
    113       <ownedParameter xmi:id="_jLlfwFSpEeCQNNgUSH7L8A" direction="return"/>
    11483    </ownedOperation>
    11584  </packagedElement>
     
    134103    </ownedOperation>
    135104  </packagedElement>
    136   <packagedElement xmi:type="uml:Class" xmi:id="_MhLCUFRyEeCQNNgUSH7L8A" name="GPSMediaPlayer" clientDependency="_JJtsYFlWEeCTIL9CCJRwPw">
     105  <packagedElement xmi:type="uml:Class" xmi:id="_MhLCUFRyEeCQNNgUSH7L8A" name="GPSVideoPlayer" clientDependency="_JJtsYFlWEeCTIL9CCJRwPw">
    137106    <generalization xmi:id="_8RbsAFlNEeCTIL9CCJRwPw" general="_Zzy2UFRvEeCQNNgUSH7L8A"/>
    138107    <ownedAttribute xmi:id="_YOwV0FVZEeCOu_gAbBroWQ" name="videos" aggregation="composite"/>
    139108    <ownedAttribute xmi:id="_lBTl0FVaEeCOu_gAbBroWQ" name="syncPanel" aggregation="composite"/>
    140     <ownedOperation xmi:id="_OVaAEFRyEeCQNNgUSH7L8A" name="addFile">
    141       <ownedParameter xmi:id="_O2fT4FRyEeCQNNgUSH7L8A" direction="return"/>
    142     </ownedOperation>
    143     <ownedOperation xmi:id="_PA6bMFRyEeCQNNgUSH7L8A" name="createUI">
    144       <ownedParameter xmi:id="_Qs9GQFRyEeCQNNgUSH7L8A" direction="return"/>
     109    <ownedOperation xmi:id="_PA6bMFRyEeCQNNgUSH7L8A" name="extendUI">
     110      <ownedParameter xmi:id="_KF0CkFqmEeC9SaX6k5fY1Q" direction="return"/>
    145111    </ownedOperation>
    146112    <ownedOperation xmi:id="_QynCUFRyEeCQNNgUSH7L8A" name="addSyncPoint">
     
    150116      <ownedParameter xmi:id="_VyPlEFRyEeCQNNgUSH7L8A" direction="return"/>
    151117    </ownedOperation>
    152     <ownedOperation xmi:id="_V6St0FRyEeCQNNgUSH7L8A" name="rremoveFile">
    153       <ownedParameter xmi:id="_XMsJ0FRyEeCQNNgUSH7L8A" direction="return"/>
     118    <ownedOperation xmi:id="_V6St0FRyEeCQNNgUSH7L8A" name="removeFile">
     119      <ownedParameter xmi:id="_HY1uIFomEeClo8qtmvnTtw" direction="return"/>
    154120    </ownedOperation>
    155121    <ownedOperation xmi:id="_YO2xcFRyEeCQNNgUSH7L8A" name="setAutoCenter">
    156122      <ownedParameter xmi:id="_Y_u0wFRyEeCQNNgUSH7L8A" direction="return"/>
    157123    </ownedOperation>
     124    <ownedOperation xmi:id="_oFrnkFRvEeCQNNgUSH7L8A" name="jumpToSynced">
     125      <ownedParameter xmi:id="_pXChwFRvEeCQNNgUSH7L8A" direction="return"/>
     126    </ownedOperation>
    158127  </packagedElement>
    159128  <packagedElement xmi:type="uml:Dependency" xmi:id="_JJtsYFlWEeCTIL9CCJRwPw" name="n:1" supplier="_PlPfAFRsEeCQNNgUSH7L8A" client="_MhLCUFRyEeCQNNgUSH7L8A"/>
     129  <packagedElement xmi:type="uml:Class" xmi:id="_zSPkMFnhEeClo8qtmvnTtw" name="VideoEngine">
     130    <ownedAttribute xmi:id="_SBMnYFVZEeCOu_gAbBroWQ" name="players" aggregation="composite"/>
     131    <ownedOperation xmi:id="_8dM34FnhEeClo8qtmvnTtw" name="operation"/>
     132    <ownedOperation xmi:id="_b4aZcFRvEeCQNNgUSH7L8A" name="setupMediaPlayer">
     133      <ownedParameter xmi:id="_fB4EwFRvEeCQNNgUSH7L8A" direction="return"/>
     134    </ownedOperation>
     135    <ownedOperation xmi:id="_fStWEFRvEeCQNNgUSH7L8A" name="addFile">
     136      <ownedParameter xmi:id="_gJGykFRvEeCQNNgUSH7L8A" direction="return"/>
     137    </ownedOperation>
     138    <ownedOperation xmi:id="_iEVJIFRvEeCQNNgUSH7L8A" name="play">
     139      <ownedParameter xmi:id="_itT0sFRvEeCQNNgUSH7L8A" direction="return"/>
     140    </ownedOperation>
     141    <ownedOperation xmi:id="_i4CeAFRvEeCQNNgUSH7L8A" name="pause">
     142      <ownedParameter xmi:id="_jPIvYFRvEeCQNNgUSH7L8A" direction="return"/>
     143    </ownedOperation>
     144    <ownedOperation xmi:id="_lSj_sFRvEeCQNNgUSH7L8A" name="jumpTo">
     145      <ownedParameter xmi:id="_nK9rwFRvEeCQNNgUSH7L8A" direction="return"/>
     146    </ownedOperation>
     147    <ownedOperation xmi:id="_qOxbAFRvEeCQNNgUSH7L8A" name="setSubtitles">
     148      <ownedParameter xmi:id="_sINo4FRvEeCQNNgUSH7L8A" direction="return"/>
     149    </ownedOperation>
     150    <ownedOperation xmi:id="_qvaC4FRvEeCQNNgUSH7L8A" name="setSpeed">
     151      <ownedParameter xmi:id="_rV2X0FRvEeCQNNgUSH7L8A" direction="return"/>
     152    </ownedOperation>
     153    <ownedOperation xmi:id="_sm6XEFRvEeCQNNgUSH7L8A" name="setDeinterlacer">
     154      <ownedParameter xmi:id="_uJ2wgFRvEeCQNNgUSH7L8A" direction="return"/>
     155    </ownedOperation>
     156    <ownedOperation xmi:id="_J3w9AFSnEeCQNNgUSH7L8A" name="metaDataAvailable">
     157      <ownedParameter xmi:id="_KdwmAFSnEeCQNNgUSH7L8A" direction="return"/>
     158    </ownedOperation>
     159    <ownedOperation xmi:id="_SLcDYFSnEeCQNNgUSH7L8A" name="mute">
     160      <ownedParameter xmi:id="_TVWRwFSnEeCQNNgUSH7L8A" direction="return"/>
     161    </ownedOperation>
     162  </packagedElement>
     163  <packagedElement xmi:type="uml:Class" xmi:id="_n4H5YFolEeClo8qtmvnTtw" name="Video">
     164    <ownedAttribute xmi:id="_rEkAMFolEeClo8qtmvnTtw" name="canvas" aggregation="composite"/>
     165    <ownedAttribute xmi:id="_TrDd0FRsEeCQNNgUSH7L8A" name="filepath" aggregation="composite"/>
     166    <ownedAttribute xmi:id="_JD1QUFomEeClo8qtmvnTtw" name="player" aggregation="composite"/>
     167  </packagedElement>
     168  <packagedElement xmi:type="uml:Dependency" xmi:id="_OyCWkFqlEeC9SaX6k5fY1Q" supplier="_zSPkMFnhEeClo8qtmvnTtw" client="_Zzy2UFRvEeCQNNgUSH7L8A"/>
     169  <packagedElement xmi:type="uml:Dependency" xmi:id="_VjNvcFqlEeC9SaX6k5fY1Q" supplier="_n4H5YFolEeClo8qtmvnTtw" client="_Zzy2UFRvEeCQNNgUSH7L8A"/>
     170  <packagedElement xmi:type="uml:Interface" xmi:id="_6vSikFxoEeCd3KUH_BuVkA" name="VideoObserver"/>
    160171</uml:Package>
  • applications/editors/josm/plugins/videomapping/uml/refactoring.umlclass

    r25742 r25765  
    7777    <styles xmi:type="notation:CanonicalStyle" xmi:id="_aKUcwVRrEeCQNNgUSH7L8A"/>
    7878    <element xmi:type="uml:Class" href="refactoring.uml#_aDA64FRrEeCQNNgUSH7L8A"/>
    79     <layoutConstraint xmi:type="notation:Bounds" xmi:id="_aKUcwlRrEeCQNNgUSH7L8A" x="255" y="270"/>
     79    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_aKUcwlRrEeCQNNgUSH7L8A" x="100" y="255"/>
    8080  </children>
    8181  <children xmi:type="notation:Shape" xmi:id="_Plrj4FRsEeCQNNgUSH7L8A" type="2001" fontName="Calibri">
     
    8989        <layoutConstraint xmi:type="notation:Location" xmi:id="_S4ibwVRsEeCQNNgUSH7L8A"/>
    9090      </children>
    91       <children xmi:type="notation:Node" xmi:id="_TrWYwFRsEeCQNNgUSH7L8A" type="3001">
    92         <element xmi:type="uml:Property" href="refactoring.uml#_TrDd0FRsEeCQNNgUSH7L8A"/>
    93         <layoutConstraint xmi:type="notation:Location" xmi:id="_TrWYwVRsEeCQNNgUSH7L8A"/>
    94       </children>
    9591      <children xmi:type="notation:Node" xmi:id="_UmWocFRsEeCQNNgUSH7L8A" type="3001">
    9692        <element xmi:type="uml:Property" href="refactoring.uml#_UmDtgFRsEeCQNNgUSH7L8A"/>
     
    132128    <styles xmi:type="notation:CanonicalStyle" xmi:id="_Plrj4VRsEeCQNNgUSH7L8A"/>
    133129    <element xmi:type="uml:Class" href="refactoring.uml#_PlPfAFRsEeCQNNgUSH7L8A"/>
    134     <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Plrj4lRsEeCQNNgUSH7L8A" x="460" y="500" width="166"/>
     130    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Plrj4lRsEeCQNNgUSH7L8A" x="465" y="505" width="166"/>
    135131  </children>
    136132  <children xmi:type="notation:Shape" xmi:id="_Z0FxQFRvEeCQNNgUSH7L8A" type="2001" fontName="Calibri">
     
    152148        <layoutConstraint xmi:type="notation:Location" xmi:id="_pLy2EVSmEeCQNNgUSH7L8A"/>
    153149      </children>
    154       <children xmi:type="notation:Node" xmi:id="_SS7QkFVZEeCOu_gAbBroWQ" type="3001">
    155         <element xmi:type="uml:Property" href="refactoring.uml#_SBMnYFVZEeCOu_gAbBroWQ"/>
    156         <layoutConstraint xmi:type="notation:Location" xmi:id="_SS7QkVVZEeCOu_gAbBroWQ"/>
     150      <children xmi:type="notation:Node" xmi:id="_J2KG0FtzEeCcNedtTKlFGg" type="3001">
     151        <element xmi:type="uml:Property" href="refactoring.uml#_J0hIEFtzEeCcNedtTKlFGg"/>
     152        <layoutConstraint xmi:type="notation:Location" xmi:id="_J2KG0VtzEeCcNedtTKlFGg"/>
    157153      </children>
    158154      <styles xmi:type="notation:TitleStyle" xmi:id="_Z0FxRlRvEeCQNNgUSH7L8A" showTitle="true"/>
     
    162158    </children>
    163159    <children xmi:type="notation:BasicCompartment" xmi:id="_Z0FxSlRvEeCQNNgUSH7L8A" type="7002">
    164       <children xmi:type="notation:Node" xmi:id="_b4tUYFRvEeCQNNgUSH7L8A" type="3002">
    165         <element xmi:type="uml:Operation" href="refactoring.uml#_b4aZcFRvEeCQNNgUSH7L8A"/>
    166         <layoutConstraint xmi:type="notation:Location" xmi:id="_b4tUYVRvEeCQNNgUSH7L8A"/>
    167       </children>
    168       <children xmi:type="notation:Node" xmi:id="_fTA4EFRvEeCQNNgUSH7L8A" type="3002">
    169         <element xmi:type="uml:Operation" href="refactoring.uml#_fStWEFRvEeCQNNgUSH7L8A"/>
    170         <layoutConstraint xmi:type="notation:Location" xmi:id="_fTA4EVRvEeCQNNgUSH7L8A"/>
    171       </children>
    172       <children xmi:type="notation:Node" xmi:id="_iEe6IFRvEeCQNNgUSH7L8A" type="3002">
    173         <element xmi:type="uml:Operation" href="refactoring.uml#_iEVJIFRvEeCQNNgUSH7L8A"/>
    174         <layoutConstraint xmi:type="notation:Location" xmi:id="_iEe6IVRvEeCQNNgUSH7L8A"/>
    175       </children>
    176       <children xmi:type="notation:Node" xmi:id="_i4WAAFRvEeCQNNgUSH7L8A" type="3002">
    177         <element xmi:type="uml:Operation" href="refactoring.uml#_i4CeAFRvEeCQNNgUSH7L8A"/>
    178         <layoutConstraint xmi:type="notation:Location" xmi:id="_i4WAAVRvEeCQNNgUSH7L8A"/>
    179       </children>
    180       <children xmi:type="notation:Node" xmi:id="_jVZIYFRvEeCQNNgUSH7L8A" type="3002">
    181         <element xmi:type="uml:Operation" href="refactoring.uml#_jVP-cFRvEeCQNNgUSH7L8A"/>
    182         <layoutConstraint xmi:type="notation:Location" xmi:id="_jVZIYVRvEeCQNNgUSH7L8A"/>
    183       </children>
    184       <children xmi:type="notation:Node" xmi:id="_kYwC0FRvEeCQNNgUSH7L8A" type="3002">
    185         <element xmi:type="uml:Operation" href="refactoring.uml#_kYdH4FRvEeCQNNgUSH7L8A"/>
    186         <layoutConstraint xmi:type="notation:Location" xmi:id="_kYwC0VRvEeCQNNgUSH7L8A"/>
    187       </children>
    188       <children xmi:type="notation:Node" xmi:id="_lStwsFRvEeCQNNgUSH7L8A" type="3002">
    189         <element xmi:type="uml:Operation" href="refactoring.uml#_lSj_sFRvEeCQNNgUSH7L8A"/>
    190         <layoutConstraint xmi:type="notation:Location" xmi:id="_lStwsVRvEeCQNNgUSH7L8A"/>
    191       </children>
    192160      <children xmi:type="notation:Node" xmi:id="_nSa-oFRvEeCQNNgUSH7L8A" type="3002">
    193161        <element xmi:type="uml:Operation" href="refactoring.uml#_nSHcoFRvEeCQNNgUSH7L8A"/>
    194162        <layoutConstraint xmi:type="notation:Location" xmi:id="_nSa-oVRvEeCQNNgUSH7L8A"/>
    195       </children>
    196       <children xmi:type="notation:Node" xmi:id="_oF0xgFRvEeCQNNgUSH7L8A" type="3002">
    197         <element xmi:type="uml:Operation" href="refactoring.uml#_oFrnkFRvEeCQNNgUSH7L8A"/>
    198         <layoutConstraint xmi:type="notation:Location" xmi:id="_oF0xgVRvEeCQNNgUSH7L8A"/>
    199       </children>
    200       <children xmi:type="notation:Node" xmi:id="_pdvmsFRvEeCQNNgUSH7L8A" type="3002">
    201         <element xmi:type="uml:Operation" href="refactoring.uml#_pdcrwFRvEeCQNNgUSH7L8A"/>
    202         <layoutConstraint xmi:type="notation:Location" xmi:id="_pdvmsVRvEeCQNNgUSH7L8A"/>
    203       </children>
    204       <children xmi:type="notation:Node" xmi:id="_qO6k8FRvEeCQNNgUSH7L8A" type="3002">
    205         <element xmi:type="uml:Operation" href="refactoring.uml#_qOxbAFRvEeCQNNgUSH7L8A"/>
    206         <layoutConstraint xmi:type="notation:Location" xmi:id="_qO6k8VRvEeCQNNgUSH7L8A"/>
    207       </children>
    208       <children xmi:type="notation:Node" xmi:id="_qvjM0FRvEeCQNNgUSH7L8A" type="3002">
    209         <element xmi:type="uml:Operation" href="refactoring.uml#_qvaC4FRvEeCQNNgUSH7L8A"/>
    210         <layoutConstraint xmi:type="notation:Location" xmi:id="_qvjM0VRvEeCQNNgUSH7L8A"/>
    211       </children>
    212       <children xmi:type="notation:Node" xmi:id="_snNSAFRvEeCQNNgUSH7L8A" type="3002">
    213         <element xmi:type="uml:Operation" href="refactoring.uml#_sm6XEFRvEeCQNNgUSH7L8A"/>
    214         <layoutConstraint xmi:type="notation:Location" xmi:id="_snNSAVRvEeCQNNgUSH7L8A"/>
    215       </children>
    216       <children xmi:type="notation:Node" xmi:id="_J4D38FSnEeCQNNgUSH7L8A" type="3002">
    217         <element xmi:type="uml:Operation" href="refactoring.uml#_J3w9AFSnEeCQNNgUSH7L8A"/>
    218         <layoutConstraint xmi:type="notation:Location" xmi:id="_J4D38VSnEeCQNNgUSH7L8A"/>
    219       </children>
    220       <children xmi:type="notation:Node" xmi:id="_SLu-UFSnEeCQNNgUSH7L8A" type="3002">
    221         <element xmi:type="uml:Operation" href="refactoring.uml#_SLcDYFSnEeCQNNgUSH7L8A"/>
    222         <layoutConstraint xmi:type="notation:Location" xmi:id="_SLu-UVSnEeCQNNgUSH7L8A"/>
    223163      </children>
    224164      <children xmi:type="notation:Node" xmi:id="_iJtzEFSpEeCQNNgUSH7L8A" type="3002">
     
    239179    <styles xmi:type="notation:CanonicalStyle" xmi:id="_Z0FxQVRvEeCQNNgUSH7L8A"/>
    240180    <element xmi:type="uml:Class" href="refactoring.uml#_Zzy2UFRvEeCQNNgUSH7L8A"/>
    241     <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Z0FxQlRvEeCQNNgUSH7L8A" x="705" y="30"/>
     181    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Z0FxQlRvEeCQNNgUSH7L8A" x="725" y="290"/>
    242182  </children>
    243183  <children xmi:type="notation:Shape" xmi:id="_4MKRAFRxEeCQNNgUSH7L8A" type="2001" fontName="Calibri">
     
    298238    <styles xmi:type="notation:CanonicalStyle" xmi:id="_4MKRAVRxEeCQNNgUSH7L8A"/>
    299239    <element xmi:type="uml:Class" href="refactoring.uml#_4MAgAFRxEeCQNNgUSH7L8A"/>
    300     <layoutConstraint xmi:type="notation:Bounds" xmi:id="_4MKRAlRxEeCQNNgUSH7L8A" x="280" y="540"/>
     240    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_4MKRAlRxEeCQNNgUSH7L8A" x="115" y="515"/>
    301241  </children>
    302242  <children xmi:type="notation:Shape" xmi:id="_MhUzUFRyEeCQNNgUSH7L8A" type="2001" fontName="Calibri">
     
    320260    </children>
    321261    <children xmi:type="notation:BasicCompartment" xmi:id="_MhekVlRyEeCQNNgUSH7L8A" type="7002">
    322       <children xmi:type="notation:Node" xmi:id="_OVs7AFRyEeCQNNgUSH7L8A" type="3002">
    323         <element xmi:type="uml:Operation" href="refactoring.uml#_OVaAEFRyEeCQNNgUSH7L8A"/>
    324         <layoutConstraint xmi:type="notation:Location" xmi:id="_OVs7AVRyEeCQNNgUSH7L8A"/>
    325       </children>
    326262      <children xmi:type="notation:Node" xmi:id="_PBEMMFRyEeCQNNgUSH7L8A" type="3002">
    327263        <element xmi:type="uml:Operation" href="refactoring.uml#_PA6bMFRyEeCQNNgUSH7L8A"/>
     
    343279        <element xmi:type="uml:Operation" href="refactoring.uml#_YO2xcFRyEeCQNNgUSH7L8A"/>
    344280        <layoutConstraint xmi:type="notation:Location" xmi:id="_YPJsYVRyEeCQNNgUSH7L8A"/>
     281      </children>
     282      <children xmi:type="notation:Node" xmi:id="_oF0xgFRvEeCQNNgUSH7L8A" type="3002">
     283        <element xmi:type="uml:Operation" href="refactoring.uml#_oFrnkFRvEeCQNNgUSH7L8A"/>
     284        <layoutConstraint xmi:type="notation:Location" xmi:id="_oF0xgVRvEeCQNNgUSH7L8A"/>
    345285      </children>
    346286      <styles xmi:type="notation:TitleStyle" xmi:id="_MhekV1RyEeCQNNgUSH7L8A" showTitle="true"/>
     
    357297    <styles xmi:type="notation:CanonicalStyle" xmi:id="_MhUzUVRyEeCQNNgUSH7L8A"/>
    358298    <element xmi:type="uml:Class" href="refactoring.uml#_MhLCUFRyEeCQNNgUSH7L8A"/>
    359     <layoutConstraint xmi:type="notation:Bounds" xmi:id="_MhUzUlRyEeCQNNgUSH7L8A" x="705" y="460" width="146"/>
     299    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_MhUzUlRyEeCQNNgUSH7L8A" x="710" y="560" width="146"/>
     300  </children>
     301  <children xmi:type="notation:Shape" xmi:id="_zS1aEFnhEeClo8qtmvnTtw" type="2001" fontName="Calibri">
     302    <children xmi:type="notation:DecorationNode" xmi:id="_zS1aE1nhEeClo8qtmvnTtw" type="5003">
     303      <styles xmi:type="notation:FontStyle" xmi:id="_zS_LEFnhEeClo8qtmvnTtw" bold="true"/>
     304    </children>
     305    <children xmi:type="notation:DecorationNode" xmi:id="_zS1aFFnhEeClo8qtmvnTtw" type="5019"/>
     306    <children xmi:type="notation:BasicCompartment" xmi:id="_zS1aFVnhEeClo8qtmvnTtw" type="7001">
     307      <styles xmi:type="notation:TitleStyle" xmi:id="_zS1aFlnhEeClo8qtmvnTtw" showTitle="true"/>
     308      <styles xmi:type="notation:SortingStyle" xmi:id="_zS1aF1nhEeClo8qtmvnTtw"/>
     309      <styles xmi:type="notation:FilteringStyle" xmi:id="_zS1aGFnhEeClo8qtmvnTtw"/>
     310      <styles xmi:type="notation:CanonicalStyle" xmi:id="_zS1aGVnhEeClo8qtmvnTtw"/>
     311    </children>
     312    <children xmi:type="notation:BasicCompartment" xmi:id="_zS1aGlnhEeClo8qtmvnTtw" type="7002">
     313      <children xmi:type="notation:Node" xmi:id="_8dpj0FnhEeClo8qtmvnTtw" type="3002">
     314        <element xmi:type="uml:Operation" href="refactoring.uml#_8dM34FnhEeClo8qtmvnTtw"/>
     315        <layoutConstraint xmi:type="notation:Location" xmi:id="_8dpj0VnhEeClo8qtmvnTtw"/>
     316      </children>
     317      <children xmi:type="notation:Node" xmi:id="_b4tUYFRvEeCQNNgUSH7L8A" type="3002">
     318        <element xmi:type="uml:Operation" href="refactoring.uml#_b4aZcFRvEeCQNNgUSH7L8A"/>
     319        <layoutConstraint xmi:type="notation:Location" xmi:id="_b4tUYVRvEeCQNNgUSH7L8A"/>
     320      </children>
     321      <children xmi:type="notation:Node" xmi:id="_fTA4EFRvEeCQNNgUSH7L8A" type="3002">
     322        <element xmi:type="uml:Operation" href="refactoring.uml#_fStWEFRvEeCQNNgUSH7L8A"/>
     323        <layoutConstraint xmi:type="notation:Location" xmi:id="_fTA4EVRvEeCQNNgUSH7L8A"/>
     324      </children>
     325      <children xmi:type="notation:Node" xmi:id="_iEe6IFRvEeCQNNgUSH7L8A" type="3002">
     326        <element xmi:type="uml:Operation" href="refactoring.uml#_iEVJIFRvEeCQNNgUSH7L8A"/>
     327        <layoutConstraint xmi:type="notation:Location" xmi:id="_iEe6IVRvEeCQNNgUSH7L8A"/>
     328      </children>
     329      <children xmi:type="notation:Node" xmi:id="_i4WAAFRvEeCQNNgUSH7L8A" type="3002">
     330        <element xmi:type="uml:Operation" href="refactoring.uml#_i4CeAFRvEeCQNNgUSH7L8A"/>
     331        <layoutConstraint xmi:type="notation:Location" xmi:id="_i4WAAVRvEeCQNNgUSH7L8A"/>
     332      </children>
     333      <children xmi:type="notation:Node" xmi:id="_lStwsFRvEeCQNNgUSH7L8A" type="3002">
     334        <element xmi:type="uml:Operation" href="refactoring.uml#_lSj_sFRvEeCQNNgUSH7L8A"/>
     335        <layoutConstraint xmi:type="notation:Location" xmi:id="_lStwsVRvEeCQNNgUSH7L8A"/>
     336      </children>
     337      <children xmi:type="notation:Node" xmi:id="_qO6k8FRvEeCQNNgUSH7L8A" type="3002">
     338        <element xmi:type="uml:Operation" href="refactoring.uml#_qOxbAFRvEeCQNNgUSH7L8A"/>
     339        <layoutConstraint xmi:type="notation:Location" xmi:id="_qO6k8VRvEeCQNNgUSH7L8A"/>
     340      </children>
     341      <children xmi:type="notation:Node" xmi:id="_qvjM0FRvEeCQNNgUSH7L8A" type="3002">
     342        <element xmi:type="uml:Operation" href="refactoring.uml#_qvaC4FRvEeCQNNgUSH7L8A"/>
     343        <layoutConstraint xmi:type="notation:Location" xmi:id="_qvjM0VRvEeCQNNgUSH7L8A"/>
     344      </children>
     345      <children xmi:type="notation:Node" xmi:id="_snNSAFRvEeCQNNgUSH7L8A" type="3002">
     346        <element xmi:type="uml:Operation" href="refactoring.uml#_sm6XEFRvEeCQNNgUSH7L8A"/>
     347        <layoutConstraint xmi:type="notation:Location" xmi:id="_snNSAVRvEeCQNNgUSH7L8A"/>
     348      </children>
     349      <children xmi:type="notation:Node" xmi:id="_J4D38FSnEeCQNNgUSH7L8A" type="3002">
     350        <element xmi:type="uml:Operation" href="refactoring.uml#_J3w9AFSnEeCQNNgUSH7L8A"/>
     351        <layoutConstraint xmi:type="notation:Location" xmi:id="_J4D38VSnEeCQNNgUSH7L8A"/>
     352      </children>
     353      <children xmi:type="notation:Node" xmi:id="_SLu-UFSnEeCQNNgUSH7L8A" type="3002">
     354        <element xmi:type="uml:Operation" href="refactoring.uml#_SLcDYFSnEeCQNNgUSH7L8A"/>
     355        <layoutConstraint xmi:type="notation:Location" xmi:id="_SLu-UVSnEeCQNNgUSH7L8A"/>
     356      </children>
     357      <styles xmi:type="notation:TitleStyle" xmi:id="_zS1aG1nhEeClo8qtmvnTtw" showTitle="true"/>
     358      <styles xmi:type="notation:SortingStyle" xmi:id="_zS1aHFnhEeClo8qtmvnTtw"/>
     359      <styles xmi:type="notation:FilteringStyle" xmi:id="_zS1aHVnhEeClo8qtmvnTtw"/>
     360      <styles xmi:type="notation:CanonicalStyle" xmi:id="_zS1aHlnhEeClo8qtmvnTtw"/>
     361    </children>
     362    <children xmi:type="notation:BasicCompartment" xmi:id="_zS1aH1nhEeClo8qtmvnTtw" type="7003">
     363      <styles xmi:type="notation:TitleStyle" xmi:id="_zS1aIFnhEeClo8qtmvnTtw" showTitle="true"/>
     364      <styles xmi:type="notation:SortingStyle" xmi:id="_zS1aIVnhEeClo8qtmvnTtw"/>
     365      <styles xmi:type="notation:FilteringStyle" xmi:id="_zS1aIlnhEeClo8qtmvnTtw"/>
     366      <styles xmi:type="notation:CanonicalStyle" xmi:id="_zS1aI1nhEeClo8qtmvnTtw"/>
     367    </children>
     368    <styles xmi:type="notation:CanonicalStyle" xmi:id="_zS1aEVnhEeClo8qtmvnTtw"/>
     369    <element xmi:type="uml:Class" href="refactoring.uml#_zSPkMFnhEeClo8qtmvnTtw"/>
     370    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_zS1aElnhEeClo8qtmvnTtw" x="485" y="30"/>
     371  </children>
     372  <children xmi:type="notation:Shape" xmi:id="_n5KbMFolEeClo8qtmvnTtw" type="2001" fontName="Calibri">
     373    <children xmi:type="notation:DecorationNode" xmi:id="_n5KbM1olEeClo8qtmvnTtw" type="5003">
     374      <styles xmi:type="notation:FontStyle" xmi:id="_n5KbRFolEeClo8qtmvnTtw" bold="true"/>
     375    </children>
     376    <children xmi:type="notation:DecorationNode" xmi:id="_n5KbNFolEeClo8qtmvnTtw" type="5019"/>
     377    <children xmi:type="notation:BasicCompartment" xmi:id="_n5KbNVolEeClo8qtmvnTtw" type="7001">
     378      <children xmi:type="notation:Node" xmi:id="_rFdYEFolEeClo8qtmvnTtw" type="3001">
     379        <element xmi:type="uml:Property" href="refactoring.uml#_rEkAMFolEeClo8qtmvnTtw"/>
     380        <layoutConstraint xmi:type="notation:Location" xmi:id="_rFdYEVolEeClo8qtmvnTtw"/>
     381      </children>
     382      <children xmi:type="notation:Node" xmi:id="_TrWYwFRsEeCQNNgUSH7L8A" type="3001">
     383        <element xmi:type="uml:Property" href="refactoring.uml#_TrDd0FRsEeCQNNgUSH7L8A"/>
     384        <layoutConstraint xmi:type="notation:Location" xmi:id="_TrWYwVRsEeCQNNgUSH7L8A"/>
     385      </children>
     386      <children xmi:type="notation:Node" xmi:id="_JER8QFomEeClo8qtmvnTtw" type="3001">
     387        <element xmi:type="uml:Property" href="refactoring.uml#_JD1QUFomEeClo8qtmvnTtw"/>
     388        <layoutConstraint xmi:type="notation:Location" xmi:id="_JER8QVomEeClo8qtmvnTtw"/>
     389      </children>
     390      <styles xmi:type="notation:TitleStyle" xmi:id="_n5KbNlolEeClo8qtmvnTtw" showTitle="true"/>
     391      <styles xmi:type="notation:SortingStyle" xmi:id="_n5KbN1olEeClo8qtmvnTtw"/>
     392      <styles xmi:type="notation:FilteringStyle" xmi:id="_n5KbOFolEeClo8qtmvnTtw"/>
     393      <styles xmi:type="notation:CanonicalStyle" xmi:id="_n5KbOVolEeClo8qtmvnTtw"/>
     394    </children>
     395    <children xmi:type="notation:BasicCompartment" xmi:id="_n5KbOlolEeClo8qtmvnTtw" type="7002">
     396      <styles xmi:type="notation:TitleStyle" xmi:id="_n5KbO1olEeClo8qtmvnTtw" showTitle="true"/>
     397      <styles xmi:type="notation:SortingStyle" xmi:id="_n5KbPFolEeClo8qtmvnTtw"/>
     398      <styles xmi:type="notation:FilteringStyle" xmi:id="_n5KbPVolEeClo8qtmvnTtw"/>
     399      <styles xmi:type="notation:CanonicalStyle" xmi:id="_n5KbPlolEeClo8qtmvnTtw"/>
     400    </children>
     401    <children xmi:type="notation:BasicCompartment" xmi:id="_n5KbP1olEeClo8qtmvnTtw" type="7003">
     402      <styles xmi:type="notation:TitleStyle" xmi:id="_n5KbQFolEeClo8qtmvnTtw" showTitle="true"/>
     403      <styles xmi:type="notation:SortingStyle" xmi:id="_n5KbQVolEeClo8qtmvnTtw"/>
     404      <styles xmi:type="notation:FilteringStyle" xmi:id="_n5KbQlolEeClo8qtmvnTtw"/>
     405      <styles xmi:type="notation:CanonicalStyle" xmi:id="_n5KbQ1olEeClo8qtmvnTtw"/>
     406    </children>
     407    <styles xmi:type="notation:CanonicalStyle" xmi:id="_n5KbMVolEeClo8qtmvnTtw"/>
     408    <element xmi:type="uml:Class" href="refactoring.uml#_n4H5YFolEeClo8qtmvnTtw"/>
     409    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_n5KbMlolEeClo8qtmvnTtw" x="510" y="355"/>
     410  </children>
     411  <children xmi:type="notation:Shape" xmi:id="_6v4_gFxoEeCd3KUH_BuVkA" type="2013" fontName="Calibri">
     412    <children xmi:type="notation:DecorationNode" xmi:id="_6v4_glxoEeCd3KUH_BuVkA" type="5018"/>
     413    <children xmi:type="notation:DecorationNode" xmi:id="_6v4_g1xoEeCd3KUH_BuVkA" type="5035"/>
     414    <children xmi:type="notation:BasicCompartment" xmi:id="_6v4_hFxoEeCd3KUH_BuVkA" type="7029">
     415      <styles xmi:type="notation:TitleStyle" xmi:id="_6v4_hVxoEeCd3KUH_BuVkA" showTitle="true"/>
     416      <styles xmi:type="notation:SortingStyle" xmi:id="_6v4_hlxoEeCd3KUH_BuVkA"/>
     417      <styles xmi:type="notation:FilteringStyle" xmi:id="_6v4_h1xoEeCd3KUH_BuVkA"/>
     418      <styles xmi:type="notation:CanonicalStyle" xmi:id="_6v4_iFxoEeCd3KUH_BuVkA"/>
     419    </children>
     420    <children xmi:type="notation:BasicCompartment" xmi:id="_6v4_iVxoEeCd3KUH_BuVkA" type="7030">
     421      <styles xmi:type="notation:TitleStyle" xmi:id="_6v4_ilxoEeCd3KUH_BuVkA" showTitle="true"/>
     422      <styles xmi:type="notation:SortingStyle" xmi:id="_6v4_i1xoEeCd3KUH_BuVkA"/>
     423      <styles xmi:type="notation:FilteringStyle" xmi:id="_6v4_jFxoEeCd3KUH_BuVkA"/>
     424      <styles xmi:type="notation:CanonicalStyle" xmi:id="_6v4_jVxoEeCd3KUH_BuVkA"/>
     425    </children>
     426    <children xmi:type="notation:BasicCompartment" xmi:id="_6v4_jlxoEeCd3KUH_BuVkA" type="7031">
     427      <styles xmi:type="notation:TitleStyle" xmi:id="_6v4_j1xoEeCd3KUH_BuVkA" showTitle="true"/>
     428      <styles xmi:type="notation:SortingStyle" xmi:id="_6v4_kFxoEeCd3KUH_BuVkA"/>
     429      <styles xmi:type="notation:FilteringStyle" xmi:id="_6v4_kVxoEeCd3KUH_BuVkA"/>
     430      <styles xmi:type="notation:CanonicalStyle" xmi:id="_6v4_klxoEeCd3KUH_BuVkA"/>
     431    </children>
     432    <element xmi:type="uml:Interface" href="refactoring.uml#_6vSikFxoEeCd3KUH_BuVkA"/>
     433    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_6v4_gVxoEeCd3KUH_BuVkA" x="773" y="118"/>
    360434  </children>
    361435  <styles xmi:type="notation:DiagramStyle" xmi:id="_Uz4jkVRrEeCQNNgUSH7L8A"/>
     
    387461    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_JJ3dYVlWEeCTIL9CCJRwPw" id="(1.0,0.3005464480874317)"/>
    388462  </edges>
     463  <edges xmi:type="notation:Connector" xmi:id="_Chj2IVomEeClo8qtmvnTtw" type="4001" source="_Plrj4FRsEeCQNNgUSH7L8A" target="_n5KbMFolEeClo8qtmvnTtw">
     464    <children xmi:type="notation:DecorationNode" xmi:id="_Chj2JFomEeClo8qtmvnTtw" type="6018">
     465      <layoutConstraint xmi:type="notation:Location" xmi:id="_Chj2JVomEeClo8qtmvnTtw" y="40"/>
     466    </children>
     467    <styles xmi:type="notation:FontStyle" xmi:id="_Chj2IlomEeClo8qtmvnTtw" fontName="Calibri"/>
     468    <element xmi:type="uml:Generalization" href="refactoring.uml#_Chj2IFomEeClo8qtmvnTtw"/>
     469    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Chj2I1omEeClo8qtmvnTtw" points="[-2, -33, 11, 58]$[14, -47, 27, 44]"/>
     470    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ChtAEFomEeClo8qtmvnTtw" id="(1.0,0.19760479041916168)"/>
     471  </edges>
     472  <edges xmi:type="notation:Edge" xmi:id="_OyMHkFqlEeC9SaX6k5fY1Q" type="4002" source="_Z0FxQFRvEeCQNNgUSH7L8A" target="_zS1aEFnhEeClo8qtmvnTtw">
     473    <children xmi:type="notation:DecorationNode" xmi:id="_OyMHlFqlEeC9SaX6k5fY1Q" type="6001">
     474      <layoutConstraint xmi:type="notation:Location" xmi:id="_OyMHlVqlEeC9SaX6k5fY1Q" y="40"/>
     475    </children>
     476    <children xmi:type="notation:DecorationNode" xmi:id="_OyMHllqlEeC9SaX6k5fY1Q" type="6010">
     477      <layoutConstraint xmi:type="notation:Location" xmi:id="_OyMHl1qlEeC9SaX6k5fY1Q" y="20"/>
     478    </children>
     479    <styles xmi:type="notation:RoutingStyle" xmi:id="_OyMHkVqlEeC9SaX6k5fY1Q"/>
     480    <styles xmi:type="notation:FontStyle" xmi:id="_OyMHklqlEeC9SaX6k5fY1Q" fontName="Calibri"/>
     481    <element xmi:type="uml:Dependency" href="refactoring.uml#_OyCWkFqlEeC9SaX6k5fY1Q"/>
     482    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_OyMHk1qlEeC9SaX6k5fY1Q" points="[-12, -1, 96, 4]$[-94, -4, 14, 1]"/>
     483    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_OyV4kFqlEeC9SaX6k5fY1Q" id="(0.11214953271028037,0.5298013245033113)"/>
     484    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_OyV4kVqlEeC9SaX6k5fY1Q" id="(0.9054054054054054,0.5254237288135594)"/>
     485  </edges>
     486  <edges xmi:type="notation:Edge" xmi:id="_VjhRcFqlEeC9SaX6k5fY1Q" type="4002" source="_Z0FxQFRvEeCQNNgUSH7L8A" target="_n5KbMFolEeClo8qtmvnTtw">
     487    <children xmi:type="notation:DecorationNode" xmi:id="_VjhRdFqlEeC9SaX6k5fY1Q" type="6001">
     488      <layoutConstraint xmi:type="notation:Location" xmi:id="_VjhRdVqlEeC9SaX6k5fY1Q" y="40"/>
     489    </children>
     490    <children xmi:type="notation:DecorationNode" xmi:id="_VjhRdlqlEeC9SaX6k5fY1Q" type="6010">
     491      <layoutConstraint xmi:type="notation:Location" xmi:id="_VjhRd1qlEeC9SaX6k5fY1Q" y="20"/>
     492    </children>
     493    <styles xmi:type="notation:RoutingStyle" xmi:id="_VjhRcVqlEeC9SaX6k5fY1Q"/>
     494    <styles xmi:type="notation:FontStyle" xmi:id="_VjhRclqlEeC9SaX6k5fY1Q" fontName="Calibri"/>
     495    <element xmi:type="uml:Dependency" href="refactoring.uml#_VjNvcFqlEeC9SaX6k5fY1Q"/>
     496    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_VjhRc1qlEeC9SaX6k5fY1Q" points="[-3, 1, 165, -25]$[-160, -26, 8, -52]"/>
     497    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_VjqbYFqlEeC9SaX6k5fY1Q" id="(0.028037383177570093,0.6026490066225165)"/>
     498  </edges>
    389499</notation:Diagram>
Note: See TracChangeset for help on using the changeset viewer.