예제 #1
0
  @Override
  public void performAction() {
    FileTable fileTable = mainFrame.getActiveTable();
    FileTableModel tableModel = fileTable.getFileTableModel();

    // Starts at 1 if current folder is not root so that '..' is not marked
    AbstractFile file;
    int nbRows = tableModel.getRowCount();
    for (int i = tableModel.getFirstMarkableRow(); i < nbRows; i++) {
      file = tableModel.getFileAtRow(i);
      if (!file.isDirectory()) tableModel.setRowMarked(i, !tableModel.isRowMarked(i));
    }
    fileTable.repaint();

    // Notify registered listeners that currently marked files have changed on the FileTable
    fileTable.fireMarkedFilesChangedEvent();
  }
예제 #2
0
  /** Copy constructor */
  public MainFrame(MainFrame mainFrame) {
    FolderPanel leftFolderPanel = mainFrame.getLeftPanel();
    FolderPanel rightFolderPanel = mainFrame.getRightPanel();
    FileTable leftFileTable = leftFolderPanel.getFileTable();
    FileTable rightFileTable = rightFolderPanel.getFileTable();

    init(
        new FolderPanel(
            this,
            new ConfFileTableTab[] {
              new ConfFileTableTab(leftFolderPanel.getCurrentFolder().getURL())
            },
            0,
            leftFileTable.getConfiguration()),
        new FolderPanel(
            this,
            new ConfFileTableTab[] {
              new ConfFileTableTab(rightFolderPanel.getCurrentFolder().getURL())
            },
            0,
            rightFileTable.getConfiguration()));

    // TODO: Sorting should be part of the FileTable configuration
    this.leftTable.sortBy(leftFileTable.getSortInfo());
    this.rightTable.sortBy(rightFileTable.getSortInfo());
  }
예제 #3
0
  /**
   * Sets the currently active FileTable. This method is to be called by FolderPanel only.
   *
   * @param table the currently active FileTable
   */
  void setActiveTable(FileTable table) {
    boolean activeTableChanged = activeTable != table;

    if (activeTableChanged) {
      this.activeTable = table;

      // Update window title to reflect new active table
      updateWindowTitle();

      // Fire table change events on registered ActivePanelListener instances.
      fireActivePanelChanged(table.getFolderPanel());
    }
  }
예제 #4
0
  /**
   * Creates a new main frame set to the given initial folders.
   *
   * @param leftInitialFolders the initial folders to display in the left panel's tabs
   * @param rightInitialFolders the initial folders to display in the right panel's tabs
   */
  public MainFrame(
      ConfFileTableTab[] leftTabs,
      int indexOfLeftSelectedTab,
      FileTableConfiguration leftTableConf,
      ConfFileTableTab[] rightTabs,
      int indexOfRightSelectedTab,
      FileTableConfiguration rightTableConf) {
    /*AbstractFile[] leftInitialFolders, AbstractFile[] rightInitialFolders,
    int indexOfLeftSelectedTab, int indexOfRightSelectedTab,
       FileURL[] leftLocationHistory, FileURL[] rightLocationHistory) { */
    init(
        new FolderPanel(this, leftTabs, indexOfLeftSelectedTab, leftTableConf),
        new FolderPanel(this, rightTabs, indexOfRightSelectedTab, rightTableConf));

    for (boolean isLeft = true; ; isLeft = false) {
      FileTable fileTable = isLeft ? leftTable : rightTable;
      fileTable.sortBy(
          Column.valueOf(
              MuConfigurations.getSnapshot()
                  .getVariable(
                      MuSnapshot.getFileTableSortByVariable(0, isLeft), MuSnapshot.DEFAULT_SORT_BY)
                  .toUpperCase()),
          !MuConfigurations.getSnapshot()
              .getVariable(
                  MuSnapshot.getFileTableSortOrderVariable(0, isLeft),
                  MuSnapshot.DEFAULT_SORT_ORDER)
              .equals(MuSnapshot.SORT_ORDER_DESCENDING));

      FolderPanel folderPanel = isLeft ? leftFolderPanel : rightFolderPanel;
      folderPanel.setTreeWidth(
          MuConfigurations.getSnapshot()
              .getVariable(MuSnapshot.getTreeWidthVariable(0, isLeft), 150));
      folderPanel.setTreeVisible(
          MuConfigurations.getSnapshot()
              .getVariable(MuSnapshot.getTreeVisiblityVariable(0, isLeft), false));

      if (!isLeft) break;
    }
  }
