eric7/UI/FindLocationWidget.py

Fri, 24 Sep 2021 20:09:58 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Fri, 24 Sep 2021 20:09:58 +0200
branch
eric7
changeset 8632
f25cd4b94eb0
parent 8358
eric7/UI/FindFileNameDialog.py@144a6b854f70
child 8636
c0a3a6e40815
permissions
-rw-r--r--

Changed the Find File dialog to an integrated widget (right side)

# -*- coding: utf-8 -*-

# Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a dialog to search for files.
"""

import os
import sys

from PyQt6.QtCore import pyqtSignal, pyqtSlot
from PyQt6.QtWidgets import (
    QWidget, QHeaderView, QApplication, QTreeWidgetItem
)

from EricWidgets.EricPathPicker import EricPathPickerModes

from .Ui_FindLocationWidget import Ui_FindLocationWidget

import UI.PixmapCache
from Utilities import direntries
import Utilities


class FindLocationWidget(QWidget, Ui_FindLocationWidget):
    """
    Class implementing a widget to search for files.
    
    The occurrences found are displayed in a QTreeWidget showing the
    filename and the pathname. The file will be opened upon a double click
    onto the respective entry of the list or by pressing the open button.
    
    @signal sourceFile(str) emitted to open a file in the editor
    @signal designerFile(str) emitted to open a Qt-Designer file
    """
    sourceFile = pyqtSignal(str)
    designerFile = pyqtSignal(str)
    
    def __init__(self, project, parent=None):
        """
        Constructor
        
        @param project reference to the project object
        @type Project
        @param parent parent widget of this dialog
        @type QWidget
        """
        super().__init__(parent)
        self.setupUi(self)
        
        self.layout().setContentsMargins(0, 3, 0, 0)
        
        self.searchDirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
        
        self.fileList.headerItem().setText(self.fileList.columnCount(), "")
        
        self.stopButton.setEnabled(False)
        self.stopButton.clicked.connect(self.__stopSearch)
        self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading"))
        
        self.findButton.setEnabled(False)
        self.findButton.clicked.connect(self.__searchFile)
        self.findButton.setIcon(UI.PixmapCache.getIcon("find"))
        
        self.openButton.setIcon(UI.PixmapCache.getIcon("open"))
        self.openButton.clicked.connect(self.__openFile)
        
        self.project = project
        self.extsepLabel.setText(os.extsep)
        
        self.__shouldStop = False
        
        self.fileNameEdit.returnPressed.connect(self.__searchFile)
        self.fileExtEdit.returnPressed.connect(self.__searchFile)
    
    @pyqtSlot()
    def __stopSearch(self):
        """
        Private slot to handle the stop button being pressed.
        """
        self.__shouldStop = True
    
    @pyqtSlot()
    def __openFile(self, itm=None):
        """
        Private slot to open a file.
        
        It emits the signal sourceFile or designerFile depending on the
        file extension.
        
        @param itm item to be opened
        @type QTreeWidgetItem
        """
        if itm is None:
            itm = self.fileList.currentItem()
        if itm is not None:
            fileName = itm.text(0)
            filePath = itm.text(1)
            
            # TODO: add more extensions and use mimetype
            #       - *.ts, *.qm->*.ts
            #       Utilities.MimeTypes.isTextFile(filename)
            if fileName.endswith('.ui'):
                self.designerFile.emit(os.path.join(filePath, fileName))
            else:
                self.sourceFile.emit(os.path.join(filePath, fileName))
    
    @pyqtSlot()
    def __searchFile(self):
        """
        Private slot to handle the search.
        """
        fileName = self.fileNameEdit.text()
        if not fileName:
            self.fileList.clear()
            return
        
        fileExt = self.fileExtEdit.text()
        if not fileExt and Utilities.isWindowsPlatform():
            self.fileList.clear()
            return
        
        self.findStatusLabel.clear()
        
        patternFormat = fileExt and "{0}{1}{2}" or "{0}*{1}{2}"
        fileNamePattern = patternFormat.format(
            fileName, os.extsep, fileExt and fileExt or '*')
        
        searchPaths = []
        if (
            self.searchDirCheckBox.isChecked() and
            self.searchDirPicker.text() != ""
        ):
            searchPaths.append(self.searchDirPicker.text())
        if self.projectCheckBox.isChecked():
            searchPaths.append(self.project.ppath)
        if self.syspathCheckBox.isChecked():
            searchPaths.extend(sys.path)
        
        self.fileList.clear()
        locations = {}
        self.__shouldStop = False
        self.stopButton.setEnabled(True)
        QApplication.processEvents()
        
        for path in searchPaths:
            if os.path.isdir(path):
                files = direntries(path, True, fileNamePattern,
                                   False, self.checkStop)
                if files:
                    for file in files:
                        fp, fn = os.path.split(file)
                        if fn in locations:
                            if fp in locations[fn]:
                                continue
                            else:
                                locations[fn].append(fp)
                        else:
                            locations[fn] = [fp]
                        QTreeWidgetItem(self.fileList, [fn, fp])
                    QApplication.processEvents()
        
        del locations
        self.stopButton.setEnabled(False)
        self.fileList.header().resizeSections(
            QHeaderView.ResizeMode.ResizeToContents)
        self.fileList.header().setStretchLastSection(True)
        
        self.findStatusLabel.setText(self.tr(
            "%n file(s) found", "", self.fileList.topLevelItemCount()))

    def checkStop(self):
        """
        Public method to check, if the search should be stopped.
        
        @return flag indicating the search should be stopped
        @rtype bool
        """
        QApplication.processEvents()
        return self.__shouldStop
    
    @pyqtSlot(str)
    def on_fileNameEdit_textChanged(self, text):
        """
        Private slot to handle the textChanged signal of the file name edit.
        
        @param text (ignored)
        @type str
        """
        self.findButton.setEnabled(bool(text))
    
    @pyqtSlot(str)
    def on_searchDirPicker_textChanged(self, text):
        """
        Private slot to handle the textChanged signal of the search directory
        edit.
        
        @param text text of the search dir edit
        @type str
        """
        self.searchDirCheckBox.setEnabled(text != "")
    
    @pyqtSlot(QTreeWidgetItem, int)
    def on_fileList_itemActivated(self, itm, column):
        """
        Private slot to handle the double click on a file item.
        
        It emits the signal sourceFile or designerFile depending on the
        file extension.
        
        @param itm the double clicked listview item
        @type QTreeWidgetItem
        @param column column that was double clicked (ignored)
        @type int
        """
        self.__openFile(itm)
    
    @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem)
    def on_fileList_currentItemChanged(self, current, previous):
        """
        Private slot handling a change of the current item.
        
        @param current current item
        @type QTreeWidgetItem
        @param previous prevoius current item
        @type QTreeWidgetItem
        """
        self.openButton.setEnabled(current is not None)
    
    @pyqtSlot()
    def activate(self):
        """
        Public slot to enable/disable the project checkbox.
        """
        if self.project and self.project.isOpen():
            self.projectCheckBox.setEnabled(True)
            self.projectCheckBox.setChecked(True)
        else:
            self.projectCheckBox.setEnabled(False)
            self.projectCheckBox.setChecked(False)
        
        self.fileNameEdit.selectAll()
        self.fileNameEdit.setFocus()

eric ide

mercurial