Skip to content

Commit

Permalink
Yellow folder icons, alternating row colors, copy paths
Browse files Browse the repository at this point in the history
  • Loading branch information
probonopd committed Jul 11, 2024
1 parent 2a56548 commit 6a2889c
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
51 changes: 46 additions & 5 deletions main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

import sys
import os
from PyQt6.QtWidgets import QApplication, QMainWindow, QHBoxLayout, QVBoxLayout, QListView, QWidget, QAbstractItemView, QMessageBox, QLabel, QTextEdit, QStackedWidget, QInputDialog, QMenu
from PyQt6.QtCore import QSettings, QByteArray, Qt, QDir, QModelIndex, QUrl, QMimeData
from PyQt6.QtWidgets import QApplication, QMainWindow, QHBoxLayout, QVBoxLayout, QListView, QWidget, QAbstractItemView, QMessageBox, QLabel, QTextEdit, QStackedWidget, QInputDialog, QMenu, QStyle
from PyQt6.QtCore import QSettings, QByteArray, Qt, QDir, QModelIndex, QUrl, QMimeData, QSize
from PyQt6.QtGui import QFileSystemModel, QAction, QPixmap, QDrag, QCursor
from PyQt6.QtWebEngineWidgets import QWebEngineView # pip install PyQt6-WebEngine
import mimetypes
Expand All @@ -20,14 +20,31 @@
import toolbar
import status_bar

class CustomFileSystemModel(QFileSystemModel):
"""
Custom file system model that allows us to customize e.g., the icons being used.
"""
def data(self, index, role):
if role == Qt.ItemDataRole.DecorationRole:
if self.isDir(index):
return self.style().standardIcon(QStyle.StandardPixmap.SP_DirIcon)
return super().data(index, role)

def style(self):
# To access the style in the model, we need to create a temporary widget
# This is a workaround because models don't have a style method
from PyQt6.QtWidgets import QWidget
return QWidget().style()


class DragDropListView(QListView):
"""
Custom list view that supports drag and drop operations.
"""
def __init__(self, parent=None):
super().__init__(parent)
self.setAcceptDrops(True)

def dragEnterEvent(self, event):
if event.mimeData().hasUrls() or event.mimeData().hasText():
event.acceptProposedAction()
Expand Down Expand Up @@ -74,6 +91,8 @@ def __init__(self):
self.setWindowTitle("Miller Columns File Manager")
self.resize(1000, 600) # Default size

self.setWindowIcon(self.style().standardIcon(QStyle.StandardPixmap.SP_DirIcon))

self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)

Expand All @@ -82,9 +101,9 @@ def __init__(self):
self.column_layout = QHBoxLayout()
self.columns = []

self.file_model = QFileSystemModel()
self.file_model = CustomFileSystemModel()
self.file_model.setRootPath('')
self.file_model.setOption(QFileSystemModel.Option.DontUseCustomDirectoryIcons, False) # Enable color icons
self.file_model.setOption(CustomFileSystemModel.Option.DontUseCustomDirectoryIcons, False) # Enable color icons
self.file_model.setFilter(QDir.Filter.AllEntries | QDir.Filter.Hidden | QDir.Filter.System)
# FIXME: . and .. should not be shown in the view, but things like $RECYCLE.BIN should be shown

Expand Down Expand Up @@ -233,7 +252,28 @@ def add_column(self, parent_index=None):
column_view = DragDropListView()
column_view.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
column_view.setUniformItemSizes(True)

column_view.setAlternatingRowColors(True)
# Set alternating row colors and text color using a style sheet
column_view.setStyleSheet("""
QListView::item {
background-color: white;
color: black;
}
QListView::item:alternate {
background-color: #f7f7f7;
color: black;
}
QListView::item:selected {
color: white;
background-color: palette(highlight);
}
QListView::item:selected:active {
color: palette(highlightedText);
background-color: palette(highlight);
}
""")

column_view.setModel(self.file_model)

if parent_index:
Expand Down Expand Up @@ -401,6 +441,7 @@ def empty_trash(self):

if __name__ == "__main__":
app = QApplication(sys.argv)
app.setWindowIcon(app.style().standardIcon(QStyle.StandardPixmap.SP_DirIcon))
window = MillerColumns()
window.show()
sys.exit(app.exec())
10 changes: 6 additions & 4 deletions toolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ def create_toolbar(window):
toolbar = QToolBar("Navigation")
window.addToolBar(Qt.ToolBarArea.TopToolBarArea, toolbar)

up_action = QAction(QIcon.fromTheme("go-up"), "Up", window)
up_action.triggered.connect(window.go_up)
toolbar.addAction(up_action)

home_action = QAction(QIcon.fromTheme("home"), "Home", window)
home_action.triggered.connect(window.go_home)
toolbar.addAction(home_action)

up_action = QAction(QIcon.fromTheme("go-up"), "Up", window)
up_action.triggered.connect(window.go_up)
toolbar.addAction(up_action)

window.path_label = QLineEdit()
window.path_label.setReadOnly(False)
window.path_label.setPlaceholderText("Enter Directory Path")
window.path_label.returnPressed.connect(window.change_path)
toolbar.addWidget(window.path_label)

toolbar.setMovable(False)
9 changes: 8 additions & 1 deletion windows_context_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,14 @@ def show_context_menu(paths: Sequence[os.PathLike | str]):
if verb.Name:
app = QApplication.instance()
action = QAction(verb.Name, app)
action.triggered.connect(lambda _, v=verb: execute_verb(v))
# Copying the path does not work using the default context menu action,
# hence we override it
# FIXME: Find a way that works independently of the language
if "path" or "Pfad" in verb.Name:
# Copy path to clipboard
action.triggered.connect(lambda _, p=paths[0]: app.clipboard().setText(str(p)))
else:
action.triggered.connect(lambda _, v=verb: execute_verb(v))
menu.addAction(action)
else:
menu.addSeparator()
Expand Down

0 comments on commit 6a2889c

Please sign in to comment.