test on linux
This commit is contained in:
parent
fd47239832
commit
7529cb31eb
@ -6,6 +6,7 @@ import javax.swing.*;
|
|||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -166,6 +167,44 @@ public class FilePanelTab extends JPanel {
|
|||||||
fileTable = new JTable(tableModel) {
|
fileTable = new JTable(tableModel) {
|
||||||
@Override
|
@Override
|
||||||
protected void processMouseEvent(java.awt.event.MouseEvent e) {
|
protected void processMouseEvent(java.awt.event.MouseEvent e) {
|
||||||
|
// Show system-like context menu on popup trigger (right-click) without
|
||||||
|
// changing default mouse-driven selection behavior.
|
||||||
|
try {
|
||||||
|
if (e.isPopupTrigger()) {
|
||||||
|
int col = columnAtPoint(e.getPoint());
|
||||||
|
int row = rowAtPoint(e.getPoint());
|
||||||
|
FileItem item = null;
|
||||||
|
if (row >= 0) {
|
||||||
|
if (viewMode == ViewMode.BRIEF) {
|
||||||
|
item = tableModel.getItemFromBriefLayout(row, col);
|
||||||
|
if (item != null) {
|
||||||
|
int index = tableModel.items.indexOf(item);
|
||||||
|
if (index >= 0) {
|
||||||
|
int selRow = index % tableModel.briefRowsPerColumn;
|
||||||
|
int selCol = index / tableModel.briefRowsPerColumn;
|
||||||
|
briefCurrentColumn = selCol;
|
||||||
|
// Select the logical row so actions apply to this item
|
||||||
|
fileTable.setRowSelectionInterval(selRow, selRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item = tableModel.getItem(row);
|
||||||
|
if (item != null) {
|
||||||
|
fileTable.setRowSelectionInterval(row, row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item != null) {
|
||||||
|
// Delegate to outer class to build and show the menu
|
||||||
|
FilePanelTab.this.showContextMenuForItem(item, e.getPoint());
|
||||||
|
}
|
||||||
|
e.consume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
// best-effort: ignore exceptions here to avoid breaking mouse handling
|
||||||
|
}
|
||||||
// Intercept mouse events to prevent changing selection via mouse.
|
// Intercept mouse events to prevent changing selection via mouse.
|
||||||
// Allow single-click to toggle marking of an item, allow BRIEF column
|
// Allow single-click to toggle marking of an item, allow BRIEF column
|
||||||
// tracking, and preserve double-click to open items. Dragging/presses
|
// tracking, and preserve double-click to open items. Dragging/presses
|
||||||
@ -809,6 +848,129 @@ public class FilePanelTab extends JPanel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a context popup menu for a specific file item at the given point (table coordinates).
|
||||||
|
*/
|
||||||
|
private void showContextMenuForItem(FileItem item, Point tablePoint) {
|
||||||
|
if (item == null) return;
|
||||||
|
|
||||||
|
JPopupMenu menu = new JPopupMenu();
|
||||||
|
|
||||||
|
// Open
|
||||||
|
JMenuItem openItem = new JMenuItem("Open");
|
||||||
|
openItem.addActionListener(ae -> {
|
||||||
|
if (item.getName().equals("..")) return;
|
||||||
|
if (item.isDirectory()) {
|
||||||
|
loadDirectory(item.getFile());
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (Desktop.isDesktopSupported()) {
|
||||||
|
Desktop.getDesktop().open(item.getFile());
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Cannot open: " + ex.getMessage()); } catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.add(openItem);
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
JMenuItem editItem = new JMenuItem("Edit");
|
||||||
|
editItem.addActionListener(ae -> {
|
||||||
|
if (item.isDirectory() || item.getName().equals("..")) return;
|
||||||
|
try {
|
||||||
|
String ext = persistedConfig != null ? persistedConfig.getExternalEditorPath() : null;
|
||||||
|
if (ext != null && !ext.trim().isEmpty()) {
|
||||||
|
java.util.List<String> cmd = new java.util.ArrayList<>();
|
||||||
|
cmd.add(ext);
|
||||||
|
cmd.add(item.getFile().getAbsolutePath());
|
||||||
|
new ProcessBuilder(cmd).start();
|
||||||
|
} else if (Desktop.isDesktopSupported()) {
|
||||||
|
Desktop.getDesktop().edit(item.getFile());
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Cannot edit: " + ex.getMessage()); } catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.add(editItem);
|
||||||
|
|
||||||
|
// Show in folder / Reveal
|
||||||
|
JMenuItem revealItem = new JMenuItem("Show in folder");
|
||||||
|
revealItem.addActionListener(ae -> {
|
||||||
|
try {
|
||||||
|
String os = System.getProperty("os.name").toLowerCase();
|
||||||
|
File f = item.getFile();
|
||||||
|
if (os.contains("win")) {
|
||||||
|
new ProcessBuilder("explorer.exe", "/select,", f.getAbsolutePath()).start();
|
||||||
|
} else if (os.contains("mac")) {
|
||||||
|
new ProcessBuilder("open", "-R", f.getAbsolutePath()).start();
|
||||||
|
} else {
|
||||||
|
File parent = f.getParentFile();
|
||||||
|
if (parent != null) new ProcessBuilder("xdg-open", parent.getAbsolutePath()).start();
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Cannot reveal file: " + ex.getMessage()); } catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.add(revealItem);
|
||||||
|
|
||||||
|
// Copy path
|
||||||
|
JMenuItem copyPath = new JMenuItem("Copy path");
|
||||||
|
copyPath.addActionListener(ae -> {
|
||||||
|
try {
|
||||||
|
StringSelection sel = new StringSelection(item.getFile().getAbsolutePath());
|
||||||
|
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(sel, null);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Cannot copy path: " + ex.getMessage()); } catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.add(copyPath);
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
JMenuItem deleteItem = new JMenuItem("Delete");
|
||||||
|
deleteItem.addActionListener(ae -> {
|
||||||
|
int res = JOptionPane.showConfirmDialog(FilePanelTab.this,
|
||||||
|
"Really delete '" + item.getName() + "'?",
|
||||||
|
"Delete",
|
||||||
|
JOptionPane.YES_NO_OPTION,
|
||||||
|
JOptionPane.WARNING_MESSAGE);
|
||||||
|
if (res == JOptionPane.YES_OPTION) {
|
||||||
|
try {
|
||||||
|
java.util.List<FileItem> toDelete = new java.util.ArrayList<>();
|
||||||
|
toDelete.add(item);
|
||||||
|
com.kfmanager.service.FileOperations.delete(toDelete, null);
|
||||||
|
// reload current directory
|
||||||
|
loadDirectory(getCurrentDirectory());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Delete failed: " + ex.getMessage()); } catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.add(deleteItem);
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
JMenuItem props = new JMenuItem("Properties");
|
||||||
|
props.addActionListener(ae -> {
|
||||||
|
try {
|
||||||
|
File f = item.getFile();
|
||||||
|
String info = String.format("Name: %s\nPath: %s\nSize: %s\nModified: %s\nReadable: %b, Writable: %b, Executable: %b",
|
||||||
|
f.getName(), f.getAbsolutePath(), item.isDirectory() ? "<DIR>" : formatSize(f.length()),
|
||||||
|
new java.util.Date(f.lastModified()).toString(), f.canRead(), f.canWrite(), f.canExecute());
|
||||||
|
JOptionPane.showMessageDialog(FilePanelTab.this, info, "Properties", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Cannot show properties: " + ex.getMessage()); } catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
menu.add(props);
|
||||||
|
|
||||||
|
// Show the popup at the click location
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
try {
|
||||||
|
menu.show(fileTable, tablePoint.x, tablePoint.y);
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void navigateUp() {
|
public void navigateUp() {
|
||||||
// If we're currently browsing an extracted archive root, navigate back to the
|
// If we're currently browsing an extracted archive root, navigate back to the
|
||||||
// original archive's parent and select the archive file.
|
// original archive's parent and select the archive file.
|
||||||
@ -1065,10 +1227,10 @@ public class FilePanelTab extends JPanel {
|
|||||||
isCurrentCell = isSelected;
|
isCurrentCell = isSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only show selection highlight when this table has keyboard focus.
|
||||||
|
// If the table is not focused, do not highlight any row (show normal background).
|
||||||
if (isCurrentCell && table.hasFocus()) {
|
if (isCurrentCell && table.hasFocus()) {
|
||||||
setBackground(selectionColor);
|
setBackground(selectionColor);
|
||||||
} else if (isCurrentCell) {
|
|
||||||
setBackground(selectionInactiveColor);
|
|
||||||
} else {
|
} else {
|
||||||
setBackground(FilePanelTab.this.getBackground());
|
setBackground(FilePanelTab.this.getBackground());
|
||||||
}
|
}
|
||||||
@ -1085,7 +1247,8 @@ public class FilePanelTab extends JPanel {
|
|||||||
} else {
|
} else {
|
||||||
// Preserve whatever style the base font has (do not force plain)
|
// Preserve whatever style the base font has (do not force plain)
|
||||||
setFont(baseFont.deriveFont(baseStyle));
|
setFont(baseFont.deriveFont(baseStyle));
|
||||||
setForeground(Color.BLACK);
|
// Use a light foreground color for better contrast on dark backgrounds
|
||||||
|
setForeground(new Color(240, 240, 240));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zobrazit ikonu pro názvy souborů
|
// Zobrazit ikonu pro názvy souborů
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user