- ShortcutsDialog: grouped tree of all keyboard shortcuts (Help menu) - Workspace tab context menu: Rename, Close, Close Others, Close to Right - SQL query tab context menu: Rename, Duplicate, Close, Close Others - Smart status bar: right-side connection indicator + selected cell preview - File → Open SQL File (Ctrl+O), Save (Ctrl+S), Save As, Open Recent - Recent files persisted to ~/.dbclient/recent_files.json (last 10) - TableViewer.cell_selected signal wired to status bar cell preview - EditorTab._filepath tracks the file associated with each query tab Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89 lines
3.0 KiB
Python
89 lines
3.0 KiB
Python
"""Keyboard Shortcuts reference dialog."""
|
|
from PyQt6.QtWidgets import (
|
|
QDialog, QVBoxLayout, QTreeWidget, QTreeWidgetItem, QDialogButtonBox,
|
|
)
|
|
from PyQt6.QtCore import Qt
|
|
from PyQt6.QtGui import QFont
|
|
|
|
_SHORTCUTS = [
|
|
("SQL Editor", [
|
|
("F5 / Ctrl+Enter", "Run query"),
|
|
("Ctrl+/", "Toggle line comment"),
|
|
("Ctrl+Space", "Force auto-complete"),
|
|
("Ctrl+F", "Find in editor"),
|
|
("Ctrl+H", "Find & Replace in editor"),
|
|
("Ctrl+Z / Ctrl+Y", "Undo / Redo"),
|
|
("Ctrl+A", "Select all"),
|
|
("Ctrl+O", "Open SQL file"),
|
|
("Ctrl+S", "Save SQL file"),
|
|
]),
|
|
("Navigation", [
|
|
("Ctrl+N", "New connection"),
|
|
("Ctrl+T", "New SQL tab"),
|
|
("Ctrl+W", "Close current tab"),
|
|
("Ctrl+Tab", "Next tab"),
|
|
]),
|
|
("Tools & Panels", [
|
|
("Ctrl+P", "Process list"),
|
|
("Ctrl+U", "User management"),
|
|
("Ctrl+Shift+H", "Toggle query history"),
|
|
("Ctrl+L", "View app logs"),
|
|
]),
|
|
("Table Viewer", [
|
|
("Ins", "Add new row"),
|
|
("Delete", "Delete selected row(s)"),
|
|
("Double-click", "Edit row"),
|
|
]),
|
|
("General", [
|
|
("Ctrl+Q", "Quit"),
|
|
]),
|
|
]
|
|
|
|
|
|
class ShortcutsDialog(QDialog):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.setWindowTitle("Keyboard Shortcuts")
|
|
self.setMinimumSize(500, 540)
|
|
self.resize(540, 580)
|
|
self._build_ui()
|
|
|
|
def _build_ui(self):
|
|
root = QVBoxLayout(self)
|
|
root.setContentsMargins(12, 12, 12, 12)
|
|
root.setSpacing(8)
|
|
|
|
tree = QTreeWidget()
|
|
tree.setColumnCount(2)
|
|
tree.setHeaderLabels(["Shortcut", "Action"])
|
|
tree.setRootIsDecorated(True)
|
|
tree.setAlternatingRowColors(True)
|
|
tree.setEditTriggers(QTreeWidget.EditTrigger.NoEditTriggers)
|
|
tree.setSelectionMode(QTreeWidget.SelectionMode.NoSelection)
|
|
tree.header().setStretchLastSection(True)
|
|
tree.setIndentation(20)
|
|
|
|
bold = QFont()
|
|
bold.setBold(True)
|
|
|
|
for category, items in _SHORTCUTS:
|
|
cat_item = QTreeWidgetItem([category, ""])
|
|
cat_item.setFont(0, bold)
|
|
cat_item.setFlags(cat_item.flags() & ~Qt.ItemFlag.ItemIsSelectable)
|
|
for key, desc in items:
|
|
child = QTreeWidgetItem([key, desc])
|
|
child.setTextAlignment(
|
|
0, Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter
|
|
)
|
|
cat_item.addChild(child)
|
|
tree.addTopLevelItem(cat_item)
|
|
cat_item.setExpanded(True)
|
|
|
|
tree.resizeColumnToContents(0)
|
|
tree.setColumnWidth(0, max(200, tree.columnWidth(0) + 20))
|
|
root.addWidget(tree, 1)
|
|
|
|
bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Close)
|
|
bb.rejected.connect(self.reject)
|
|
root.addWidget(bb)
|