0N/A/*
3261N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt.X11;
0N/A
0N/Aimport java.awt.*;
0N/Aimport javax.swing.*;
0N/Aimport java.awt.event.*;
0N/Aimport java.awt.peer.*;
0N/Aimport java.io.*;
0N/Aimport java.util.Locale;
0N/Aimport java.util.Arrays;
0N/Aimport com.sun.java.swing.plaf.motif.*;
0N/Aimport javax.swing.plaf.ComponentUI;
0N/Aimport java.security.AccessController;
0N/Aimport java.security.PrivilegedAction;
1696N/Aimport sun.util.logging.PlatformLogger;
2153N/Aimport sun.awt.AWTAccessor;
0N/A
0N/Aclass XFileDialogPeer extends XDialogPeer implements FileDialogPeer, ActionListener, ItemListener, KeyEventDispatcher, XChoicePeerListener {
1696N/A private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XFileDialogPeer");
0N/A
0N/A FileDialog target;
0N/A
0N/A // This variable holds value exactly the same as value of the 'target.file' variable except:
0N/A // 1) is changed to null after quit (see handleQuitButton())
0N/A // 2) keep the same value if 'target.file' is incorrect (see setFile())
0N/A // It's not clear HOW we used it
0N/A // We should think about existence of this variable
0N/A String file;
0N/A
0N/A String dir;
0N/A
0N/A String title;
0N/A int mode;
0N/A FilenameFilter filter;
0N/A
0N/A private static final int PATH_CHOICE_WIDTH = 20;
0N/A
0N/A // Seems that the purpose of this variable is cashing of 'target.file' variable in order to help method show()
0N/A // We should think about using 'target.file' instead of 'savedFile'
0N/A // Perhaps, 'target.file' just more correct (see target.setFile())
0N/A String savedFile;
0N/A
0N/A // Holds value of the directory which was chosen before
0N/A // We use it in order to restore previously selected directory
0N/A // at the time of the next showing of the file dialog
0N/A String savedDir;
0N/A // Holds value of the system property 'user.dir'
0N/A // in order to init current directory
0N/A String userDir;
0N/A
0N/A Dialog fileDialog;
0N/A
0N/A GridBagLayout gbl;
0N/A GridBagLayout gblButtons;
0N/A GridBagConstraints gbc;
0N/A
0N/A // ************** Components in the fileDialogWindow ***************
0N/A
0N/A TextField filterField;
0N/A
0N/A // This variable holds the current text of the file which user select through the navigation
0N/A // It's important that updating of this variable must be correct
0N/A // since this value is used at the time of the file dialog closing
0N/A // Namely, we invoke target.setFile() and then user can get this value
0N/A // We update this field in cases:
0N/A // - ITEM_STATE_CHANGED was triggered on the file list component: set to the current selected item
0N/A // - at the time of the 'show': set to savedFile
0N/A // - at the time of the programmatically setting: set to new value
0N/A TextField selectionField;
0N/A
0N/A List directoryList;
0N/A
0N/A // This is the list component which is used for the showing of the file list of the current directory
0N/A List fileList;
0N/A
0N/A Panel buttons;
0N/A Button openButton;
0N/A Button filterButton;
0N/A Button cancelButton;
0N/A Choice pathChoice;
0N/A TextField pathField;
0N/A Panel pathPanel;
0N/A
0N/A String cancelButtonText = null;
0N/A String enterFileNameLabelText = null;
0N/A String filesLabelText= null;
0N/A String foldersLabelText= null;
0N/A String pathLabelText= null;
0N/A String filterLabelText= null;
0N/A String openButtonText= null;
0N/A String saveButtonText= null;
0N/A String actionButtonText= null;
0N/A
0N/A
0N/A void installStrings() {
0N/A Locale l = target.getLocale();
0N/A UIDefaults uid = XToolkit.getUIDefaults();
0N/A cancelButtonText = uid.getString("FileChooser.cancelButtonText",l);
0N/A enterFileNameLabelText = uid.getString("FileChooser.enterFileNameLabelText",l);
0N/A filesLabelText = uid.getString("FileChooser.filesLabelText",l);
0N/A foldersLabelText = uid.getString("FileChooser.foldersLabelText",l);
0N/A pathLabelText = uid.getString("FileChooser.pathLabelText",l);
0N/A filterLabelText = uid.getString("FileChooser.filterLabelText",l);
0N/A openButtonText = uid.getString("FileChooser.openButtonText",l);
0N/A saveButtonText = uid.getString("FileChooser.saveButtonText",l);
0N/A
0N/A }
0N/A
0N/A XFileDialogPeer(FileDialog target) {
0N/A super((Dialog)target);
0N/A this.target = target;
0N/A }
0N/A
0N/A private void init(FileDialog target) {
0N/A fileDialog = target; //new Dialog(target, target.getTitle(), false);
0N/A this.title = target.getTitle();
0N/A this.mode = target.getMode();
0N/A this.target = target;
0N/A this.filter = target.getFilenameFilter();
0N/A
0N/A savedFile = target.getFile();
0N/A savedDir = target.getDirectory();
0N/A // Shouldn't save 'user.dir' to 'savedDir'
0N/A // since getDirectory() will be incorrect after handleCancel
0N/A userDir = (String)AccessController.doPrivileged(
0N/A new PrivilegedAction() {
0N/A public Object run() {
0N/A return System.getProperty("user.dir");
0N/A }
0N/A });
0N/A
0N/A installStrings();
0N/A gbl = new GridBagLayout();
0N/A gblButtons = new GridBagLayout();
0N/A gbc = new GridBagConstraints();
0N/A fileDialog.setLayout(gbl);
0N/A
0N/A // create components
0N/A buttons = new Panel();
0N/A buttons.setLayout(gblButtons);
0N/A actionButtonText = (target.getMode() == FileDialog.SAVE) ? saveButtonText : openButtonText;
0N/A openButton = new Button(actionButtonText);
0N/A
0N/A filterButton = new Button(filterLabelText);
0N/A cancelButton = new Button(cancelButtonText);
0N/A directoryList = new List();
0N/A fileList = new List();
0N/A filterField = new TextField();
0N/A selectionField = new TextField();
0N/A
2153N/A boolean isMultipleMode =
2153N/A AWTAccessor.getFileDialogAccessor().isMultipleMode(target);
2153N/A fileList.setMultipleMode(isMultipleMode);
2153N/A
0N/A // the insets used by the components in the fileDialog
0N/A Insets noInset = new Insets(0, 0, 0, 0);
0N/A Insets textFieldInset = new Insets(0, 8, 0, 8);
0N/A Insets leftListInset = new Insets(0, 8, 0, 4);
0N/A Insets rightListInset = new Insets(0, 4, 0, 8);
0N/A Insets separatorInset = new Insets(8, 0, 0, 0);
0N/A Insets labelInset = new Insets(0, 8, 0, 0);
0N/A Insets buttonsInset = new Insets(10, 8, 10, 8);
0N/A
0N/A // add components to GridBagLayout "gbl"
0N/A
0N/A Font f = new Font(Font.DIALOG, Font.PLAIN, 12);
0N/A
0N/A Label label = new Label(pathLabelText);
0N/A label.setFont(f);
0N/A addComponent(label, gbl, gbc, 0, 0, 1,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.NONE, labelInset);
0N/A
0N/A // Fixed 6260650: FileDialog.getDirectory() does not return null when file dialog is cancelled
0N/A // After showing we should display 'user.dir' as current directory
0N/A // if user didn't set directory programatically
0N/A pathField = new TextField(savedDir != null ? savedDir : userDir);
0N/A
0N/A pathChoice = new Choice() {
0N/A public Dimension getPreferredSize() {
0N/A return new Dimension(PATH_CHOICE_WIDTH, pathField.getPreferredSize().height);
0N/A }
0N/A };
0N/A pathPanel = new Panel();
0N/A pathPanel.setLayout(new BorderLayout());
0N/A
0N/A pathPanel.add(pathField,BorderLayout.CENTER);
0N/A pathPanel.add(pathChoice,BorderLayout.EAST);
0N/A //addComponent(pathField, gbl, gbc, 0, 1, 2,
0N/A // GridBagConstraints.WEST, (Container)fileDialog,
0N/A // 1, 0, GridBagConstraints.HORIZONTAL, textFieldInset);
0N/A //addComponent(pathChoice, gbl, gbc, 1, 1, GridBagConstraints.RELATIVE,
0N/A // GridBagConstraints.WEST, (Container)fileDialog,
0N/A // 1, 0, GridBagConstraints.HORIZONTAL, textFieldInset);
0N/A addComponent(pathPanel, gbl, gbc, 0, 1, 2,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.HORIZONTAL, textFieldInset);
0N/A
0N/A
0N/A
0N/A label = new Label(filterLabelText);
0N/A
0N/A label.setFont(f);
0N/A addComponent(label, gbl, gbc, 0, 2, 1,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.NONE, labelInset);
0N/A addComponent(filterField, gbl, gbc, 0, 3, 2,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.HORIZONTAL, textFieldInset);
0N/A
0N/A label = new Label(foldersLabelText);
0N/A
0N/A label.setFont(f);
0N/A addComponent(label, gbl, gbc, 0, 4, 1,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.NONE, labelInset);
0N/A
0N/A label = new Label(filesLabelText);
0N/A
0N/A label.setFont(f);
0N/A addComponent(label, gbl, gbc, 1, 4, 1,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.NONE, labelInset);
0N/A addComponent(directoryList, gbl, gbc, 0, 5, 1,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 1, GridBagConstraints.BOTH, leftListInset);
0N/A addComponent(fileList, gbl, gbc, 1, 5, 1,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 1, GridBagConstraints.BOTH, rightListInset);
0N/A
0N/A label = new Label(enterFileNameLabelText);
0N/A
0N/A label.setFont(f);
0N/A addComponent(label, gbl, gbc, 0, 6, 1,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.NONE, labelInset);
0N/A addComponent(selectionField, gbl, gbc, 0, 7, 2,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.HORIZONTAL, textFieldInset);
0N/A addComponent(new Separator(fileDialog.size().width, 2, Separator.HORIZONTAL), gbl, gbc, 0, 8, 15,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.HORIZONTAL, separatorInset);
0N/A
0N/A // add buttons to GridBagLayout Buttons
0N/A addComponent(openButton, gblButtons, gbc, 0, 0, 1,
0N/A GridBagConstraints.WEST, (Container)buttons,
0N/A 1, 0, GridBagConstraints.NONE, noInset);
0N/A addComponent(filterButton, gblButtons, gbc, 1, 0, 1,
0N/A GridBagConstraints.CENTER, (Container)buttons,
0N/A 1, 0, GridBagConstraints.NONE, noInset);
0N/A addComponent(cancelButton, gblButtons, gbc, 2, 0, 1,
0N/A GridBagConstraints.EAST, (Container)buttons,
0N/A 1, 0, GridBagConstraints.NONE, noInset);
0N/A
0N/A // add ButtonPanel to the GridBagLayout of this class
0N/A addComponent(buttons, gbl, gbc, 0, 9, 2,
0N/A GridBagConstraints.WEST, (Container)fileDialog,
0N/A 1, 0, GridBagConstraints.HORIZONTAL, buttonsInset);
0N/A
0N/A fileDialog.setSize(400, 400);
0N/A
0N/A // Update choice's popup width
0N/A XChoicePeer choicePeer = (XChoicePeer)pathChoice.getPeer();
0N/A choicePeer.setDrawSelectedItem(false);
0N/A choicePeer.setAlignUnder(pathField);
0N/A
0N/A filterField.addActionListener(this);
0N/A selectionField.addActionListener(this);
0N/A directoryList.addActionListener(this);
0N/A directoryList.addItemListener(this);
0N/A fileList.addItemListener(this);
0N/A fileList.addActionListener(this);
0N/A openButton.addActionListener(this);
0N/A filterButton.addActionListener(this);
0N/A cancelButton.addActionListener(this);
0N/A pathChoice.addItemListener(this);
0N/A pathField.addActionListener(this);
0N/A
0N/A // b6227750 FileDialog is not disposed when clicking the 'close' (X) button on the top right corner, XToolkit
0N/A target.addWindowListener(
0N/A new WindowAdapter(){
0N/A public void windowClosing(WindowEvent e){
0N/A handleCancel();
0N/A }
0N/A }
0N/A );
0N/A
0N/A // 6259434 PIT: Choice in FileDialog is not responding to keyboard interactions, XToolkit
0N/A pathChoice.addItemListener(this);
0N/A
0N/A }
0N/A
0N/A public void updateMinimumSize() {
0N/A }
0N/A
0N/A public void updateIconImages() {
0N/A if (winAttr.icons == null){
0N/A winAttr.iconsInherited = false;
0N/A winAttr.icons = getDefaultIconInfo();
0N/A setIconHints(winAttr.icons);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * add Component comp to the container cont.
0N/A * add the component to the correct GridBagLayout
0N/A */
0N/A void addComponent(Component comp, GridBagLayout gb, GridBagConstraints c, int gridx,
0N/A int gridy, int gridwidth, int anchor, Container cont, int weightx, int weighty,
0N/A int fill, Insets in) {
0N/A c.gridx = gridx;
0N/A c.gridy = gridy;
0N/A c.gridwidth = gridwidth;
0N/A c.anchor = anchor;
0N/A c.weightx = weightx;
0N/A c.weighty = weighty;
0N/A c.fill = fill;
0N/A c.insets = in;
0N/A gb.setConstraints(comp, c);
0N/A cont.add(comp);
0N/A }
0N/A
0N/A /**
0N/A * get fileName
0N/A */
0N/A String getFileName(String str) {
0N/A if (str == null) {
0N/A return "";
0N/A }
0N/A
0N/A int index = str.lastIndexOf('/');
0N/A
0N/A if (index == -1) {
0N/A return str;
0N/A } else {
0N/A return str.substring(index + 1);
0N/A }
0N/A }
0N/A
0N/A /** handleFilter
0N/A *
0N/A */
0N/A void handleFilter(String f) {
0N/A
0N/A if (f == null) {
0N/A return;
0N/A }
0N/A setFilterEntry(dir,f);
0N/A
0N/A // Fixed within 6259434: PIT: Choice in FileDialog is not responding to keyboard interactions, XToolkit
0N/A // Here we restoring Motif behaviour
0N/A directoryList.select(0);
0N/A if (fileList.getItemCount() != 0) {
0N/A fileList.requestFocus();
0N/A } else {
0N/A directoryList.requestFocus();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * handle the selection event
0N/A */
0N/A void handleSelection(String file) {
2153N/A
2153N/A int index = file.lastIndexOf(java.io.File.separatorChar);
0N/A
0N/A if (index == -1) {
0N/A savedDir = this.dir;
0N/A savedFile = file;
0N/A } else {
0N/A savedDir = file.substring(0, index+1);
0N/A savedFile = file.substring(index+1);
0N/A }
2153N/A
4787N/A String[] fileNames = fileList.getSelectedItems();
4787N/A int filesNumber = (fileNames != null) ? fileNames.length : 0;
4787N/A File[] files = new File[filesNumber];
4787N/A for (int i = 0; i < filesNumber; i++) {
4787N/A files[i] = new File(savedDir, fileNames[i]);
4787N/A }
4787N/A
2153N/A AWTAccessor.FileDialogAccessor fileDialogAccessor = AWTAccessor.getFileDialogAccessor();
2153N/A
2153N/A fileDialogAccessor.setDirectory(target, savedDir);
2153N/A fileDialogAccessor.setFile(target, savedFile);
4787N/A fileDialogAccessor.setFiles(target, files);
0N/A }
0N/A
0N/A /**
0N/A * handle the cancel event
0N/A */
0N/A void handleCancel() {
0N/A KeyboardFocusManager.getCurrentKeyboardFocusManager()
0N/A .removeKeyEventDispatcher(this);
0N/A
0N/A setSelectionField(null);
0N/A setFilterField(null);
0N/A directoryList.clear();
0N/A fileList.clear();
2153N/A
2153N/A AWTAccessor.FileDialogAccessor fileDialogAccessor = AWTAccessor.getFileDialogAccessor();
2153N/A
2153N/A fileDialogAccessor.setDirectory(target, null);
2153N/A fileDialogAccessor.setFile(target, null);
4787N/A fileDialogAccessor.setFiles(target, null);
2153N/A
0N/A handleQuitButton();
0N/A }
0N/A
0N/A /**
0N/A * handle the quit event
0N/A */
0N/A void handleQuitButton() {
0N/A dir = null;
0N/A file = null;
0N/A target.hide();
0N/A }
0N/A
0N/A /**
0N/A * set the entry of the new dir with f
0N/A */
0N/A void setFilterEntry(String d, String f) {
0N/A File fe = new File(d);
0N/A
0N/A if (fe.isDirectory() && fe.canRead()) {
0N/A // Fixed 6260659: File Name set programmatically in FileDialog is overridden during navigation, XToolkit
0N/A // Here we restoring Motif behaviour
0N/A setSelectionField(target.getFile());
0N/A
0N/A if (f.equals("")) {
0N/A f = "*";
0N/A setFilterField(f);
0N/A } else {
0N/A setFilterField(f);
0N/A }
0N/A String l[];
0N/A
0N/A if (f.equals("*")) {
0N/A l = fe.list();
0N/A } else {
0N/A // REMIND: fileDialogFilter is not implemented yet
0N/A FileDialogFilter ff = new FileDialogFilter(f);
0N/A l = fe.list(ff);
0N/A }
0N/A // Fixed 6358953: handling was added in case of I/O error happens
0N/A if (l == null) {
0N/A this.dir = getParentDirectory();
0N/A return;
0N/A }
0N/A directoryList.clear();
0N/A fileList.clear();
0N/A directoryList.setVisible(false);
0N/A fileList.setVisible(false);
0N/A
0N/A directoryList.addItem("..");
0N/A Arrays.sort(l);
0N/A for (int i = 0 ; i < l.length ; i++) {
0N/A File file = new File(d + l[i]);
0N/A if (file.isDirectory()) {
0N/A directoryList.addItem(l[i] + "/");
0N/A } else {
0N/A if (filter != null) {
0N/A if (filter.accept(new File(l[i]),l[i])) fileList.addItem(l[i]);
0N/A }
0N/A else fileList.addItem(l[i]);
0N/A }
0N/A }
0N/A this.dir = d;
0N/A
0N/A pathField.setText(dir);
0N/A
0N/A // Some code was removed
0N/A // Now we do updating of the pathChoice at the time of the choice opening
0N/A
0N/A target.setDirectory(this.dir);
0N/A directoryList.setVisible(true);
0N/A fileList.setVisible(true);
0N/A }
0N/A }
0N/A
0N/A
0N/A String[] getDirList(String dir) {
0N/A if (!dir.endsWith("/"))
0N/A dir = dir + "/";
0N/A char[] charr = dir.toCharArray();
0N/A int numSlashes = 0;
0N/A for (int i=0;i<charr.length;i++) {
0N/A if (charr[i] == '/')
0N/A numSlashes++;
0N/A }
0N/A String[] starr = new String[numSlashes];
0N/A int j=0;
0N/A for (int i=charr.length-1;i>=0;i--) {
0N/A if (charr[i] == '/')
0N/A {
0N/A starr[j++] = new String(charr,0,i+1);
0N/A }
0N/A }
0N/A return starr;
0N/A }
0N/A
0N/A /**
0N/A * set the text in the selectionField
0N/A */
0N/A void setSelectionField(String str) {
0N/A selectionField.setText(str);
0N/A }
0N/A
0N/A /**
0N/A * set the text in the filterField
0N/A */
0N/A void setFilterField(String str) {
0N/A filterField.setText(str);
0N/A }
0N/A
0N/A /**
0N/A *
0N/A * @see java.awt.event.ItemEvent
0N/A * ItemEvent.ITEM_STATE_CHANGED
0N/A */
0N/A public void itemStateChanged(ItemEvent itemEvent){
0N/A if (itemEvent.getID() != ItemEvent.ITEM_STATE_CHANGED ||
0N/A itemEvent.getStateChange() == ItemEvent.DESELECTED) {
0N/A return;
0N/A }
0N/A
0N/A Object source = itemEvent.getSource();
0N/A
0N/A if (source == pathChoice) {
0N/A /*
0N/A * Update the selection ('folder name' text field) after
0N/A * the current item changing in the unfurled choice by the arrow keys.
0N/A * See 6259434, 6240074 for more information
0N/A */
0N/A String dir = pathChoice.getSelectedItem();
0N/A pathField.setText(dir);
0N/A } else if (directoryList == source) {
0N/A setFilterField(getFileName(filterField.getText()));
0N/A } else if (fileList == source) {
0N/A String file = fileList.getItem((Integer)itemEvent.getItem());
0N/A setSelectionField(file);
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Updates the current directory only if directoryList-specific
0N/A * action occurred. Returns false if the forward directory is inaccessible
0N/A */
0N/A boolean updateDirectoryByUserAction(String str) {
0N/A
0N/A String dir;
0N/A if (str.equals("..")) {
0N/A dir = getParentDirectory();
0N/A }
0N/A else {
0N/A dir = this.dir + str;
0N/A }
0N/A
0N/A File fe = new File(dir);
0N/A if (fe.canRead()) {
0N/A this.dir = dir;
0N/A return true;
0N/A }else {
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A String getParentDirectory(){
0N/A String parent = this.dir;
0N/A if (!this.dir.equals("/")) // If the current directory is "/" leave it alone.
0N/A {
0N/A if (dir.endsWith("/"))
0N/A parent = parent.substring(0,parent.lastIndexOf("/"));
0N/A
0N/A parent = parent.substring(0,parent.lastIndexOf("/")+1);
0N/A }
0N/A return parent;
0N/A }
0N/A
0N/A public void actionPerformed( ActionEvent actionEvent ) {
0N/A String actionCommand = actionEvent.getActionCommand();
0N/A Object source = actionEvent.getSource();
0N/A
0N/A if (actionCommand.equals(actionButtonText)) {
0N/A handleSelection( selectionField.getText() );
0N/A handleQuitButton();
0N/A } else if (actionCommand.equals(filterLabelText)) {
0N/A handleFilter( filterField.getText() );
0N/A } else if (actionCommand.equals(cancelButtonText)) {
0N/A handleCancel();
0N/A } else if ( source instanceof TextField ) {
0N/A if ( selectionField == ((TextField)source) ) {
0N/A // Fixed within 6259434: PIT: Choice in FileDialog is not responding to keyboard interactions, XToolkit
0N/A // We should handle the action based on the selection field
0N/A // Looks like mistake
0N/A handleSelection(selectionField.getText());
0N/A handleQuitButton();
0N/A } else if (filterField == ((TextField)source)) {
0N/A handleFilter(filterField.getText());
0N/A } else if (pathField == ((TextField)source)) {
0N/A target.setDirectory(pathField.getText());
0N/A }
0N/A } else if (source instanceof List) {
0N/A if (directoryList == ((List)source)) {
0N/A //handleFilter( actionCommand + getFileName( filterField.getText() ) );
0N/A if (updateDirectoryByUserAction(actionCommand)){
0N/A handleFilter( getFileName( filterField.getText() ) );
0N/A }
0N/A } else if (fileList == ((List)source)) {
0N/A handleSelection( actionCommand );
0N/A handleQuitButton();
0N/A }
0N/A }
0N/A }
0N/A
0N/A public boolean dispatchKeyEvent(KeyEvent keyEvent) {
0N/A int id = keyEvent.getID();
0N/A int keyCode = keyEvent.getKeyCode();
0N/A
0N/A if (id == KeyEvent.KEY_PRESSED && keyCode == KeyEvent.VK_ESCAPE) {
0N/A synchronized (target.getTreeLock()) {
0N/A Component comp = (Component) keyEvent.getSource();
0N/A while (comp != null) {
0N/A // Fix for 6240084 Disposing a file dialog when the drop-down is active does not dispose the dropdown menu, on Xtoolkit
0N/A // See also 6259493
0N/A if (comp == pathChoice) {
0N/A XChoicePeer choicePeer = (XChoicePeer)pathChoice.getPeer();
0N/A if (choicePeer.isUnfurled()){
0N/A return false;
0N/A }
0N/A }
0N/A if (comp.getPeer() == this) {
0N/A handleCancel();
0N/A return true;
0N/A }
0N/A comp = comp.getParent();
0N/A }
0N/A }
0N/A }
0N/A
0N/A return false;
0N/A }
0N/A
0N/A
0N/A /**
0N/A * set the file
0N/A */
0N/A public void setFile(String file) {
0N/A
0N/A if (file == null) {
0N/A this.file = null;
0N/A return;
0N/A }
0N/A
0N/A if (this.dir == null) {
0N/A String d = "./";
0N/A File f = new File(d, file);
0N/A
0N/A if (f.isFile()) {
0N/A this.file = file;
0N/A setDirectory(d);
0N/A }
0N/A } else {
0N/A File f = new File(this.dir, file);
0N/A if (f.isFile()) {
0N/A this.file = file;
0N/A }
0N/A }
0N/A
0N/A setSelectionField(file);
0N/A }
0N/A
0N/A /**
0N/A * set the directory
0N/A * FIXME: we should update 'savedDir' after programmatically 'setDirectory'
0N/A * Otherwise, SavedDir will be not null before second showing
0N/A * So the current directory of the file dialog will be incorrect after second showing
0N/A * since 'setDirectory' will be ignored
0N/A * We cann't update savedDir here now since it used very often
0N/A */
0N/A public void setDirectory(String dir) {
0N/A
0N/A if (dir == null) {
0N/A this.dir = null;
0N/A return;
0N/A }
0N/A
0N/A if (dir.equals(this.dir)) {
0N/A return;
0N/A }
0N/A
0N/A int i;
0N/A if ((i=dir.indexOf("~")) != -1) {
0N/A
0N/A dir = dir.substring(0,i) + System.getProperty("user.home") + dir.substring(i+1,dir.length());
0N/A }
0N/A
0N/A File fe = new File(dir).getAbsoluteFile();
0N/A log.fine("Current directory : " + fe);
0N/A
0N/A if (!fe.isDirectory()) {
0N/A dir = "./";
0N/A fe = new File(dir).getAbsoluteFile();
0N/A
0N/A if (!fe.isDirectory()) {
0N/A return;
0N/A }
0N/A }
0N/A try {
0N/A dir = this.dir = fe.getCanonicalPath();
0N/A } catch (java.io.IOException ie) {
0N/A dir = this.dir = fe.getAbsolutePath();
0N/A }
0N/A pathField.setText(this.dir);
0N/A
0N/A
0N/A if (dir.endsWith("/")) {
0N/A this.dir = dir;
0N/A handleFilter("");
0N/A } else {
0N/A this.dir = dir + "/";
0N/A handleFilter("");
0N/A }
0N/A
0N/A // Some code was removed
0N/A // Now we do updating of the pathChoice at the time of the choice opening
0N/A // Fixed problem:
0N/A // The exception java.awt.IllegalComponentStateException will be thrown
0N/A // if the user invoke setDirectory after the closing of the file dialog
0N/A }
0N/A
0N/A /**
0N/A * set filenameFilter
0N/A *
0N/A */
0N/A public void setFilenameFilter(FilenameFilter filter) {
0N/A this.filter = filter;
0N/A }
0N/A
1052N/A
1052N/A public void dispose() {
1052N/A FileDialog fd = (FileDialog)fileDialog;
1052N/A if (fd != null) {
1052N/A fd.removeAll();
1052N/A }
1052N/A super.dispose();
1052N/A }
1052N/A
1052N/A // 03/02/2005 b5097243 Pressing 'ESC' on a file dlg does not dispose the dlg on Xtoolkit
1052N/A public void setVisible(boolean b){
0N/A if (fileDialog == null) {
0N/A init((FileDialog)target);
0N/A }
0N/A
0N/A if (savedDir != null || userDir != null) {
0N/A setDirectory(savedDir != null ? savedDir : userDir);
0N/A }
0N/A
0N/A if (savedFile != null) {
0N/A // Actually in Motif implementation lost file value which was saved after prevously showing
0N/A // Seems we shouldn't restore Motif behaviour in this case
0N/A setFile(savedFile);
0N/A }
0N/A
0N/A super.setVisible(b);
0N/A if (b == true){
0N/A // See 6240074 for more information
0N/A XChoicePeer choicePeer = (XChoicePeer)pathChoice.getPeer();
0N/A choicePeer.addXChoicePeerListener(this);
0N/A KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
0N/A }else{
0N/A // See 6240074 for more information
0N/A XChoicePeer choicePeer = (XChoicePeer)pathChoice.getPeer();
0N/A choicePeer.removeXChoicePeerListener();
0N/A KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this);
0N/A }
1052N/A
1052N/A selectionField.requestFocusInWindow();
0N/A }
0N/A
0N/A /*
0N/A * Adding items to the path choice based on the text string
0N/A * See 6240074 for more information
0N/A */
0N/A public void addItemsToPathChoice(String text){
0N/A String dirList[] = getDirList(text);
0N/A for (int i = 0; i < dirList.length; i++) pathChoice.addItem(dirList[i]);
0N/A }
0N/A
0N/A /*
0N/A * Refresh the unfurled choice at the time of the opening choice according to the text of the path field
0N/A * See 6240074 for more information
0N/A */
0N/A public void unfurledChoiceOpening(ListHelper choiceHelper){
0N/A
0N/A // When the unfurled choice is opening the first time, we need only to add elements, otherwise we've got exception
0N/A if (choiceHelper.getItemCount() == 0){
0N/A addItemsToPathChoice(pathField.getText());
0N/A return;
0N/A }
0N/A
0N/A // If the set of the directories the exactly same as the used to be then dummy
0N/A if (pathChoice.getItem(0).equals(pathField.getText()))
0N/A return;
0N/A
0N/A pathChoice.removeAll();
0N/A addItemsToPathChoice(pathField.getText());
0N/A }
0N/A
0N/A /*
0N/A * Refresh the file dialog at the time of the closing choice according to the selected item of the choice
0N/A * See 6240074 for more information
0N/A */
0N/A public void unfurledChoiceClosing(){
0N/A // This is the exactly same code as invoking later at the time of the itemStateChanged
0N/A // Here is we restore Windows behaviour: change current directory if user press 'ESC'
0N/A String dir = pathChoice.getSelectedItem();
0N/A target.setDirectory(dir);
0N/A }
0N/A}
0N/A
0N/Aclass Separator extends Canvas {
0N/A public final static int HORIZONTAL = 0;
0N/A public final static int VERTICAL = 1;
0N/A int orientation;
0N/A
0N/A public Separator(int length, int thickness, int orient) {
0N/A super();
0N/A orientation = orient;
0N/A if (orient == HORIZONTAL) {
0N/A resize(length, thickness);
0N/A } else {
0N/A // VERTICAL
0N/A resize(thickness, length);
0N/A }
0N/A }
0N/A
0N/A public void paint(Graphics g) {
0N/A int x1, y1, x2, y2;
0N/A Rectangle bbox = bounds();
0N/A Color c = getBackground();
0N/A Color brighter = c.brighter();
0N/A Color darker = c.darker();
0N/A
0N/A if (orientation == HORIZONTAL) {
0N/A x1 = 0;
0N/A x2 = bbox.width - 1;
0N/A y1 = y2 = bbox.height/2 - 1;
0N/A
0N/A } else {
0N/A // VERTICAL
0N/A x1 = x2 = bbox.width/2 - 1;
0N/A y1 = 0;
0N/A y2 = bbox.height - 1;
0N/A }
0N/A g.setColor(darker);
0N/A g.drawLine(x1, y2, x2, y2);
0N/A g.setColor(brighter);
0N/A if (orientation == HORIZONTAL)
0N/A g.drawLine(x1, y2+1, x2, y2+1);
0N/A else
0N/A g.drawLine(x1+1, y2, x2+1, y2);
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * Motif file dialogs let the user specify a filter that controls the files that
0N/A * are displayed in the dialog. This filter is generally specified as a regular
0N/A * expression. The class is used to implement Motif-like filtering.
0N/A */
0N/Aclass FileDialogFilter implements FilenameFilter {
0N/A
0N/A String filter;
0N/A
0N/A public FileDialogFilter(String f) {
0N/A filter = f;
0N/A }
0N/A
0N/A /*
0N/A * Tells whether or not the specified file should be included in a file list
0N/A */
0N/A public boolean accept(File dir, String fileName) {
0N/A
0N/A File f = new File(dir, fileName);
0N/A
0N/A if (f.isDirectory()) {
0N/A return true;
0N/A } else {
0N/A return matches(fileName, filter);
0N/A }
0N/A }
0N/A
0N/A /*
0N/A * Tells whether or not the input string matches the given filter
0N/A */
0N/A private boolean matches(String input, String filter) {
0N/A String regex = convert(filter);
0N/A return input.matches(regex);
0N/A }
0N/A
0N/A /*
0N/A * Converts the filter into the form which is acceptable by Java's regexps
0N/A */
0N/A private String convert(String filter) {
215N/A String regex = "^" + filter + "$";
0N/A regex = regex.replaceAll("\\.", "\\\\.");
0N/A regex = regex.replaceAll("\\?", ".");
0N/A regex = regex.replaceAll("\\*", ".*");
0N/A return regex;
0N/A }
0N/A}