예제 #5
0
  /**
   * Updates this window's title to show currently active folder and window number. This method is
   * called by this class and WindowManager.
   */
  public void updateWindowTitle() {
    // Update window title
    String title = activeTable.getFolderPanel().getCurrentFolder().getAbsolutePath();

    // Add the application name to window title on all OSs except MAC
    if (!OsFamily.MAC_OS_X.isCurrent()) title += " - muCommander";

    java.util.List<MainFrame> mainFrames = WindowManager.getMainFrames();
    if (mainFrames.size() > 1) title += " [" + (mainFrames.indexOf(this) + 1) + "]";
    setTitle(title);

    // Use new Window decorations introduced in Mac OS X 10.5 (Leopard)
    if (OsFamily.MAC_OS_X.isCurrent() && OsVersion.MAC_OS_X_10_5.isCurrentOrHigher()) {
      // Displays the document icon in the window title bar, works only for local files
      AbstractFile currentFolder = activeTable.getFolderPanel().getCurrentFolder();
      Object javaIoFile;
      if (currentFolder.getURL().getScheme().equals(FileProtocols.FILE)) {
        // If the current folder is an archive entry, display the archive file, this is the closest
        // we can get
        // with a java.io.File
        if (currentFolder.hasAncestor(AbstractArchiveEntryFile.class))
          javaIoFile = currentFolder.getParentArchive().getUnderlyingFileObject();
        else javaIoFile = currentFolder.getUnderlyingFileObject();
      } else {
        // If the current folder is not a local file, use the special /Network directory which is
        // sort of
        // 'Network Neighborhood'.
        javaIoFile = new java.io.File("/Network");
      }

      // Note that for some strange reason (looks like a bug), setting the property to null won't
      // remove
      // the previous icon.
      getRootPane().putClientProperty("Window.documentFile", javaIoFile);
    }
  }
  public void dragGestureRecognized(DragGestureEvent event) {
    if (folderPanel.getMainFrame().getNoEventsMode()) return;

    FileTable fileTable = folderPanel.getFileTable();
    FileTableModel tableModel = fileTable.getFileTableModel();

    // Return (do not initiate drag) if mouse button2 or button3 was used
    if ((event.getTriggerEvent().getModifiers()
            & (InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK))
        != 0) return;

    // Do not use that to retrieve the current selected file as it is inaccurate: the selection
    // could have changed since the
    // the mouse was clicked.
    //        AbstractFile selectedFile = fileTable.getSelectedFile(false);
    //        // Return if selected file is null (could happen if '..' is selected)
    //        if(selectedFile==null)
    //            return;

    // Find out which row was clicked
    int clickedRow = fileTable.rowAtPoint(event.getDragOrigin());
    // Return (do not initiate drag) if the selected file is the parent folder '..'
    if (clickedRow == -1 || fileTable.isParentFolder(clickedRow)) return;

    // Retrieve the file corresponding to the clicked row
    AbstractFile selectedFile = tableModel.getFileAtRow(clickedRow);

    // Find out which files are to be dragged, based on the selected file and currenlty marked
    // files.
    // If there are some files marked, drag marked files only if the selected file is one of the
    // marked files.
    // In any other case, only drag the selected file.
    FileSet markedFiles;
    FileSet draggedFiles;
    if (tableModel.getNbMarkedFiles() > 0
        && (markedFiles = fileTable.getSelectedFiles()).contains(selectedFile)) {
      draggedFiles = markedFiles;
    } else {
      draggedFiles = new FileSet(fileTable.getCurrentFolder(), selectedFile);
    }

    // Set initial DnDContext information
    DnDContext.setDragInitiatedByMucommander(true);
    DnDContext.setDragInitiator(folderPanel);
    DnDContext.setDragGestureModifiersEx(event.getTriggerEvent().getModifiersEx());

    // Start dragging
    DragSource.getDefaultDragSource()
        .startDrag(event, null, new TransferableFileSet(draggedFiles), this);
    //        DragSource.getDefaultDragSource().startDrag(createCustomDragGestureEvent(event,
    // DnDConstants.ACTION_MOVE), null, new TransferableFileSet(draggedFiles), this);
  }
  @Override
  protected int getRowIncrement() {
    FileTable activeTable = mainFrame.getActiveTable();

    return activeTable.getRowCount() - activeTable.getSelectedRow();
  }
