def __init__(self, parent) -> None: super().__init__(parent) self.rapidApp = parent self.prefs = self.rapidApp.prefs self.setObjectName("jobCodePanelScrollArea") self.jobCodePanel = QPanelView(label=_("Job Codes"), ) self.jobCodePanel.setObjectName("jobCodePanel") self.jobCodeOptions = JobCodeOptionsWidget(prefs=self.prefs, rapidApp=self.rapidApp, parent=self) self.jobCodeOptions.setObjectName("jobCodeOptions") self.jobCodePanel.addWidget(self.jobCodeOptions) self.verticalScrollBarVisible.connect( self.jobCodeOptions.containerVerticalScrollBar) self.horizontalScrollBarVisible.connect( self.jobCodeOptions.containerHorizontalScrollBar) widget = QWidget() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) layout.addWidget(self.jobCodePanel) self.setWidget(widget) self.setWidgetResizable(True) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) if parent is not None: self.rapidApp.thumbnailView.selectionModel( ).selectionChanged.connect(self.jobCodeOptions.setWidgetStates) self.rapidApp.thumbnailModel.selectionReset.connect( self.jobCodeOptions.setWidgetStates)
def __init__(self, parent) -> None: super().__init__(parent) assert parent is not None self.rapidApp = parent self.prefs = self.rapidApp.prefs # type: Preferences self.setObjectName("backupPanelScrollArea") self.backupDevices = BackupDeviceModel(parent=self) self.backupStoragePanel = QPanelView( label=_("Projected Backup Storage Use"), ) self.backupStoragePanel.setObjectName("backupStoragePanel") self.backupOptionsPanel = QPanelView(label=_("Backup Options"), ) self.backupOptionsPanel.setObjectName("backupOptionsPanel") self.backupDevicesView = BackupDeviceView(rapidApp=self.rapidApp, parent=self) self.backupDevicesView.setObjectName("backupDevicesView") self.backupDevicesView.setModel(self.backupDevices) self.backupDevicesView.setItemDelegate( BackupDeviceDelegate(rapidApp=self.rapidApp)) self.backupDevicesView.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.backupOptionsPanel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) self.backupOptions = BackupOptionsWidget(prefs=self.prefs, parent=self, rapidApp=self.rapidApp) self.backupOptionsPanel.addWidget(self.backupOptions) self.backupStoragePanel.addWidget(self.backupDevicesView) self.verticalScrollBarVisible.connect( self.backupDevicesView.containerVerticalScrollBar) self.verticalScrollBarVisible.connect( self.backupOptions.containerVerticalScrollBar) self.horizontalScrollBarVisible.connect( self.backupOptions.containerHorizontalScrollBar) widget = QWidget() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(QSplitter().handleWidth()) widget.setLayout(layout) layout.addWidget(self.backupStoragePanel) layout.addWidget(self.backupOptionsPanel) self.setWidget(widget) self.setWidgetResizable(True) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
class JobCodePanel(ScrollAreaNoFrame): """ JobCode preferences widget """ def __init__(self, parent) -> None: super().__init__(parent) self.rapidApp = parent self.prefs = self.rapidApp.prefs self.setObjectName("jobCodePanelScrollArea") self.jobCodePanel = QPanelView(label=_("Job Codes"), ) self.jobCodePanel.setObjectName("jobCodePanel") self.jobCodeOptions = JobCodeOptionsWidget(prefs=self.prefs, rapidApp=self.rapidApp, parent=self) self.jobCodeOptions.setObjectName("jobCodeOptions") self.jobCodePanel.addWidget(self.jobCodeOptions) self.verticalScrollBarVisible.connect( self.jobCodeOptions.containerVerticalScrollBar) self.horizontalScrollBarVisible.connect( self.jobCodeOptions.containerHorizontalScrollBar) widget = QWidget() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) layout.addWidget(self.jobCodePanel) self.setWidget(widget) self.setWidgetResizable(True) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) if parent is not None: self.rapidApp.thumbnailView.selectionModel( ).selectionChanged.connect(self.jobCodeOptions.setWidgetStates) self.rapidApp.thumbnailModel.selectionReset.connect( self.jobCodeOptions.setWidgetStates) def needToPromptForJobCode(self) -> bool: return (self.prefs.any_pref_uses_job_code() and self.rapidApp.thumbnailModel.jobCodeNeeded()) def getJobCodeBeforeDownload(self) -> bool: """ :return: True if job code was entered and applied """ return self.jobCodeOptions.getJobCode(on_download=True) def updateDefaultMessage(self) -> None: self.jobCodeOptions.setDefaultMessage()
def __init__(self, parent) -> None: super().__init__(parent) self.rapidApp = parent self.prefs = self.rapidApp.prefs self.setObjectName("renamePanelScrollArea") self.photoRenamePanel = QPanelView( label=_("Photo Renaming"), ) self.photoRenamePanel.setObjectName("photoRenamePanelView") self.videoRenamePanel = QPanelView( label=_("Video Renaming"), ) self.videoRenamePanel.setObjectName("videoRenamePanelView") self.renameOptionsPanel = QPanelView( label=_("Renaming Options"), ) self.renameOptionsPanel.setObjectName("renameOptionsPanelView") self.photoRenameWidget = RenameWidget( preset_type=PresetPrefType.preset_photo_rename, prefs=self.prefs, parent=self, exiftool_process=self.rapidApp.exiftool_process, ) self.photoRenameWidget.setObjectName("photoRenameWidget") self.videoRenameWidget = RenameWidget( preset_type=PresetPrefType.preset_video_rename, prefs=self.prefs, parent=self, exiftool_process=self.rapidApp.exiftool_process, ) self.videoRenameWidget.setObjectName("videoRenameWidget") self.renameOptions = RenameOptionsWidget( prefs=self.prefs, parent=self, photoRenameWidget=self.photoRenameWidget, videoRenameWidget=self.videoRenameWidget, ) self.renameOptions.setObjectName("renameOptionsWidget") self.photoRenamePanel.addWidget(self.photoRenameWidget) self.videoRenamePanel.addWidget(self.videoRenameWidget) self.renameOptionsPanel.addWidget(self.renameOptions) for widget in ( self.photoRenameWidget, self.videoRenameWidget, self.renameOptions, ): self.verticalScrollBarVisible.connect(widget.containerVerticalScrollBar) self.horizontalScrollBarVisible.connect( self.renameOptions.containerHorizontalScrollBar ) widget = QWidget() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(QSplitter().handleWidth()) widget.setLayout(layout) layout.addWidget(self.photoRenamePanel) layout.addWidget(self.videoRenamePanel) layout.addWidget(self.renameOptionsPanel) self.setWidget(widget) self.setWidgetResizable(True) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
class RenamePanel(ScrollAreaNoFrame): """ Renaming preferences widget, for photos, videos, and general renaming options. """ def __init__(self, parent) -> None: super().__init__(parent) self.rapidApp = parent self.prefs = self.rapidApp.prefs self.setObjectName("renamePanelScrollArea") self.photoRenamePanel = QPanelView( label=_("Photo Renaming"), ) self.photoRenamePanel.setObjectName("photoRenamePanelView") self.videoRenamePanel = QPanelView( label=_("Video Renaming"), ) self.videoRenamePanel.setObjectName("videoRenamePanelView") self.renameOptionsPanel = QPanelView( label=_("Renaming Options"), ) self.renameOptionsPanel.setObjectName("renameOptionsPanelView") self.photoRenameWidget = RenameWidget( preset_type=PresetPrefType.preset_photo_rename, prefs=self.prefs, parent=self, exiftool_process=self.rapidApp.exiftool_process, ) self.photoRenameWidget.setObjectName("photoRenameWidget") self.videoRenameWidget = RenameWidget( preset_type=PresetPrefType.preset_video_rename, prefs=self.prefs, parent=self, exiftool_process=self.rapidApp.exiftool_process, ) self.videoRenameWidget.setObjectName("videoRenameWidget") self.renameOptions = RenameOptionsWidget( prefs=self.prefs, parent=self, photoRenameWidget=self.photoRenameWidget, videoRenameWidget=self.videoRenameWidget, ) self.renameOptions.setObjectName("renameOptionsWidget") self.photoRenamePanel.addWidget(self.photoRenameWidget) self.videoRenamePanel.addWidget(self.videoRenameWidget) self.renameOptionsPanel.addWidget(self.renameOptions) for widget in ( self.photoRenameWidget, self.videoRenameWidget, self.renameOptions, ): self.verticalScrollBarVisible.connect(widget.containerVerticalScrollBar) self.horizontalScrollBarVisible.connect( self.renameOptions.containerHorizontalScrollBar ) widget = QWidget() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(QSplitter().handleWidth()) widget.setLayout(layout) layout.addWidget(self.photoRenamePanel) layout.addWidget(self.videoRenamePanel) layout.addWidget(self.renameOptionsPanel) self.setWidget(widget) self.setWidgetResizable(True) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) def updateSequences( self, downloads_today: List[str], stored_sequence_no: int ) -> None: """ Update the value displayed in the display to reflect any values changed after the completion of a download. :param downloads_today: new downloads today value :param stored_sequence_no: new stored sequence number value """ self.renameOptions.downloadsToday.setValue(int(downloads_today[1])) self.renameOptions.downloads_today_tracker.downloads_today = downloads_today self.renameOptions.storedNumber.setValue(stored_sequence_no + 1) def setSamplePhoto(self, sample_photo: Photo) -> None: self.photoRenameWidget.updateSampleFile(sample_rpd_file=sample_photo) def setSampleVideo(self, sample_video: Video) -> None: self.videoRenameWidget.updateSampleFile(sample_rpd_file=sample_video)
class BackupPanel(ScrollAreaNoFrame): """ Backup preferences widget, for photos and video backups while downloading. """ def __init__(self, parent) -> None: super().__init__(parent) assert parent is not None self.rapidApp = parent self.prefs = self.rapidApp.prefs # type: Preferences self.setObjectName("backupPanelScrollArea") self.backupDevices = BackupDeviceModel(parent=self) self.backupStoragePanel = QPanelView( label=_("Projected Backup Storage Use"), ) self.backupStoragePanel.setObjectName("backupStoragePanel") self.backupOptionsPanel = QPanelView(label=_("Backup Options"), ) self.backupOptionsPanel.setObjectName("backupOptionsPanel") self.backupDevicesView = BackupDeviceView(rapidApp=self.rapidApp, parent=self) self.backupDevicesView.setObjectName("backupDevicesView") self.backupDevicesView.setModel(self.backupDevices) self.backupDevicesView.setItemDelegate( BackupDeviceDelegate(rapidApp=self.rapidApp)) self.backupDevicesView.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.backupOptionsPanel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) self.backupOptions = BackupOptionsWidget(prefs=self.prefs, parent=self, rapidApp=self.rapidApp) self.backupOptionsPanel.addWidget(self.backupOptions) self.backupStoragePanel.addWidget(self.backupDevicesView) self.verticalScrollBarVisible.connect( self.backupDevicesView.containerVerticalScrollBar) self.verticalScrollBarVisible.connect( self.backupOptions.containerVerticalScrollBar) self.horizontalScrollBarVisible.connect( self.backupOptions.containerHorizontalScrollBar) widget = QWidget() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(QSplitter().handleWidth()) widget.setLayout(layout) layout.addWidget(self.backupStoragePanel) layout.addWidget(self.backupOptionsPanel) self.setWidget(widget) self.setWidgetResizable(True) self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) def updateExample(self) -> None: """ Update the example paths in the backup panel """ self.backupOptions.updateExample() def updateLocationCombos(self) -> None: """ Update backup location comboboxes in case directory status has changed. """ self.backupOptions.updateLocationCombos() def addBackupVolume(self, mount_details: BackupVolumeDetails) -> None: self.backupDevices.addBackupVolume(mount_details=mount_details) self.backupDevicesView.updateGeometry() def removeBackupVolume(self, path: str) -> None: self.backupDevices.removeBackupVolume(path=path) self.backupDevicesView.updateGeometry() def resetBackupDisplay(self) -> None: self.backupDevices.reset() self.backupDevicesView.updateGeometry() def setupBackupDisplay(self) -> None: """ Sets up the backup view list regardless of whether backups are manual specified by the user, or auto-detection is on """ if not self.prefs.backup_files: logging.debug( "No backups configured: no backup destinations to display") return backup_devices = self.rapidApp.backup_devices # type: BackupDeviceCollection if self.prefs.backup_device_autodetection: for path in backup_devices: self.backupDevices.addBackupVolume( mount_details=backup_devices.get_backup_volume_details( path=path)) else: # manually specified backup paths try: mounts = backup_devices.get_manual_mounts() if mounts is None: return self.backupDevices.addBackupVolume(mount_details=mounts[0]) if len(mounts) > 1: self.backupDevices.addBackupVolume(mount_details=mounts[1]) except Exception: logging.exception( "An unexpected error occurred when adding backup destinations. " "Exception:") self.backupDevicesView.updateGeometry() def setDownloadAttributes(self, marked: FileTypeCounter, photos_size: int, videos_size: int, merge: bool) -> None: """ Set the attributes used to generate the visual display of the files marked to be downloaded :param marked: number and type of files marked for download :param photos_size: size in bytes of photos marked for download :param videos_size: size in bytes of videos marked for download :param merge: whether to replace or add to the current values """ self.backupDevices.setDownloadAttributes(marked=marked, photos_size=photos_size, videos_size=videos_size, merge=merge) def sufficientSpaceAvailable(self) -> bool: """ Check to see that there is sufficient space with which to perform a download. :return: True or False value if sufficient space. Will always return True if backups are disabled or there are no backup devices. """ if self.prefs.backup_files: return self.backupDevices.sufficientSpaceAvailable() else: return True def setDownloadingTo( self, downloading_to: DefaultDict[int, Set[FileType]]) -> None: self.backupDevices.downloading_to = downloading_to
def createDestinationViews(self) -> None: """ Create the widgets that let the user choose where to download photos and videos to, and that show them how much storage space there is available for their files. """ self.photoDestination = QPanelView(label=_("Photos"), ) self.photoDestination.setObjectName("photoDestinationPanelView") self.videoDestination = QPanelView(label=_("Videos"), ) self.videoDestination.setObjectName("videoDestinationPanelView") # Display storage space when photos and videos are being downloaded to the same # partition. That is, "combined" means not combined widgets, but combined # display of destination download stats the user sees self.combinedDestinationDisplay = DestinationDisplay( parent=self, rapidApp=self.rapidApp) self.combinedDestinationDisplayContainer = QPanelView( _("Projected Storage Use"), ) self.combinedDestinationDisplay.setObjectName( "combinedDestinationDisplay") self.combinedDestinationDisplayContainer.addWidget( self.combinedDestinationDisplay) self.combinedDestinationDisplayContainer.setObjectName( "combinedDestinationDisplayContainer") # Display storage space when photos and videos are being downloaded to different # partitions. # Also display the file system folder chooser for both destinations. self.photoDestinationDisplay = DestinationDisplay( menu=True, file_type=FileType.photo, parent=self, rapidApp=self.rapidApp) self.photoDestinationDisplay.setDestination( self.prefs.photo_download_folder) self.photoDestinationDisplay.setObjectName("photoDestinationDisplay") self.photoDestinationWidget = ComputerWidget( objectName="photoDestination", view=self.photoDestinationDisplay, fileSystemView=self.rapidApp.photoDestinationFSView, select_text=_("Select a destination folder"), ) self.videoDestinationDisplay = DestinationDisplay( menu=True, file_type=FileType.video, parent=self, rapidApp=self.rapidApp) self.videoDestinationDisplay.setObjectName("videoDestinationDisplay") self.videoDestinationDisplay.setDestination( self.prefs.video_download_folder) self.videoDestinationWidget = ComputerWidget( objectName="videoDestination", view=self.videoDestinationDisplay, fileSystemView=self.rapidApp.videoDestinationFSView, select_text=_("Select a destination folder"), ) self.photoDestination.addWidget(self.photoDestinationWidget) self.videoDestination.addWidget(self.videoDestinationWidget) for widget in (self.photoDestinationWidget, self.videoDestinationWidget, self.combinedDestinationDisplay): self.verticalScrollBarVisible.connect( widget.containerVerticalScrollBar) self.horizontalScrollBarVisible.connect( self.videoDestinationWidget.containerHorizontalScrollBar) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(self.splitter.handleWidth()) layout.addWidget(self.combinedDestinationDisplayContainer) layout.addWidget(self.photoDestination) self.photoDestinationContainer = QWidget() self.photoDestinationContainer.setObjectName( "photoDestinationContainer") self.photoDestinationContainer.setLayout(layout)
class DestinationPanel(ScrollAreaNoFrame): def __init__(self, parent) -> None: super().__init__(parent) assert parent is not None self.rapidApp = parent self.prefs = self.rapidApp.prefs self.setObjectName("destinationPanelScrollArea") self.splitter = QSplitter(parent=self) self.splitter.setObjectName("destinationPanelSplitter") self.splitter.setOrientation(Qt.Vertical) self.createDestinationViews() self.splitter.addWidget(self.photoDestinationContainer) self.splitter.addWidget(self.videoDestination) self.splitter.setCollapsible(0, False) self.splitter.setCollapsible(1, False) self.setWidget(self.splitter) self.setWidgetResizable(True) def createDestinationViews(self) -> None: """ Create the widgets that let the user choose where to download photos and videos to, and that show them how much storage space there is available for their files. """ self.photoDestination = QPanelView(label=_("Photos"), ) self.photoDestination.setObjectName("photoDestinationPanelView") self.videoDestination = QPanelView(label=_("Videos"), ) self.videoDestination.setObjectName("videoDestinationPanelView") # Display storage space when photos and videos are being downloaded to the same # partition. That is, "combined" means not combined widgets, but combined # display of destination download stats the user sees self.combinedDestinationDisplay = DestinationDisplay( parent=self, rapidApp=self.rapidApp) self.combinedDestinationDisplayContainer = QPanelView( _("Projected Storage Use"), ) self.combinedDestinationDisplay.setObjectName( "combinedDestinationDisplay") self.combinedDestinationDisplayContainer.addWidget( self.combinedDestinationDisplay) self.combinedDestinationDisplayContainer.setObjectName( "combinedDestinationDisplayContainer") # Display storage space when photos and videos are being downloaded to different # partitions. # Also display the file system folder chooser for both destinations. self.photoDestinationDisplay = DestinationDisplay( menu=True, file_type=FileType.photo, parent=self, rapidApp=self.rapidApp) self.photoDestinationDisplay.setDestination( self.prefs.photo_download_folder) self.photoDestinationDisplay.setObjectName("photoDestinationDisplay") self.photoDestinationWidget = ComputerWidget( objectName="photoDestination", view=self.photoDestinationDisplay, fileSystemView=self.rapidApp.photoDestinationFSView, select_text=_("Select a destination folder"), ) self.videoDestinationDisplay = DestinationDisplay( menu=True, file_type=FileType.video, parent=self, rapidApp=self.rapidApp) self.videoDestinationDisplay.setObjectName("videoDestinationDisplay") self.videoDestinationDisplay.setDestination( self.prefs.video_download_folder) self.videoDestinationWidget = ComputerWidget( objectName="videoDestination", view=self.videoDestinationDisplay, fileSystemView=self.rapidApp.videoDestinationFSView, select_text=_("Select a destination folder"), ) self.photoDestination.addWidget(self.photoDestinationWidget) self.videoDestination.addWidget(self.videoDestinationWidget) for widget in (self.photoDestinationWidget, self.videoDestinationWidget, self.combinedDestinationDisplay): self.verticalScrollBarVisible.connect( widget.containerVerticalScrollBar) self.horizontalScrollBarVisible.connect( self.videoDestinationWidget.containerHorizontalScrollBar) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(self.splitter.handleWidth()) layout.addWidget(self.combinedDestinationDisplayContainer) layout.addWidget(self.photoDestination) self.photoDestinationContainer = QWidget() self.photoDestinationContainer.setObjectName( "photoDestinationContainer") self.photoDestinationContainer.setLayout(layout) def updateDestinationPanelViews( self, same_dev: bool, merge: bool, marked_summary: MarkedSummary, downloading_to: Optional[DefaultDict[int, Set[FileType]]] = None, ) -> bool: """ Updates the header bar and storage space view for the photo and video download destinations. :return True if destinations required for the download exist, and there is sufficient space on them, else False. """ size_photos_marked = marked_summary.size_photos_marked size_videos_marked = marked_summary.size_videos_marked marked = marked_summary.marked destinations_good = True if same_dev: files_to_display = DisplayingFilesOfType.photos_and_videos self.combinedDestinationDisplay.downloading_to = downloading_to self.combinedDestinationDisplay.setDestination( self.prefs.photo_download_folder) self.combinedDestinationDisplay.setDownloadAttributes( marked=marked, photos_size=size_photos_marked, videos_size=size_videos_marked, files_to_display=files_to_display, display_type=DestinationDisplayType.usage_only, merge=merge, ) display_type = DestinationDisplayType.folder_only self.combinedDestinationDisplayContainer.setVisible(True) destinations_good = ( self.combinedDestinationDisplay.sufficientSpaceAvailable()) else: files_to_display = DisplayingFilesOfType.photos display_type = DestinationDisplayType.folders_and_usage self.combinedDestinationDisplayContainer.setVisible(False) if self.prefs.photo_download_folder: self.photoDestinationDisplay.downloading_to = downloading_to self.photoDestinationDisplay.setDownloadAttributes( marked=marked, photos_size=size_photos_marked, videos_size=0, files_to_display=files_to_display, display_type=display_type, merge=merge, ) self.photoDestinationWidget.setViewVisible(True) if display_type == DestinationDisplayType.folders_and_usage: destinations_good = ( self.photoDestinationDisplay.sufficientSpaceAvailable()) else: # Photo download folder was invalid or simply not yet set self.photoDestinationWidget.setViewVisible(False) if size_photos_marked: destinations_good = False if not same_dev: files_to_display = DisplayingFilesOfType.videos if self.prefs.video_download_folder: self.videoDestinationDisplay.downloading_to = downloading_to self.videoDestinationDisplay.setDownloadAttributes( marked=marked, photos_size=0, videos_size=size_videos_marked, files_to_display=files_to_display, display_type=display_type, merge=merge, ) self.videoDestinationWidget.setViewVisible(True) if display_type == DestinationDisplayType.folders_and_usage: destinations_good = ( self.videoDestinationDisplay.sufficientSpaceAvailable() and destinations_good) else: # Video download folder was invalid or simply not yet set self.videoDestinationWidget.setViewVisible(False) if size_videos_marked: destinations_good = False return destinations_good