Source code: com/memoire/bu/BuExplorer.java
1 /**
2 * @modification $Date: 2003/01/23 09:59:29 $
3 * @statut unstable
4 * @file BuExplorer.java
5 * @version 0.36
6 * @author Guillaume Desnoix
7 * @email guillaume@desnoix.com
8 * @license GNU General Public License 2 (GPL2)
9 * @copyright 1998-2001 Guillaume Desnoix
10 */
11
12 package com.memoire.bu;
13
14 import com.memoire.bu.*;
15 import com.memoire.dnd.*;
16 import com.memoire.fu.*;
17 import com.memoire.xml.*;
18
19 import java.awt.*;
20 import java.awt.event.*;
21 import java.io.*;
22 import java.net.*;
23 import java.lang.reflect.*;
24 import java.text.*;
25 import java.util.*;
26 import java.util.zip.*;
27
28 import javax.swing.*;
29 import javax.swing.border.*;
30 import javax.swing.event.*;
31
32 public class BuExplorer
33 extends BuPanel
34 implements ActionListener, ListSelectionListener
35 {
36 protected Icon i_computer ;
37 protected Icon i_disk ;
38 protected Icon i_floppy ;
39 protected Icon i_directory;
40 protected Icon i_file ;
41 protected Icon i_home ;
42 protected Icon i_parent ;
43
44 protected BuCommonInterface app_;
45 protected Vector listeners_;
46
47 protected BuComboBox roots_;
48 protected BuTextField current_;
49 protected BuEmptyList dirs_;
50 protected BuComboBox filters_;
51 protected BuComboBox sorters_;
52 protected BuEmptyList files_;
53
54 protected BuFileViewer viewer_; //BuList
55
56 protected BuPopupMenu pmCurrent_;
57 protected BuPopupMenu pmDirs_;
58 protected BuPopupMenu pmFiles_;
59
60 protected BuMenuItem miOuvrirFichier_;
61 protected BuMenuItem miCvsAdd_;
62 protected BuMenuItem miCvsUpdate_;
63 protected BuMenuItem miCvsCommit_;
64 protected BuMenuItem miAntBuild_;
65 protected BuMenuItem miMake_;
66
67 protected FuFile last_;
68
69 public BuExplorer()
70 {
71 this(null,true,null);
72 }
73
74 public BuExplorer(FuFile _path)
75 {
76 this(null,true,_path);
77 }
78
79 public BuExplorer(BuCommonInterface _app)
80 {
81 this(_app,false,null);
82 }
83
84 public BuExplorer(BuCommonInterface _app, boolean _viewer)
85 {
86 this(_app,_viewer,null);
87 }
88
89 public BuExplorer(BuCommonInterface _app, boolean _viewer, FuFile _path)
90 {
91 app_ =_app;
92 listeners_=new Vector(1,1);
93
94 MouseListener mh=new MouseHandler();
95 KeyListener kh=new KeyHandler ();
96
97 roots_=new BuComboBox();
98 roots_.setMaximumRowCount(20);
99
100 current_=new BuTextField();//LabelMultiLine();
101 //current_.setWrapMode(BuLabelMultiLine.LETTER);
102 //current_.setBorder(new EmptyBorder(2,6,0,6));
103 current_.addMouseListener(mh);
104 current_.addActionListener(new ActionListener()
105 {
106 public void actionPerformed(ActionEvent _evt)
107 {
108 current_.setEnabled(false);
109 current_.repaint(0);
110 String p=BuLib.expandedPath(current_.getText());
111
112 /*
113 File r=null;
114 try
115 {
116 r=new URLAdapter(new URL(p));
117 ((URLAdapter)r).init();
118 }
119 catch(Exception ex) { r=new File(p); }
120 */
121
122 FuFile r=FuFile.createFile(p);
123
124 if(r.exists())
125 {
126 setCurrentDirectory(r);
127 }
128 else
129 {
130 getToolkit().beep();
131 current_.setText(BuLib.reducedPath(""+last_));
132 }
133 current_.setEnabled(true);
134 current_.repaint(0);
135 current_.requestFocus();
136 }
137 });
138
139 dirs_=new BuEmptyList();
140 dirs_.setEmptyText("No directory");
141 //dirs_.setBorder(new EmptyBorder(3,3,3,3));
142 dirs_.addMouseListener(mh);
143 dirs_.addKeyListener (kh);
144 dirs_.addListSelectionListener(this);
145
146 filters_=new BuComboBox();
147 filters_.setMaximumRowCount(20);
148
149 sorters_=new BuComboBox();
150 sorters_.addItem("Name");
151 sorters_.addItem("Type");
152 sorters_.addItem("Date");
153 sorters_.addItem("Size");
154 sorters_.setMaximumRowCount(20);
155
156 files_=new BuEmptyList();
157 files_.setEmptyText("No file");
158 //files_.setBorder(new EmptyBorder(3,3,3,3));
159 files_.addMouseListener(mh);
160 files_.addKeyListener (kh);
161 files_.addListSelectionListener(this);
162
163 pmCurrent_=new BuPopupMenu(BuResource.BU.getString("Répertoire"));
164 pmCurrent_.addMenuItem(BuResource.BU.getString("Rafraîchir"),"RAFRAICHIR" ,true);
165 pmCurrent_.addMenuItem(BuResource.BU.getString("Créer..." ),"CREER_REPERTOIRE",true);
166 pmCurrent_.addSeparator();
167 miCvsUpdate_=pmCurrent_.addMenuItem("Update","CVS_UPDATE",false);
168 miCvsCommit_=pmCurrent_.addMenuItem("Commit","CVS_COMMIT",false);
169 miAntBuild_ =pmCurrent_.addMenuItem("Build" ,"ANT_BUILD" ,false);
170 miMake_ =pmCurrent_.addMenuItem("Make" ,"MAKE" ,false);
171
172 pmDirs_=new BuPopupMenu(BuResource.BU.getString("Répertoires"));
173 pmDirs_.addMenuItem(BuResource.BU.getString("Ouvrir" ),"OUVRIR_REPERTOIRE" ,true);
174 pmDirs_.addSeparator();
175 pmDirs_.addMenuItem(BuResource.BU.getString("Renommer..."),"RENOMMER_REPERTOIRE",true);
176 pmDirs_.addMenuItem(BuResource.BU.getString("Détruire..."),"DETRUIRE_REPERTOIRE",true);
177
178 pmFiles_=new BuPopupMenu(BuResource.BU.getString("Fichiers"));
179 miOuvrirFichier_=pmFiles_.addMenuItem
180 (BuResource.BU.getString("Ouvrir"),"OUVRIR_FICHIER",true);
181 pmFiles_.addMenuItem(BuResource.BU.getString("Tout sélectionner"),"TOUTSELECTIONNER",true);
182 pmFiles_.addSeparator();
183 pmFiles_.addMenuItem(BuResource.BU.getString("Renommer..."),"RENOMMER_FICHIER",true);
184 pmFiles_.addMenuItem(BuResource.BU.getString("Détruire..."),"DETRUIRE_FICHIER",true);
185 pmFiles_.addSeparator();
186 miCvsAdd_=pmFiles_.addMenuItem("Add","CVS_ADD",false);
187
188 BuPanel p1=new BuPanel(new BuVerticalLayout(2,true,true));
189 p1.add(roots_);
190 p1.add(current_);
191 BuScrollPane spDirs=new BuScrollPane(dirs_);
192 spDirs.setPreferredSize(new Dimension(150,150));
193 p1.add(spDirs);
194 //p1.setPreferredSize(new Dimension(150,220));
195
196 BuPanel p2=new BuPanel(new BuVerticalLayout(2,true,true));
197 //p2.setPreferredSize(new Dimension(150,220));
198 p2.add(filters_);
199 p2.add(sorters_);
200 BuScrollPane spFiles=new BuScrollPane(files_);
201 spFiles.setPreferredSize(new Dimension(150,150));
202 p2.add(spFiles);
203
204 BuSplit2Pane spv=new BuSplit2Pane
205 (p1,p2,
206 (_viewer ? BuSplit2Pane.HORIZONTAL : BuSplit2Pane.VERTICAL));
207
208 setLayout(new BuBorderLayout());
209
210 addMtab();
211 addDefaultFilters();
212
213 new DndSource(DndRequestSelection.SINGLETON).add(dirs_);
214 new DndSource(DndRequestSelection.SINGLETON).add(files_);
215
216 if(_viewer)
217 {
218 /*
219 viewer_=new BuList();
220 viewer_.setBackground(UIManager.getColor("Panel.background"));
221 viewer_.setCellRenderer(createFileViewer());
222 */
223
224 int nbcols=BuPreferences.BU.getIntegerProperty("explorer.columns",1);
225 if(nbcols<1) nbcols=1;
226 if(nbcols>5) nbcols=5;
227
228 viewer_=createFileViewer();
229 viewer_.setBorder(new EmptyBorder(2,2,2,2));
230 viewer_.setLayout(new BuGridLayout
231 (nbcols,2,2,true,true,false,false));
232
233 final BuScrollPane sp3=new BuScrollPane(viewer_);
234 sp3.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
235 sp3.setPreferredSize(new Dimension
236 (sp3.getPreferredSize().width+202*nbcols-2,409));
237 sp3.getVerticalScrollBar().setUnitIncrement(202);
238 sp3.getVerticalScrollBar().setBlockIncrement(404);
239 sp3.getHorizontalScrollBar().setUnitIncrement(202);
240 sp3.getHorizontalScrollBar().setBlockIncrement(404);
241
242 /*
243 final BuSplit3Pane sph=new BuSplit3Pane
244 (spv,sp3,null,BuSplit3Pane.HORIZONTAL);
245 add(sph);
246 */
247 final BuPanel sph=new BuPanel(new BuBorderLayout(2,2));
248 sph.add(spv,BuBorderLayout.CENTER);
249 sph.add(sp3,BuBorderLayout.EAST);
250 add(sph);
251
252 /*
253 final BuToggleButton tb=new BuToggleButton("Viewer");
254 tb.setRequestFocusEnabled(false);
255 tb.setMargin(new Insets(1,1,1,1));
256 tb.setFont(getETF());
257 tb.setIcon(BuResource.resizeIcon(BuResource.BU.getIcon("voir"),12));
258 tb.setSelected(true);
259 tb.setHorizontalAlignment(BuToggleButton.RIGHT);
260 tb.addActionListener(new ActionListener()
261 {
262 public void actionPerformed(ActionEvent _evt)
263 {
264 sp3.setVisible(tb.isSelected());
265 updateViewer();
266 //sph.updateSplits();
267 sph.revalidate();
268 }
269 });
270 BuPanel ptb=new BuPanel(new FlowLayout(FlowLayout.RIGHT,0,0));
271 ptb.add(tb);
272 p2.add(ptb);
273 */
274 }
275 else
276 {
277 add(spv);
278 }
279
280 updateLnf();
281
282 roots_ .addActionListener(this);
283 filters_.addActionListener(this);
284 sorters_.addActionListener(this);
285 setCurrentDirectory(FuFile.ensureFuFile(_path));
286
287 // adjust the top of the scrollpanes
288 int ph1=p1.getPreferredSize().height;
289 int ph2=p2.getPreferredSize().height;
290 if(ph2>ph1)
291 {
292 p1.setBorder(new EmptyBorder(ph2-ph1,0,0,0));
293 p2.setBorder(new EmptyBorder(0,0,0,0));
294 //Dimension ps=current_.getPreferredSize();
295 //current_.setPreferredSize(new Dimension(ps.width,ps.height+ph2-ph1));
296 }
297 else
298 {
299 p1.setBorder(new EmptyBorder(0,0,0,0));
300 p2.setBorder(new EmptyBorder(ph1-ph2,0,0,0));
301 }
302
303
304 p1.setPreferredSize(new Dimension(150,220));
305 p2.setPreferredSize(new Dimension(150,220));
306 }
307
308 public void updateUI()
309 {
310 super.updateUI();
311 try
312 {
313 updateLnf();
314 pmCurrent_.updateUI();
315 pmDirs_ .updateUI();
316 pmFiles_ .updateUI();
317 }
318 catch(Exception ex) { }
319 }
320
321 private static Font getETF()
322 {
323 return BuLib.deriveFont("List.font",Font.PLAIN,-2);
324 }
325
326 private void updateLnf()
327 {
328 i_computer =getLnfIcon("FileView.computerIcon");
329 i_disk =getLnfIcon("FileView.hardDriveIcon");
330 i_floppy =getLnfIcon("FileView.floppyDriveIcon");
331 i_directory=getLnfIcon("FileView.directoryIcon");
332 i_file =getLnfIcon("FileView.fileIcon");
333 i_home =getLnfIcon("FileChooser.homeFolderIcon");
334 i_parent =getLnfIcon("FileChooser.upFolderIcon");
335
336 if(i_file!=null) DndIcons.put(FuFile.class,i_file);
337
338 Font ft=getETF();
339 roots_ .setFont(ft);
340 current_.setFont(ft);
341 dirs_ .setFont(ft);
342 filters_.setFont(ft);
343 sorters_.setFont(ft);
344 files_ .setFont(ft);
345
346 roots_ .setRenderer (new FileCR(true));
347 dirs_ .setCellRenderer(new FileCR(false));
348 files_ .setCellRenderer(new FileCR(false));
349 filters_.setRenderer (new FilterCR());
350 sorters_.setRenderer (new FilterCR());
351 }
352
353 protected Icon getLnfIcon(String _key)
354 {
355 Icon r=UIManager.getIcon(_key);
356
357 /*
358 if(r instanceof ImageIcon)
359 {
360 Image img=((ImageIcon)r).getImage();
361 int rw=Math.max(img.getWidth(this),img.getHeight(this));
362 int dw=BuResource.BU.getDefaultSize();
363 System.err.println("%%% RW="+rw+" DW="+dw);
364 if(rw>dw)
365 r=new BuIcon(img.getScaledInstance
366 (dw,dw,Image.SCALE_SMOOTH));
367 }
368 */
369
370 return r;
371 }
372
373 protected void updateMenuCurrent()
374 {
375 miCvsUpdate_.setEnabled
376 (getCurrentDirectory().createChild("CVS" ).exists());
377 miCvsCommit_.setEnabled
378 (getCurrentDirectory().createChild("CVS" ).exists());
379 miAntBuild_ .setEnabled
380 (getCurrentDirectory().createChild("build.xml").exists());
381 miMake_ .setEnabled
382 (getCurrentDirectory().createChild("Makefile" ).exists());
383 pmCurrent_.computeMnemonics();
384 }
385
386 protected void updateMenuDirs()
387 {
388 int l=dirs_.getSelectedValues().length;
389 BuActionEnabler.setEnabledForAction(pmDirs_,"OUVRIR_REPERTOIRE" ,l==1);
390 BuActionEnabler.setEnabledForAction(pmDirs_,"DETRUIRE_REPERTOIRE",l==1);
391 BuActionEnabler.setEnabledForAction(pmDirs_,"RENOMMER_REPERTOIRE",l==1);
392 pmDirs_.computeMnemonics();
393 }
394
395 protected void updateMenuFiles()
396 {
397 int l=files_.getSelectedValues().length;
398 int s=listeners_.size();
399 BuActionEnabler.setEnabledForAction(pmFiles_,"OUVRIR_FICHIER" ,(l>0)&&(s>0));
400 BuActionEnabler.setEnabledForAction(pmFiles_,"DETRUIRE_FICHIER",l==1);
401 BuActionEnabler.setEnabledForAction(pmFiles_,"RENOMMER_FICHIER",l==1);
402 miCvsAdd_.setEnabled(getCurrentDirectory().createChild("CVS").exists());
403 pmFiles_.computeMnemonics();
404 }
405
406 protected void updateViewer()
407 {
408 if(viewer_==null) return;
409
410 Object[] d=dirs_ .getSelectedValues();
411 Object[] f=files_.getSelectedValues();
412
413 /*
414 if((d!=null)&&(d.length>0)&&(d[0] instanceof URLAdapter))
415 {
416 URLAdapter p=(URLAdapter)d[0];
417 System.err.println("Name="+p.getName());
418 System.err.println("Path="+p.getPath());
419 System.err.println("Dir.="+p.isDirectory());
420 }
421 if((f!=null)&&(f.length>0)&&(f[0] instanceof URLAdapter))
422 {
423 URLAdapter p=(URLAdapter)f[0];
424 System.err.println("Name="+p.getName());
425 System.err.println("Path="+p.getPath());
426 System.err.println("Dir.="+p.isDirectory());
427 }
428 */
429
430 /*
431 DefaultListModel lm=new DefaultListModel();
432 for(int i=0;i<d.length;i++) lm.addElement(d[i]);
433 for(int i=0;i<f.length;i++) lm.addElement(f[i]);
434 viewer_.setModel(lm);
435 */
436
437 viewer_.updateContent(d,f);
438 }
439
440 public BuFileViewer createFileViewer()
441 {
442 BuFileViewer r=new BuFileViewer();
443 r.setFileRenderer(new BuFileRenderer());
444 return r;
445 }
446
447 public void addActionListener(ActionListener _l)
448 { listeners_.addElement(_l); }
449
450 public void removeActionListener(ActionListener _l)
451 { listeners_.removeElement(_l); }
452
453 private class KeyHandler extends KeyAdapter
454 {
455 public void keyTyped(KeyEvent _evt)
456 {
457 Object source=_evt.getSource();
458 char c=Character.toUpperCase(_evt.getKeyChar());
459
460 if(c==KeyEvent.VK_ENTER)
461 {
462 if( (source==dirs_)
463 &&(dirs_.getSelectedValues().length==1))
464 openDirectory();
465 else
466 if( (source==files_)
467 &&(files_.getSelectedValues().length==1))
468 openFile();
469 }
470 else
471 if(Character.isLetterOrDigit(c))
472 {
473 if((source==dirs_)||(source==files_))
474 {
475 try
476 {
477 JList l=(JList)source;
478 ListModel m=l.getModel();
479 int t=m.getSize();
480 for(int i=0;i<t;i++)
481 {
482 FuFile f=(FuFile)m.getElementAt(i);
483 String v=f.getName();
484 if((v.length()>0)&&(Character.toUpperCase(v.charAt(0))==c))
485 {
486 l.setSelectedValue(f,true);
487 break;
488 }
489 }
490 }
491 catch(Throwable th) { th.printStackTrace(); }
492 }
493 }
494 }
495 }
496
497 private class MouseHandler extends MouseAdapter
498 {
499 public void mouseClicked(MouseEvent _evt)
500 {
501 Object source=_evt.getSource();
502
503 if(_evt.getClickCount()==2)
504 {
505 if( (source==dirs_)
506 &&(dirs_.getSelectedValues().length==1))
507 openDirectory();
508 else
509 if( (source==files_)
510 &&(files_.getSelectedValues().length==1))
511 openFile();
512 }
513 else
514 if((_evt.getModifiers()&InputEvent.BUTTON3_MASK)!= 0)
515 {
516 if(source==current_)
517 {
518 updateMenuCurrent();
519 Point p=SwingUtilities.convertPoint
520 (current_,new Point(0,current_.getHeight()),BuExplorer.this);
521 pmCurrent_.show(BuExplorer.this,p.x,p.y+2);//p.x,p.y);
522 }
523 else
524 if(source==dirs_)
525 {
526 updateMenuDirs();
527 Point p=SwingUtilities.convertPoint
528 (dirs_,new Point(0,_evt.getY()),BuExplorer.this);
529 pmDirs_.show(BuExplorer.this,p.x,p.y+10);//p.x,p.y);
530 }
531 else
532 if(source==files_)
533 {
534 updateMenuFiles();
535 Point p=SwingUtilities.convertPoint
536 (files_,new Point(0,_evt.getY()),BuExplorer.this);
537 pmFiles_.show(BuExplorer.this,p.x,p.y+10);//p.x,p.y);
538 }
539 }
540 }
541 }
542
543 public class Root extends FuFileFile
544 {
545 private String display_;
546 private String type_;
547
548 public Root(String _mount, String _display, String _type)
549 {
550 super(_mount);
551 type_ =_type;
552 if(_display==null) _display=_mount;
553 if(!_mount.equals(_display)) display_=_display;
554 }
555
556 public String getViewText()
557 {
558 String r;
559
560 if("..".equals(type_)) r="..";
561 else if(display_!=null) r=display_;
562 else r=BuLib.reducedPath(getAbsolutePath());
563
564 return r;
565 }
566
567 public Icon getViewIcon()
568 {
569 Icon r=i_disk;
570
571 if(".." .equals(type_)) r=i_parent;
572 else
573 if("home" .equals(type_)) r=i_home;
574 else
575 if("directory".equals(type_)) r=i_directory;
576 else
577 if("computer" .equals(type_)) r=i_computer;
578 else
579 if("floppy" .equals(type_)) r=i_floppy;
580
581 return r;
582 }
583 }
584
585 /*
586 public static class URLAdapter extends File
587 {
588 private URL url_;
589 private String name_;
590
591 private boolean init_;
592 private boolean exists_;
593 private long lastModified_;
594 private long length_;
595 private String[] list_;
596
597 public URLAdapter(URLAdapter _a, String _n) throws MalformedURLException
598 {
599 this(new URL(_a.url_,_n));
600 }
601
602 public URLAdapter(URL _url)
603 {
604 super(_url.getFile());
605 url_ =_url;
606 list_=new String[0];
607 init_=false;
608 }
609
610 public void init()
611 {
612 if(!init_)
613 {
614 init_=true;
615 try
616 {
617 URLConnection cnx=getURL().openConnection();
618 lastModified_=cnx.getLastModified();
619 length_ =cnx.getContentLength();
620 exists_=true;
621
622 if(isDirectory())
623 {
624 InputStream in=cnx.getInputStream();
625 BufferedReader nr=new BufferedReader(new InputStreamReader(in));
626 Vector v =new Vector();
627
628 if("ftp".equals(url_.getProtocol()))
629 {
630 while(true)
631 {
632 String l=nr.readLine();
633 if(l==null) break;
634 if(l.length()<53) continue;
635 char d=l.charAt(0);
636 l=l.substring(53);
637 int i=0;
638 while( (i<l.length())
639 &&!Character.isWhitespace(l.charAt(i))) i++;
640 l=l.substring(i).trim();
641 if(d=='d') l+="/";
642 v.addElement(l);
643 }
644 }
645 else
646 if("http".equals(url_.getProtocol()))
647 {
648 v.addElement("[content].html");
649
650 XmlParser p=new XmlParser(nr,url_.toString(),XmlParser.HTML);
651 XmlReader r=new XmlReader(XmlParser.HTML);
652 p.setXmlListener(r);
653 p.parse();
654 //System.out.println(r.getTree());
655 XmlNode[] nodes=r.getTree().findNodes("A");
656 String base =""+url_;
657
658 for(int i=0;i<nodes.length;i++)
659 {
660 String href=nodes[i].getAttribute("HREF");
661 if(href!=null)
662 {
663 try
664 {
665 String l=""+new URL(url_,href);
666 if(l.startsWith(base))
667 {
668 l=l.substring(base.length());
669 int k=l.indexOf("/");
670 if((k==-1)||(k==l.length()-1))
671 if(!v.contains(l)) v.addElement(l);
672 }
673 }
674 catch(Exception ex) { }
675 }
676 }
677 }
678
679 nr.close();
680
681 int l=v.size();
682 list_=new String[l];
683 for(int i=0;i<l;i++)
684 list_[i]=(String)v.elementAt(i);
685 }
686 }
687 catch(Exception ex)
688 {
689 exists_=false;
690 //ex.printStackTrace();
691 }
692 }
693 }
694
695 public InputStream getInputStream() throws IOException
696 {
697 return getURL().openStream();
698 }
699
700 public URL getURL()
701 {
702 if(getPath().endsWith("[content].html"))
703 {
704 try { return new URL(getParent()); }
705 catch(MalformedURLException ex) { }
706 }
707
708 return url_;
709 }
710
711 public String getText()
712 {
713 return "["+url_.getHost()+"]"+getURL().getFile();
714 }
715
716 public boolean canRead()
717 {
718 return true;
719 }
720
721 public boolean canWrite()
722 {
723 return false;
724 }
725
726 //int compareTo(File pathname)
727 //int compareTo(Object o)
728
729 public boolean createNewFile()
730 {
731 return false;
732 }
733
734 public boolean delete()
735 {
736 return false;
737 }
738
739 public void deleteOnExit()
740 {
741 }
742
743 public boolean equals(Object _o)
744 {
745 return (_o instanceof URLAdapter)&&(url_==((URLAdapter)_o).url_);
746 }
747
748 public boolean exists()
749 {
750 return !init_ ? true : exists_;
751 }
752
753 public File getAbsoluteFile()
754 {
755 return this;
756 }
757
758 public String getAbsolutePath()
759 {
760 return url_.toString();
761 }
762
763 public File getCanonicalFile()
764 {
765 return this;
766 }
767
768 public String getCanonicalPath()
769 {
770 return url_.toString();
771 }
772
773 public void setName(String _name)
774 {
775 name_=_name;
776 }
777
778 public String getName()
779 {
780 if(name_!=null) return name_;
781
782 String r;
783
784 try
785 {
786 r=url_.getPath();
787 if((r!=null)&&r.endsWith("/"))
788 r=r.substring(0,r.length()-1);
789 int i=r.lastIndexOf('/');
790 r=r.substring(i+1);
791 }
792 catch(Exception ex) { r=null; }
793
794 return r;
795 }
796
797 public String getParent()
798 {
799 String r;
800
801 try
802 {
803 r=url_.getFile();
804 if((r!=null)&&r.endsWith("/"))
805 r=r.substring(0,r.length()-1);
806 int i=r.lastIndexOf('/');
807 if(i>=0)
808 {
809 r=r.substring(0,i+1);
810 r=new URL(url_,r).toString();
811 }
812 else r=null;
813 }
814 catch(Exception ex) { r=null; }
815
816 return r;
817 }
818
819 public File getParentFile()
820 {
821 File r=null;
822 try { r=new URLAdapter(new URL(getParent())); }
823 catch(MalformedURLException ex) { }
824 return r;
825 }
826
827 public String getPath()
828 {
829 return url_.toString();
830 }
831
832 //int hashCode()
833
834 public boolean isAbsolute()
835 {
836 return true;
837 }
838
839 public boolean isDirectory()
840 {
841 String n=url_.getFile();
842 return (n==null)||n.endsWith("/");
843 }
844
845 public boolean isFile()
846 {
847 return !isDirectory();
848 }
849
850 public boolean isHidden()
851 {
852 String n=getName();
853 return (n!=null)&&n.startsWith(".");
854 }
855
856 public long lastModified()
857 {
858 init();
859 return lastModified_;
860 }
861
862 public long length()
863 {
864 init();
865 return length_;
866 }
867
868 public String[] list()
869 {
870 init();
871 return list_;
872 }
873
874 //String[] list(FilenameFilter filter)
875
876 public File[] listFiles()
877 {
878 init();
879
880 int l=list_.length;
881 File[] r=new File[l];
882
883 try
884 {
885 for(int i=0;i<l;i++)
886 r[i]=new URLAdapter(new URL(url_,list_[i]));
887 }
888 catch(MalformedURLException ex) { r=new File[0]; }
889
890 return r;
891 }
892
893 //File[] listFiles(FileFilter filter)
894 //File[] listFiles(FilenameFilter filter)
895
896 public boolean mkdir()
897 {
898 return false;
899 }
900
901 public boolean mkdirs()
902 {
903 return false;
904 }
905
906 public boolean renameTo(File _dest)
907 {
908 return false;
909 }
910
911 public boolean setLastModified(long _time)
912 {
913 return false;
914 }
915
916 public boolean setReadOnly()
917 {
918 return true;
919 }
920
921 public String toString()
922 {
923 return url_.toString();
924 }
925
926 public URL toURL()
927 {
928 return url_;
929 }
930 }
931 */
932
933 /*
934 private final class FileCR
935 implements ListCellRenderer
936 {
937 private boolean cb_;
938 private JLabel dl_;
939
940 public FileCR(boolean _cb)
941 {
942 cb_=_cb;
943 dl_=new BuLabel();
944 }
945
946 public Component getListCellRendererComponent
947 (JList _list,
948 Object _value,
949 int _index,
950 boolean _selected,
951 boolean _focus)
952 {
953 JLabel r=null;
954
955 Object o=(cb_
956 ? UIManager.get("ComboBox.renderer")
957 : UIManager.get("List.cellRenderer"));
958
959 if(o instanceof ListCellRenderer)
960 {
961 o=((ListCellRenderer)o).
962 getListCellRendererComponent(_list,_value,_index,_selected,_focus);
963 if(o instanceof JLabel) r=(JLabel)o;
964 }
965
966 if(r==null)
967 {
968 r=dl_;
969
970 if(_selected)
971 {
972 r.setOpaque(true);
973 r.setBackground(_list.getSelectionBackground());
974 r.setForeground(_list.getSelectionForeground());
975 if(cb_)
976 r.setBorder(UIManager.getBorder("ComboBox.selectedCellBorder"));
977 else
978 r.setBorder(UIManager.getBorder("List.selectedCellBorder"));
979 }
980 else
981 {
982 r.setOpaque(false);
983 r.setBackground(_list.getBackground());
984 r.setForeground(_list.getForeground());
985 if(cb_)
986 r.setBorder(UIManager.getBorder("ComboBox.cellBorder"));
987 else
988 r.setBorder(UIManager.getBorder("List.cellBorder"));
989 }
990 }
991
992 r.setFont(getETF());
993
994 File f=(File)_value;
995
996 Icon icon=BuResource.BU.getIcon("detruire",16);
997 String text=f.getName();
998
999 if(f instanceof Root)
1000 {
1001 icon=((Root)f).getIcon();
1002 text=((Root)f).getText();
1003 }
1004 else
1005 if(f.isDirectory())
1006 {
1007 icon=i_directory;
1008 }
1009 else
1010 if(f.isFile())
1011 {
1012 icon=i_file;
1013 }
1014 else
1015 {
1016 r.setForeground(Color.red);
1017 }
1018
1019 r.setText(text);
1020 r.setIcon(icon);
1021 r.setDisabledIcon(icon);
1022
1023 return r;
1024 }
1025 }
1026 */
1027
1028 private final class FileCR
1029 extends BuAbstractCellRenderer
1030 {
1031 private int type=BuPreferences.BU.getIntegerProperty
1032 ("explorer.fileIcon",2);
1033
1034 public FileCR(boolean _cb)
1035 {
1036 super(_cb
1037 ? BuAbstractCellRenderer.COMBOBOX
1038 : BuAbstractCellRenderer.LIST);
1039 }
1040
1041 public Component getListCellRendererComponent
1042 (JList _list,
1043 Object _value,
1044 int _index,
1045 boolean _selected,
1046 boolean _focus)
1047 {
1048 BuLabel r=(BuLabel)super.getListCellRendererComponent
1049 (_list,_value,_index,_selected,_focus);
1050
1051 r.setFont(getETF());
1052
1053 FuFile f=(FuFile)_value;
1054
1055 String text;
1056 if(f instanceof Root)
1057 text=f.getViewText();
1058 else
1059 if(type_==BuAbstractCellRenderer.COMBOBOX)
1060 text=f.getViewText();
1061 else
1062 text=f.getName();
1063
1064 Icon icon=null;
1065
1066 if(type!=0)
1067 {
1068 if(f instanceof Root)
1069 {
1070 icon=((Root)f).getViewIcon();
1071 }
1072 else
1073 if(f.isDirectory())
1074 {
1075 if("..".equals(text)) icon=i_parent;
1076 else icon=i_directory;
1077 }
1078 else
1079 if(f.isFile())
1080 {
1081 icon=i_file;
1082
1083 if((type==2)&&(viewer_!=null))
1084 {
1085 Icon fi=viewer_.getFileRenderer().getIcon(f);
1086
1087 if(fi instanceof BuIcon)
1088 {
1089 int oiw=16;
1090 if(icon!=null)
1091 oiw=Math.min(icon.getIconWidth(),
1092 icon.getIconHeight());
1093 int fiw=fi.getIconWidth();
1094 if((fiw>oiw)&&(fiw>16))
1095 fi=BuResource.BU.resizeIcon((BuIcon)fi,oiw);
1096 }
1097
1098 if(fi!=null) icon=fi;
1099 }
1100 }
1101 else
1102 {
1103 icon=BuResource.BU.getIcon("detruire",16);
1104 r.setForeground(Color.red);
1105 }
1106 }
1107
1108 r.setText(text);
1109 r.setIcon(icon);
1110 r.setDisabledIcon(icon);
1111 return r;
1112 }
1113 }
1114
1115 /*
1116 private final class FilterCR
1117 implements ListCellRenderer
1118 {
1119 private JLabel dl_;
1120
1121 public FilterCR()
1122 {
1123 dl_=new BuLabel();
1124 }
1125
1126 public Component getListCellRendererComponent
1127 (JList _list,
1128 Object _value,
1129 int _index,
1130 boolean _selected,
1131 boolean _focus)
1132 {
1133 JLabel r=null;
1134
1135 Object o=UIManager.get("ComboBox.renderer");
1136
1137 if(o instanceof ListCellRenderer)
1138 {
1139 o=((ListCellRenderer)o).
1140 getListCellRendererComponent(_list,_value,_index,_selected,_focus);
1141 if(o instanceof JLabel) r=(JLabel)o;
1142 }
1143
1144 if(r==null)
1145 {
1146 r=dl_;
1147
1148 if(_selected)
1149 {
1150 r.setOpaque(true);
1151 r.setBackground(_list.getSelectionBackground());
1152 r.setForeground(_list.getSelectionForeground());
1153 r.setBorder(UIManager.getBorder("ComboBox.selectedCellBorder"));
1154 }
1155 else
1156 {
1157 r.setOpaque(false);
1158 r.setBackground(_list.getBackground());
1159 r.setForeground(_list.getForeground());
1160 r.setBorder(UIManager.getBorder("ComboBox.cellBorder"));
1161 }
1162 }
1163
1164 BuFileFilter f=(BuFileFilter)_value;
1165 r.setText(f.getDescription());
1166 r.setFont(getETF());
1167 return r;
1168 }
1169 }
1170 */
1171
1172 private final class FilterCR
1173 extends BuAbstractCellRenderer
1174 {
1175 public FilterCR()
1176 {
1177 super(BuAbstractCellRenderer.COMBOBOX);
1178 }
1179
1180 public Component getListCellRendererComponent
1181 (JList _list,
1182 Object _value,
1183 int _index,
1184 boolean _selected,
1185 boolean _focus)
1186 {
1187 BuLabel r=(BuLabel)super.getListCellRendererComponent
1188 (_list,_value,_index,_selected,_focus);
1189
1190 if(_value instanceof BuFileFilter)
1191 _value=((BuFileFilter)_value).getDescription();
1192 r.setText(" "+_value);
1193 r.setFont(getETF());
1194 return r;
1195 }
1196 }
1197
1198 protected static String clean(String _dir)
1199 {
1200 String r=_dir;
1201 if(r!=null)
1202 {
1203 r=r.trim();
1204 if("".equals(r))
1205 {
1206 r=null;
1207 }
1208 else
1209 {
1210 r=FuLib.expandedPath(r);
1211 if((r.length()>1)&&r.endsWith(FuFile.separator))
1212 r=r.substring(0,r.length()-1);
1213 }
1214 }
1215 return r;
1216 }
1217
1218 protected void addMtab()
1219 {
1220 String od=clean(BuPreferences.BU.getStringProperty("directory.open",null));
1221 if(od!=null)
1222 roots_.addItem(new Root(od,od,"directory"));
1223
1224 String sd=clean(BuPreferences.BU.getStringProperty("directory.save",null));
1225 if((sd!=null)&&!sd.equals(od))
1226 roots_.addItem(new Root(sd,sd,"directory"));
1227
1228 String ud=clean(FuLib.getSystemProperty("user.dir"));
1229 if((ud!=null)&&!ud.equals(sd)&&!ud.equals(od))
1230 roots_.addItem(new Root(ud,ud,"directory"));
1231
1232 String hd=clean(FuLib.getSystemProperty("user.home"));
1233 if((hd!=null)&&!hd.equals(ud)&&!hd.equals(sd)&&!hd.equals(od))
1234 roots_.addItem(new Root(hd,BuResource.BU.getString("Maison"),"home"));
1235
1236 if(FuLib.isUnix())
1237 {
1238 try
1239 {
1240 LineNumberReader rin=new LineNumberReader
1241 (new InputStreamReader(new FileInputStream("/etc/mtab")));
1242 // FileReader (TMP)
1243
1244 String l;
1245 while((l=rin.readLine())!=null)
1246 {
1247 l=l.trim();
1248 if(l.startsWith("#")) continue;
1249
1250 try
1251 {
1252 StringTokenizer st=new StringTokenizer(l);
1253 String device=st.nextToken();
1254 String mount =st.nextToken();
1255 String type =st.nextToken();
1256 if( !"none" .equals(device)
1257 &&!"swap" .equals(type)
1258 &&!"devpts" .equals(type)
1259 &&!"devfs" .equals(type)
1260 &&!"tmpfs" .equals(type)
1261 &&!"usbdevfs".equals(type)
1262 &&!"/boot" .equals(mount))
1263 {
1264 if(!device.startsWith("/" )) type="computer";
1265 if(mount.endsWith("floppy")) type="floppy";
1266 String display=mount.substring(mount.lastIndexOf(File.separator)+1);
1267 if("".equals(display)) display="/";
1268 else display=display.substring(0,1)
1269 .toUpperCase()+display.substring(1);
1270 roots_.addItem(new Root(mount,display,type));
1271 }
1272 }
1273 catch(Exception ex) { }
1274 }
1275 }
1276 catch(Throwable th) { } //IOException ex
1277 }
1278
1279 try
1280 {
1281 Method m=File.class.getMethod("listRoots",new Class[0]);
1282 File[] l=(File[])m.invoke(null,new Object[0]);
1283 for(int i=0;i<l.length;i++)
1284 {
1285 String p=l[i].getPath(); //AbsolutePath();
1286 if(!p.equals("/")&&!p.equals("A:\\")&&!p.equals("B:\\"))
1287 roots_.addItem
1288 (new Root(p,p,"disk"));
1289 }
1290 }
1291 catch(NoSuchMethodException ex1) { }
1292 catch(Exception ex2) { ex2.printStackTrace(); }
1293
1294 for(int i=1;i<=9;i++)
1295 {
1296 String path=BuPreferences.BU.getStringProperty
1297 ("explorer.favorite."+i+".path");
1298 if(!"".equals(path))
1299 {
1300 URL u=null;
1301 try { u=new URL(path); }
1302 catch(MalformedURLException ex) { }
1303 if(u!=null)
1304 {
1305 roots_.addItem(FuFile.createFile(u));
1306 }
1307 else
1308 {
1309 String type=BuPreferences.BU.getStringProperty
1310 ("explorer.favorite."+i+".type","directory");
1311 Root f=new Root(path,path,type);
1312 if(f.exists()) roots_.addItem(f);
1313 }
1314 }
1315 }
1316 }
1317
1318 public void addDefaultFilters()
1319 {
1320 BuFileFilter all=new BuFileFilterAll();
1321 all.setExtensionListInDescription(false);
1322 addFilter(all);
1323
1324 if(app_==null)
1325 {
1326 BuFileFilter archives=new BuFileFilter
1327 (new String[] { "ace","bz","bz2","gz","lha","lhz","rar",
1328 "shar","tar","z","zip","zoo"
1329 },BuResource.BU.getString("Archives"));
1330 BuFileFilter images=new BuFileFilter
1331 (new String[] { "bmp","cgm","ief","g3","gif","jpeg","jpg",
1332 "pcd","pcx","png","pnm","pbm","pgm","ppm",
1333 "ras","tga","tif","tiff","xpm","xwd",
1334 "bdz"
1335 },BuResource.BU.getString("Images"));
1336 BuFileFilter texts =new BuFileFilter
1337 (new String[] { "abw","asc","bib","doc","eps","htm","html",
1338 "ltx","pdf","ps","rdf","rtx","sdw","stw",
1339 "sxw","tex","txt"
1340 },BuResource.BU.getString("Textes"));
1341 BuFileFilter sounds=new BuFileFilter
1342 (new String[] { "ac3","au","snd","aiff","voc","wav","mp3",
1343 "mid","mod","ogg","s3m","stm","ult","xi",
1344 "m3u"
1345 },BuResource.BU.getString("Musique et sons"));
1346 BuFileFilter movies=new BuFileFilter
1347 (new String[] { "mp2","mpe","mpeg","mpg","vob","qt","mov",
1348 "moov","movie","flc","fli","mng","asf",
1349 "asx","avi","wmv"
1350 },BuResource.BU.getString("Films"));
1351
1352 archives.setExtensionListInDescription(false);
1353 images .setExtensionListInDescription(false);
1354 texts .setExtensionListInDescription(false);
1355 sounds .setExtensionListInDescription(false);
1356 movies .setExtensionListInDescription(false);
1357
1358 addFilter(archives);
1359 addFilter(images);
1360 addFilter(movies);
1361 addFilter(sounds);
1362 addFilter(texts);
1363 }
1364
1365 filters_.setSelectedItem(all);
1366 }
1367
1368 private Hashtable filters_list=new Hashtable(11);
1369
1370 public void addFilter(BuFileFilter _ff)
1371 {
1372 addFilter(_ff,false);
1373 }
1374
1375 public void addFilter(BuFileFilter _ff, boolean _temporary)
1376 {
1377 //_ff.setExtensionListInDescription(false);
1378 if(filters_list.get(_ff)==null)
1379 {
1380 filters_list.put(_ff, _temporary ? Boolean.TRUE : Boolean.FALSE);
1381 filters_.hidePopup();
1382 filters_.removeAllItems();
1383
1384 int l=filters_list.size();
1385 Object[] o=new Object[l];
1386 Enumeration e=filters_list.keys();
1387 int i=0;
1388 while(e.hasMoreElements()) { o[i]=e.nextElement(); i++; }
1389 FuSort.sort(o);
1390 for(i=0;i<l;i++) filters_.addItem(o[i]);
1391 }
1392 }
1393
1394 public void cleanFilters()
1395 {
1396 Enumeration e=filters_list.keys();
1397 Vector v=new Vector();
1398 while(e.hasMoreElements())
1399 {
1400 Object f=e.nextElement();
1401 if(Boolean.TRUE.equals(filters_list.get(f)))
1402 v.addElement(f);
1403 }
1404 for(int i=0;i<v.size();i++)
1405 {
1406 Object o=v.elementAt(i);
1407 filters_list.remove(o);
1408 }
1409 }
1410
1411 private class Model
1412 implements Serializable, ListModel
1413 {
1414 private FuFile[] els_;
1415 private int nb_;
1416 private Vector ldl_;
1417
1418 public Model(FuFile[] _els, int _nb)
1419 {
1420 els_=_els;
1421 nb_ =_nb;
1422 ldl_=new Vector();
1423 }
1424
1425 public int getSize() { return nb_; }
1426 public Object getElementAt(int _i) { return els_[_i]; }
1427
1428 public void addListDataListener(ListDataListener _l)
1429 { ldl_.addElement(_l); }
1430
1431 public void removeListDataListener(ListDataListener _l)
1432 { ldl_.removeElement(_l); }
1433 }
1434
1435 public FuFile getCurrentRoot()
1436 {
1437 return (FuFile)roots_.getSelectedItem();
1438 }
1439
1440 public FuFile getCurrentDirectory()
1441 {
1442 /*
1443 String p=BuLib.expandedPath(current_.getText());
1444 File r=null;
1445 try
1446 {
1447 r=new URLAdapter(new URL(p));
1448 }
1449 catch(Exception ex) { r=new File(p); }
1450 return r;
1451 */
1452 return last_;
1453 }
1454
1455 public void setCurrentDirectory(FuFile _dir)
1456 {
1457
1458 if((_dir==null)||!_dir.exists()) return;
1459
1460 if(!_dir.isAbsolute())
1461 {
1462 try { _dir=_dir.getCanonicalFuFile(); }
1463 catch(IOException ex) { }
1464 }
1465
1466 FuFile d=_dir;
1467 if(!d.isDirectory())
1468 /*
1469 {
1470 if(d instanceof URLAdapter) d=((URLAdapter)d).getParentFile();
1471 else d=FuLib.getParentFile(d);
1472 }
1473 */
1474 d=d.getParentFuFile();
1475
1476 if((d==null)||!d.exists()) return;
1477
1478 int i,n;
1479 synchronized(roots_)
1480 {
1481 n=roots_.getItemCount();
1482 for(i=0;i<n;i++)
1483 {
1484 FuFile r=(FuFile)roots_.getItemAt(i);
1485 //System.err.println("ROOT: "+r+" "+d);//.equals(r));
1486 if(d.equals(r)) { roots_.setSelectedItem(r); break; }
1487 }
1488 }
1489
1490 if(i==n) updateLists(d);
1491 if(!_dir.isDirectory()) files_.setSelectedValue(_dir,true);
1492 }
1493
1494 public FuFile getSelectedDirectory()
1495 {
1496 return (FuFile)dirs_.getSelectedValue();
1497 }
1498
1499 public FuFile getSelectedFile()
1500 {
1501 return (FuFile)files_.getSelectedValue();
1502 }
1503
1504 // actions
1505
1506 public void refresh()
1507 {
1508 updateLists(getCurrentDirectory());
1509 }
1510
1511 public void openDirectory()
1512 {
1513 //updateLists(getSelectedDirectory());
1514 setCurrentDirectory(getSelectedDirectory());
1515 }
1516
1517 public final void openFile()
1518 {
1519 fireFileAction("OUVRIR");
1520 }
1521
1522 public final void extraFile(String _cmd)
1523 {
1524 fireFileAction(_cmd);
1525 }
1526
1527 protected void fireFileAction(String _action)
1528 {
1529 Object[] selected=files_.getSelectedValues();
1530 if(selected==null) return;
1531
1532 for(int i=0;i<selected.length;i++)
1533 if(((FuFile)selected[i]).canRead())
1534 {
1535 String path=((FuFile)selected[i]).getAbsolutePath();
1536 ActionEvent evt=new ActionEvent
1537 (this,ActionEvent.ACTION_PERFORMED,
1538 _action+"("+path+")");
1539 for(Enumeration e=listeners_.elements(); e.hasMoreElements(); )
1540 ((ActionListener)e.nextElement()).actionPerformed(evt);
1541 }
1542 }
1543
1544 public void addExtraFileCommand(String _s,String _cmd,BuIcon _icon)
1545 {
1546 //pmFiles_.addSeparator();
1547 pmFiles_.addMenuItem(_s,"EXTRA_FICHIER("+_cmd+")",_icon,true);
1548 }
1549
1550 public void selectAllFiles()
1551 {
1552 ListModel model=files_.getModel();
1553 int size =model.getSize();
1554 if(size>0) files_.setSelectionInterval(0,model.getSize()-1);
1555 }
1556
1557 public void createDirectory()
1558 {
1559 BuDialogInput d=new BuDialogInput
1560 (null,null,"Créer","Nom du sous-répertoire:","");
1561 if(d.activate()==JOptionPane.OK_OPTION)
1562 {
1563 String name =d.getValue();
1564 FuFile current=getCurrentDirectory();
1565
1566 if(current.createChild(name).mkdir())
1567 refresh();
1568 else
1569 {
1570 new BuDialogError
1571 (null,null,
1572 "Impossible de créer le sous-répertoire "+name+"\n"+
1573 "dans le répertoire "+current.getAbsolutePath())
1574 .activate();
1575 }
1576 }
1577 }
1578
1579 public void renameDirectory()
1580 {
1581 FuFile selected=getSelectedDirectory();
1582
1583 BuDialogInput d=new BuDialogInput
1584 (null,null,"Renommer","Nouve