예제 #8
0
 public void setAutoSizeColumnsEnabled(boolean b) {
   leftTable.setAutoSizeColumnsEnabled(b);
   rightTable.setAutoSizeColumnsEnabled(b);
 }
예제 #9
0
 public boolean isAutoSizeColumnsEnabled() {
   return leftTable.isAutoSizeColumnsEnabled();
 }
예제 #10
0
 /** Makes both folders the same, choosing the one which is currently active. */
 public void setSameFolder() {
   (activeTable == leftTable ? rightTable : leftTable)
       .getFolderPanel()
       .tryChangeCurrentFolder(activeTable.getFolderPanel().getCurrentFolder());
 }
예제 #11
0
  /**
   * Swaps the two FolderPanel instances: after a call to this method, the left FolderPanel will be
   * the right one and vice-versa.
   */
  public void swapFolders() {
    splitPane.remove(leftFolderPanel);
    splitPane.remove(rightFolderPanel);

    // Swaps the folder panels.
    FolderPanel tempPanel = leftFolderPanel;
    leftFolderPanel = rightFolderPanel;
    rightFolderPanel = tempPanel;

    // swaps folders trees
    int tempTreeWidth = leftFolderPanel.getTreeWidth();
    leftFolderPanel.setTreeWidth(rightFolderPanel.getTreeWidth());
    rightFolderPanel.setTreeWidth(tempTreeWidth);
    boolean tempTreeVisible = leftFolderPanel.isTreeVisible();
    leftFolderPanel.setTreeVisible(rightFolderPanel.isTreeVisible());
    rightFolderPanel.setTreeVisible(tempTreeVisible);

    // Resets the tables.
    FileTable tempTable = leftTable;
    leftTable = rightTable;
    rightTable = tempTable;

    // Preserve the sort order and columns visibility.
    TableColumnModel model = leftTable.getColumnModel();
    leftTable.setColumnModel(rightTable.getColumnModel());
    rightTable.setColumnModel(model);

    SortInfo sortInfo = (SortInfo) leftTable.getSortInfo().clone();

    leftTable.sortBy(rightTable.getSortInfo());
    leftTable.updateColumnsVisibility();

    rightTable.sortBy(sortInfo);
    rightTable.updateColumnsVisibility();

    // Do the swap and update the split pane
    splitPane.setLeftComponent(leftFolderPanel);
    splitPane.setRightComponent(rightFolderPanel);

    splitPane.doLayout();

    // Update split pane divider's location
    splitPane.updateDividerLocation();

    activeTable.requestFocus();
  }
예제 #12
0
 /**
  * Returns the currently active panel.
  *
  * <p>The returned panel doesn't necessarily have focus, for example if the MainFrame is currently
  * not in the foreground.
  *
  * @return the currently active panel
  */
 public FolderPanel getActivePanel() {
   return activeTable.getFolderPanel();
 }
예제 #13
0
  private void init(FolderPanel leftFolderPanel, FolderPanel rightFolderPanel) {
    // Set the window icon
    setWindowIcon();

    if (OsFamily.MAC_OS_X.isCurrent()) {
      // Lion Fullscreen support
      FullScreenUtilities.setWindowCanFullScreen(this, true);
    }

    // Enable window resize
    setResizable(true);

    // The toolbar should have no inset, this is why it is left out of the insetsPane
    JPanel contentPane = new JPanel(new BorderLayout());
    setContentPane(contentPane);

    // Initializes the folder panels and file tables.
    this.leftFolderPanel = leftFolderPanel;
    this.rightFolderPanel = rightFolderPanel;
    leftTable = leftFolderPanel.getFileTable();
    rightTable = rightFolderPanel.getFileTable();
    activeTable = leftTable;

    // Create the toolbar and corresponding panel wrapping it, and show it only if it hasn't been
    // disabled in the
    // preferences.
    // Note: Toolbar.setVisible() has to be called no matter if Toolbar is visible or not, in order
    // for it to be
    // properly initialized
    this.toolbar = new ToolBar(this);
    this.toolbarPanel = ToolbarMoreButton.wrapToolBar(toolbar);
    this.toolbarPanel.setVisible(
        MuConfigurations.getPreferences()
            .getVariable(MuPreference.TOOLBAR_VISIBLE, MuPreferences.DEFAULT_TOOLBAR_VISIBLE));
    contentPane.add(toolbarPanel, BorderLayout.NORTH);

    JPanel insetsPane =
        new JPanel(new BorderLayout()) {
          // Add an x=3,y=3 gap around content pane
          @Override
          public Insets getInsets() {
            return new Insets(0, 3, 3, 3); // No top inset
          }
        };

    // Below the toolbar there is the pane with insets
    contentPane.add(insetsPane, BorderLayout.CENTER);

    // Listen to location change events to display the current folder in the window's title
    leftFolderPanel.getLocationManager().addLocationListener(this);
    rightFolderPanel.getLocationManager().addLocationListener(this);

    // Create menu bar (has to be created after toolbar)
    MainMenuBar menuBar = new MainMenuBar(this);
    setJMenuBar(menuBar);

    // Create the split pane that separates folder panels and allows to resize how much space is
    // allocated to the
    // both of them. The split orientation is loaded from and saved to the preferences.
    // Note: the vertical/horizontal terminology used in muCommander is just the opposite of the one
    // used
    // in JSplitPane which is anti-natural / confusing.
    splitPane =
        new ProportionalSplitPane(
            this,
            MuConfigurations.getSnapshot()
                    .getVariable(
                        MuSnapshot.getSplitOrientation(0), MuSnapshot.DEFAULT_SPLIT_ORIENTATION)
                    .equals(MuSnapshot.VERTICAL_SPLIT_ORIENTATION)
                ? JSplitPane.HORIZONTAL_SPLIT
                : JSplitPane.VERTICAL_SPLIT,
            false,
            MainFrame.this.leftFolderPanel,
            MainFrame.this.rightFolderPanel) {
          // We don't want any extra space around split pane
          @Override
          public Insets getInsets() {
            return new Insets(0, 0, 0, 0);
          }
        };

    // Remove any default border the split pane has
    splitPane.setBorder(null);

    // Adds buttons that allow to collapse and expand the split pane in both directions
    splitPane.setOneTouchExpandable(true);

    // Disable all the JSPlitPane accessibility shortcuts that are registered by default, as some of
    // them
    // conflict with default mucommander action shortcuts (e.g. F6 and F8)
    splitPane.disableAccessibilityShortcuts();

    // Split pane will be given any extra space
    insetsPane.add(splitPane, BorderLayout.CENTER);

    // Add a 2-pixel gap between the file table and status bar
    YBoxPanel southPanel = new YBoxPanel();
    southPanel.addSpace(2);

    // Add status bar
    this.statusBar = new StatusBar(this);
    southPanel.add(statusBar);

    // Show command bar only if it hasn't been disabled in the preferences
    this.commandBar = new CommandBar(this);
    // Note: CommandBar.setVisible() has to be called no matter if CommandBar is visible or not, in
    // order for it to be properly initialized
    this.commandBar.setVisible(
        MuConfigurations.getPreferences()
            .getVariable(
                MuPreference.COMMAND_BAR_VISIBLE, MuPreferences.DEFAULT_COMMAND_BAR_VISIBLE));
    southPanel.add(commandBar);
    insetsPane.add(southPanel, BorderLayout.SOUTH);

    // Perform CloseAction when the user asked the window to close
    setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    addWindowListener(
        new WindowAdapter() {
          @Override
          public void windowClosing(WindowEvent e) {
            ActionManager.performAction(CloseWindowAction.Descriptor.ACTION_ID, MainFrame.this);
          }
        });

    ActionKeymap.registerActions(this);

    // Fire table change events on registered ActivePanelListener instances, to notify of the intial
    // active table.
    fireActivePanelChanged(activeTable.getFolderPanel());

    // Set the custom FocusTraversalPolicy that manages focus for both FolderPanel and their
    // subcomponents.
    setFocusTraversalPolicy(new CustomFocusTraversalPolicy());
  }