From 7dacbc4a33fb253d57f5437ed65dcf30b4d8932b Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Sun, 16 Aug 2015 21:04:51 -0500 Subject: [PATCH] Code cleanup, PEP8 formatting, and removing unused imports. --- src/classes/timeline.py | 3 +- src/windows/models/blender_model.py | 262 +++++++++--------- src/windows/models/effects_model.py | 2 +- src/windows/models/files_model.py | 355 ++++++++++++------------- src/windows/models/properties_model.py | 10 +- src/windows/models/transition_model.py | 295 ++++++++++---------- 6 files changed, 455 insertions(+), 472 deletions(-) diff --git a/src/classes/timeline.py b/src/classes/timeline.py index 1c380eb78b..e4fb96f08d 100644 --- a/src/classes/timeline.py +++ b/src/classes/timeline.py @@ -25,11 +25,10 @@ along with OpenShot Library. If not, see . """ -import openshot # Python module for libopenshot (required video editing module installed separately) - from classes.updates import UpdateInterface from classes.logger import log from classes.app import get_app +import openshot # Python module for libopenshot (required video editing module installed separately) class TimelineSync(UpdateInterface): diff --git a/src/windows/models/blender_model.py b/src/windows/models/blender_model.py index b6f8c13d6a..510c69705d 100644 --- a/src/windows/models/blender_model.py +++ b/src/windows/models/blender_model.py @@ -26,140 +26,138 @@ """ import os -from urllib.parse import urlparse -from classes import updates +import xml.dom.minidom as xml + +from PyQt5.QtCore import Qt +from PyQt5.QtGui import * +from PyQt5.QtWidgets import QMessageBox +import openshot # Python module for libopenshot (required video editing module installed separately) + from classes import info from classes.logger import log -from classes.settings import SettingStore from classes.app import get_app -from PyQt5.QtCore import QMimeData, QSize, Qt, QCoreApplication, QPoint, QFileInfo -from PyQt5.QtGui import * -from PyQt5.QtWidgets import QTreeWidget, QApplication, QMessageBox, QTreeWidgetItem, QAbstractItemView -import xml.dom.minidom as xml -import openshot # Python module for libopenshot (required video editing module installed separately) + class BlenderModel(): - - def update_model(self, clear=True): - log.info("updating effects model.") - app = get_app() - proj = app.project - - # Get window to check filters - win = app.window - - # Clear all items - if clear: - self.model_paths = {} - self.model.clear() - - # Add Headers - self.model.setHorizontalHeaderLabels(["Thumb", "Name" ]) - - # get a list of files in the OpenShot /effects directory - effects_dir = os.path.join(info.PATH, "blender") - icons_dir = os.path.join(effects_dir, "icons") - - for file in os.listdir(effects_dir): - if os.path.isfile(os.path.join(effects_dir, file)) and ".xml" in file: - # Split path - path = os.path.join(effects_dir, file) - (fileBaseName, fileExtension)=os.path.splitext(path) - - # load xml effect file - xmldoc = xml.parse(path) - - # Get all attributes - title = xmldoc.getElementsByTagName("title")[0].childNodes[0].data - description = xmldoc.getElementsByTagName("description")[0].childNodes[0].data - icon_name = xmldoc.getElementsByTagName("icon")[0].childNodes[0].data - icon_path = os.path.join(icons_dir, icon_name) - category = xmldoc.getElementsByTagName("category")[0].childNodes[0].data - service = xmldoc.getElementsByTagName("service")[0].childNodes[0].data - - if not win.actionEffectsShowAll.isChecked(): - if win.actionEffectsShowVideo.isChecked(): - if not category == "Video": - continue # to next file, didn't match filter - elif win.actionEffectsShowAudio.isChecked(): - if not category == "Audio": - continue # to next file, didn't match filter - - if win.effectsFilter.text() != "": - if not win.effectsFilter.text().lower() in self.app._tr(title).lower() and not win.effectsFilter.text().lower() in self.app._tr(description).lower(): - continue - - # Generate thumbnail for file (if needed) - thumb_path = os.path.join(info.CACHE_PATH, icon_name) - - # Check if thumb exists - if not os.path.exists(thumb_path): - - try: - # Reload this reader - clip = openshot.Clip(icon_path) - reader = clip.Reader() - - # Open reader - reader.Open() - - # Determine scale of thumbnail - scale = 95.0 / reader.info.width - - # Save thumbnail - reader.GetFrame(0).Save(thumb_path, scale) - reader.Close() - - except: - # Handle exception - msg = QMessageBox() - msg.setText(app._tr("{} is not a valid image file.".format(filename))) - msg.exec_() - continue - - row = [] - - # Append thumbnail - col = QStandardItem() - col.setIcon(QIcon(thumb_path)) - col.setText(self.app._tr(title)) - col.setToolTip(self.app._tr(title)) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) - row.append(col) - - # Append Name - col = QStandardItem("Name") - col.setData(self.app._tr(title), Qt.DisplayRole) - col.setText(self.app._tr(title)) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) - row.append(col) - - # Append Path - col = QStandardItem("Path") - col.setData(path, Qt.DisplayRole) - col.setText(path) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) - row.append(col) - - # Append Service - col = QStandardItem("Service") - col.setData(service, Qt.DisplayRole) - col.setText(service) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) - row.append(col) - - # Append ROW to MODEL (if does not already exist in model) - if not path in self.model_paths: - self.model.appendRow(row) - self.model_paths[path] = path - - # Process events in QT (to keep the interface responsive) - app.processEvents() - - def __init__(self, *args): - - # Create standard model - self.app = get_app() - self.model = QStandardItemModel() - self.model.setColumnCount(4) - self.model_paths = {} + def update_model(self, clear=True): + log.info("updating effects model.") + app = get_app() + + # Get window to check filters + win = app.window + + # Clear all items + if clear: + self.model_paths = {} + self.model.clear() + + # Add Headers + self.model.setHorizontalHeaderLabels(["Thumb", "Name"]) + + # get a list of files in the OpenShot /effects directory + effects_dir = os.path.join(info.PATH, "blender") + icons_dir = os.path.join(effects_dir, "icons") + + for file in os.listdir(effects_dir): + if os.path.isfile(os.path.join(effects_dir, file)) and ".xml" in file: + # Split path + path = os.path.join(effects_dir, file) + (fileBaseName, fileExtension) = os.path.splitext(path) + + # load xml effect file + xmldoc = xml.parse(path) + + # Get all attributes + title = xmldoc.getElementsByTagName("title")[0].childNodes[0].data + description = xmldoc.getElementsByTagName("description")[0].childNodes[0].data + icon_name = xmldoc.getElementsByTagName("icon")[0].childNodes[0].data + icon_path = os.path.join(icons_dir, icon_name) + category = xmldoc.getElementsByTagName("category")[0].childNodes[0].data + service = xmldoc.getElementsByTagName("service")[0].childNodes[0].data + + if not win.actionEffectsShowAll.isChecked(): + if win.actionEffectsShowVideo.isChecked(): + if not category == "Video": + continue # to next file, didn't match filter + elif win.actionEffectsShowAudio.isChecked(): + if not category == "Audio": + continue # to next file, didn't match filter + + if win.effectsFilter.text() != "": + if not win.effectsFilter.text().lower() in self.app._tr(title).lower() and not win.effectsFilter.text().lower() in self.app._tr(description).lower(): + continue + + # Generate thumbnail for file (if needed) + thumb_path = os.path.join(info.CACHE_PATH, icon_name) + + # Check if thumb exists + if not os.path.exists(thumb_path): + + try: + # Reload this reader + clip = openshot.Clip(icon_path) + reader = clip.Reader() + + # Open reader + reader.Open() + + # Determine scale of thumbnail + scale = 95.0 / reader.info.width + + # Save thumbnail + reader.GetFrame(0).Save(thumb_path, scale) + reader.Close() + + except: + # Handle exception + msg = QMessageBox() + msg.setText(app._tr("{} is not a valid image file.".format(icon_path))) + msg.exec_() + continue + + row = [] + + # Append thumbnail + col = QStandardItem() + col.setIcon(QIcon(thumb_path)) + col.setText(self.app._tr(title)) + col.setToolTip(self.app._tr(title)) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) + row.append(col) + + # Append Name + col = QStandardItem("Name") + col.setData(self.app._tr(title), Qt.DisplayRole) + col.setText(self.app._tr(title)) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) + row.append(col) + + # Append Path + col = QStandardItem("Path") + col.setData(path, Qt.DisplayRole) + col.setText(path) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) + row.append(col) + + # Append Service + col = QStandardItem("Service") + col.setData(service, Qt.DisplayRole) + col.setText(service) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) + row.append(col) + + # Append ROW to MODEL (if does not already exist in model) + if not path in self.model_paths: + self.model.appendRow(row) + self.model_paths[path] = path + + # Process events in QT (to keep the interface responsive) + app.processEvents() + + def __init__(self, *args): + + # Create standard model + self.app = get_app() + self.model = QStandardItemModel() + self.model.setColumnCount(4) + self.model_paths = {} \ No newline at end of file diff --git a/src/windows/models/effects_model.py b/src/windows/models/effects_model.py index c01fa16ba6..42c64db31a 100644 --- a/src/windows/models/effects_model.py +++ b/src/windows/models/effects_model.py @@ -196,4 +196,4 @@ def __init__(self, *args): self.app = get_app() self.model = EffectsStandardItemModel() self.model.setColumnCount(5) - self.model_names = {} + self.model_names = {} \ No newline at end of file diff --git a/src/windows/models/files_model.py b/src/windows/models/files_model.py index d8fbfa63e0..34e1161407 100644 --- a/src/windows/models/files_model.py +++ b/src/windows/models/files_model.py @@ -27,197 +27,192 @@ """ import os -from urllib.parse import urlparse + +from PyQt5.QtCore import QMimeData, Qt +from PyQt5.QtGui import * +from PyQt5.QtWidgets import QMessageBox +import openshot # Python module for libopenshot (required video editing module installed separately) + from classes import updates from classes import info from classes.query import File from classes.logger import log -from classes.settings import SettingStore from classes.app import get_app -from PyQt5.QtCore import QMimeData, QSize, Qt, QCoreApplication, QPoint, QFileInfo -from PyQt5.QtGui import * -from PyQt5.QtWidgets import QTreeWidget, QApplication, QMessageBox, QTreeWidgetItem, QAbstractItemView -import openshot # Python module for libopenshot (required video editing module installed separately) try: import json except ImportError: import simplejson as json + class FileStandardItemModel(QStandardItemModel): - - def __init__(self, parent=None): - QStandardItemModel.__init__(self) - - def mimeData(self, indexes): - - # Create MimeData for drag operation - data = QMimeData() - - # Get list of all selected file ids - files = [] - for item in indexes: - selected_row = self.itemFromIndex(item).row() - files.append(self.item(selected_row, 4).text()) - data.setText(json.dumps(files)) - data.setHtml("clip") - - # Return Mimedata - return data - + def __init__(self, parent=None): + QStandardItemModel.__init__(self) + + def mimeData(self, indexes): + # Create MimeData for drag operation + data = QMimeData() + + # Get list of all selected file ids + files = [] + for item in indexes: + selected_row = self.itemFromIndex(item).row() + files.append(self.item(selected_row, 4).text()) + data.setText(json.dumps(files)) + data.setHtml("clip") + + # Return Mimedata + return data + class FilesModel(updates.UpdateInterface): - - # This method is invoked by the UpdateManager each time a change happens (i.e UpdateInterface) - def changed(self, action): - - # Something was changed in the 'files' list - if len(action.key) >= 1 and action.key[0].lower() == "files": - # Refresh project files model - if action.type == "insert": - # Don't clear the existing items if only inserting new things - self.update_model(clear=False) - else: - # Clear existing items - self.update_model(clear=True) - - def update_model(self, clear=True): - log.info("updating files model.") - app = get_app() - - # Get window to check filters - win = app.window - - # Clear all items - if clear: - self.model_ids = {} - self.model.clear() - - # Add Headers - self.model.setHorizontalHeaderLabels(["Thumb", "Name", "Type" ]) - - # Get list of files in project - files = File.filter() # get all files - - # add item for each file - for file in files: - path, filename = os.path.split(file.data["path"]) - - if not win.actionFilesShowAll.isChecked(): - if win.actionFilesShowVideo.isChecked(): - if not file.data["media_type"] == "video": - continue #to next file, didn't match filter - elif win.actionFilesShowAudio.isChecked(): - if not file.data["media_type"] == "audio": - continue #to next file, didn't match filter - elif win.actionFilesShowImage.isChecked(): - if not file.data["media_type"] == "image": - continue #to next file, didn't match filter - - if win.filesFilter.text() != "": - if not win.filesFilter.text().lower() in filename.lower(): - continue - - # Generate thumbnail for file (if needed) - if (file.data["media_type"] == "video" or file.data["media_type"] == "image"): - # Determine thumb path - thumb_path = os.path.join(info.THUMBNAIL_PATH, "{}.png".format(file.id)) - - # Check if thumb exists - if not os.path.exists(thumb_path): - - try: - # Convert path to the correct relative path (based on this folder) - file_path = file.absolute_path() - - # Reload this reader - clip = openshot.Clip(file_path) - reader = clip.Reader() - - # Open reader - reader.Open() - - # Determine if video overlay should be applied to thumbnail - overlay_path = "" - if file.data["media_type"] == "video": - overlay_path = os.path.join(info.IMAGES_PATH, "overlay.png") - - # Save thumbnail - reader.GetFrame(0).Thumbnail(thumb_path, 98, 64, os.path.join(info.IMAGES_PATH, "mask.png"), overlay_path, "#000", False) - reader.Close() - clip.Close() - - except: - # Handle exception - msg = QMessageBox() - msg.setText(app._tr("{} is not a valid video, audio, or image file.".format(filename))) - msg.exec_() - continue - - - else: - # Audio file - thumb_path = os.path.join(info.PATH, "images", "AudioThumbnail.png") - - - row = [] - - # Append thumbnail - col = QStandardItem() - col.setIcon(QIcon(thumb_path)) - col.setText((filename[:9] + '...') if len(filename) > 10 else filename) - col.setToolTip(filename) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) - row.append(col) - - # Append Filename - col = QStandardItem("Name") - col.setData(filename, Qt.DisplayRole) - col.setText((filename[:20] + '...') if len(filename) > 15 else filename) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) - row.append(col) - - # Append Media Type - col = QStandardItem("Type") - col.setData(file.data["media_type"], Qt.DisplayRole) - col.setText(file.data["media_type"]) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) - row.append(col) - - # Append Path - col = QStandardItem("Path") - col.setData(path, Qt.DisplayRole) - col.setText(path) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) - row.append(col) - - # Append ID - col = QStandardItem("ID") - col.setData(file.data["id"], Qt.DisplayRole) - col.setText(file.data["id"]) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) - row.append(col) - - # Append ROW to MODEL (if does not already exist in model) - if not file.data["id"] in self.model_ids: - self.model.appendRow(row) - self.model_ids[file.data["id"]] = file.data["id"] - - # Process events in QT (to keep the interface responsive) - app.processEvents() - - # Refresh view and filters (to hide or show this new item) - get_app().window.resize_contents() - - def __init__(self, *args): - - # Add self as listener to project data updates (undo/redo, as well as normal actions handled within this class all update the tree model) - app = get_app() - app.updates.add_listener(self) - - # Create standard model - self.model = FileStandardItemModel() - self.model.setColumnCount(5) - self.model_ids = {} - - + # This method is invoked by the UpdateManager each time a change happens (i.e UpdateInterface) + def changed(self, action): + + # Something was changed in the 'files' list + if len(action.key) >= 1 and action.key[0].lower() == "files": + # Refresh project files model + if action.type == "insert": + # Don't clear the existing items if only inserting new things + self.update_model(clear=False) + else: + # Clear existing items + self.update_model(clear=True) + + def update_model(self, clear=True): + log.info("updating files model.") + app = get_app() + + # Get window to check filters + win = app.window + + # Clear all items + if clear: + self.model_ids = {} + self.model.clear() + + # Add Headers + self.model.setHorizontalHeaderLabels(["Thumb", "Name", "Type"]) + + # Get list of files in project + files = File.filter() # get all files + + # add item for each file + for file in files: + path, filename = os.path.split(file.data["path"]) + + if not win.actionFilesShowAll.isChecked(): + if win.actionFilesShowVideo.isChecked(): + if not file.data["media_type"] == "video": + continue # to next file, didn't match filter + elif win.actionFilesShowAudio.isChecked(): + if not file.data["media_type"] == "audio": + continue # to next file, didn't match filter + elif win.actionFilesShowImage.isChecked(): + if not file.data["media_type"] == "image": + continue # to next file, didn't match filter + + if win.filesFilter.text() != "": + if not win.filesFilter.text().lower() in filename.lower(): + continue + + # Generate thumbnail for file (if needed) + if (file.data["media_type"] == "video" or file.data["media_type"] == "image"): + # Determine thumb path + thumb_path = os.path.join(info.THUMBNAIL_PATH, "{}.png".format(file.id)) + + # Check if thumb exists + if not os.path.exists(thumb_path): + + try: + # Convert path to the correct relative path (based on this folder) + file_path = file.absolute_path() + + # Reload this reader + clip = openshot.Clip(file_path) + reader = clip.Reader() + + # Open reader + reader.Open() + + # Determine if video overlay should be applied to thumbnail + overlay_path = "" + if file.data["media_type"] == "video": + overlay_path = os.path.join(info.IMAGES_PATH, "overlay.png") + + # Save thumbnail + reader.GetFrame(0).Thumbnail(thumb_path, 98, 64, os.path.join(info.IMAGES_PATH, "mask.png"), overlay_path, "#000", False) + reader.Close() + clip.Close() + + except: + # Handle exception + msg = QMessageBox() + msg.setText(app._tr("{} is not a valid video, audio, or image file.".format(filename))) + msg.exec_() + continue + + + else: + # Audio file + thumb_path = os.path.join(info.PATH, "images", "AudioThumbnail.png") + + row = [] + + # Append thumbnail + col = QStandardItem() + col.setIcon(QIcon(thumb_path)) + col.setText((filename[:9] + '...') if len(filename) > 10 else filename) + col.setToolTip(filename) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) + row.append(col) + + # Append Filename + col = QStandardItem("Name") + col.setData(filename, Qt.DisplayRole) + col.setText((filename[:20] + '...') if len(filename) > 15 else filename) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) + row.append(col) + + # Append Media Type + col = QStandardItem("Type") + col.setData(file.data["media_type"], Qt.DisplayRole) + col.setText(file.data["media_type"]) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) + row.append(col) + + # Append Path + col = QStandardItem("Path") + col.setData(path, Qt.DisplayRole) + col.setText(path) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) + row.append(col) + + # Append ID + col = QStandardItem("ID") + col.setData(file.data["id"], Qt.DisplayRole) + col.setText(file.data["id"]) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) + row.append(col) + + # Append ROW to MODEL (if does not already exist in model) + if not file.data["id"] in self.model_ids: + self.model.appendRow(row) + self.model_ids[file.data["id"]] = file.data["id"] + + # Process events in QT (to keep the interface responsive) + app.processEvents() + + # Refresh view and filters (to hide or show this new item) + get_app().window.resize_contents() + + def __init__(self, *args): + + # Add self as listener to project data updates (undo/redo, as well as normal actions handled within this class all update the tree model) + app = get_app() + app.updates.add_listener(self) + + # Create standard model + self.model = FileStandardItemModel() + self.model.setColumnCount(5) + self.model_ids = {} \ No newline at end of file diff --git a/src/windows/models/properties_model.py b/src/windows/models/properties_model.py index 05510d6c59..611d67b602 100644 --- a/src/windows/models/properties_model.py +++ b/src/windows/models/properties_model.py @@ -135,8 +135,8 @@ def update_frame(self, frame_number): requested_time = float(frame_number - 1) / fps_float # Determine the frame needed for this clip (based on the position on the timeline) - time_diff = (requested_time - clip.Position()) + clip.Start(); - self.frame_number = int(time_diff * fps_float) + 1; + time_diff = (requested_time - clip.Position()) + clip.Start() + self.frame_number = int(time_diff * fps_float) + 1 # Calculate biggest and smallest possible frames min_frame_number = int((clip.Start() * fps_float)) + 1 @@ -335,10 +335,6 @@ def update_model(self, filter=""): if filter and filter.lower() not in name.lower(): continue - # Hide the following fields - if label == "hash": - continue - # Insert new data into model, or update existing values row = [] if self.new_item: @@ -482,4 +478,4 @@ def __init__(self, parent, *args): self.model.itemChanged.connect(self.value_updated) # Add self as listener to project data updates (used to update the timeline) - get_app().updates.add_listener(self) + get_app().updates.add_listener(self) \ No newline at end of file diff --git a/src/windows/models/transition_model.py b/src/windows/models/transition_model.py index d2efd6ee44..e497bdb48c 100644 --- a/src/windows/models/transition_model.py +++ b/src/windows/models/transition_model.py @@ -26,164 +26,159 @@ """ import os -from urllib.parse import urlparse -from classes import updates + +from PyQt5.QtCore import QMimeData, Qt +from PyQt5.QtGui import * +from PyQt5.QtWidgets import QMessageBox +import openshot # Python module for libopenshot (required video editing module installed separately) + from classes import info from classes.logger import log -from classes.settings import SettingStore from classes.app import get_app -from PyQt5.QtCore import QMimeData, QSize, Qt, QCoreApplication, QPoint, QFileInfo -from PyQt5.QtGui import * -from PyQt5.QtWidgets import QTreeWidget, QApplication, QMessageBox, QTreeWidgetItem, QAbstractItemView -import openshot # Python module for libopenshot (required video editing module installed separately) try: import json except ImportError: import simplejson as json + class TransitionStandardItemModel(QStandardItemModel): - - def __init__(self, parent=None): - QStandardItemModel.__init__(self) - - def mimeData(self, indexes): - - # Create MimeData for drag operation - data = QMimeData() - - # Get list of all selected file ids - files = [] - for item in indexes: - selected_row = self.itemFromIndex(item).row() - files.append(self.item(selected_row, 3).text()) - data.setText(json.dumps(files)) - data.setHtml("transition") - - # Return Mimedata - return data - + def __init__(self, parent=None): + QStandardItemModel.__init__(self) + + def mimeData(self, indexes): + # Create MimeData for drag operation + data = QMimeData() + + # Get list of all selected file ids + files = [] + for item in indexes: + selected_row = self.itemFromIndex(item).row() + files.append(self.item(selected_row, 3).text()) + data.setText(json.dumps(files)) + data.setHtml("transition") + + # Return Mimedata + return data + + class TransitionsModel(): - - def update_model(self, clear=True): - log.info("updating transitions model.") - app = get_app() - proj = app.project - - # Get window to check filters - win = app.window - - # Clear all items - if clear: - self.model_paths = {} - self.model.clear() - - # Add Headers - self.model.setHorizontalHeaderLabels(["Thumb", "Name" ]) - - # get a list of files in the OpenShot /transitions directory - transitions_dir = os.path.join(info.PATH, "transitions") - common_dir = os.path.join(transitions_dir, "common") - extra_dir = os.path.join(transitions_dir, "extra") - transition_groups = [ { "type" : "common", "dir" : common_dir, "files" : os.listdir(common_dir) }, - { "type" : "extra", "dir" : extra_dir, "files" : os.listdir(extra_dir) } ] - - for group in transition_groups: - type = group["type"] - dir = group["dir"] - files = group["files"] - - for filename in sorted(files): - path = os.path.join(dir, filename) - (fileBaseName, fileExtension)=os.path.splitext(filename) - - # Skip hidden files (such as .DS_Store, etc...) - if filename[0] == "." or "thumbs.db" in filename.lower(): - continue - - # get name of transition - trans_name = fileBaseName.replace("_", " ").capitalize() - - if not win.actionTransitionsShowAll.isChecked(): - if win.actionTransitionsShowCommon.isChecked(): - if not type == "common": - continue # to next file, didn't match filter - - if win.transitionsFilter.text() != "": - if not win.transitionsFilter.text().lower() in self.app._tr(trans_name).lower(): - continue - - # Generate thumbnail for file (if needed) - thumb_path = os.path.join(info.CACHE_PATH, "{}.png".format(fileBaseName)) - - # Check if thumb exists - if not os.path.exists(thumb_path): - - try: - # Reload this reader - clip = openshot.Clip(path) - reader = clip.Reader() - - # Open reader - reader.Open() - - # Save thumbnail - reader.GetFrame(0).Thumbnail(thumb_path, 98, 64, os.path.join(info.IMAGES_PATH, "mask.png"), "", "#000", True) - reader.Close() - clip.Close() - - except: - # Handle exception - msg = QMessageBox() - msg.setText(app._tr("{} is not a valid image file.".format(filename))) - msg.exec_() - continue - - row = [] - - # Append thumbnail - col = QStandardItem() - col.setIcon(QIcon(thumb_path)) - col.setText(self.app._tr(trans_name)) - col.setToolTip(self.app._tr(trans_name)) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) - row.append(col) - - # Append Filename - col = QStandardItem("Name") - col.setData(self.app._tr(trans_name), Qt.DisplayRole) - col.setText(self.app._tr(trans_name)) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) - row.append(col) - - # Append Media Type - col = QStandardItem("Type") - col.setData(type, Qt.DisplayRole) - col.setText(type) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) - row.append(col) - - # Append Path - col = QStandardItem("Path") - col.setData(path, Qt.DisplayRole) - col.setText(path) - col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) - row.append(col) - - # Append ROW to MODEL (if does not already exist in model) - if not path in self.model_paths: - self.model.appendRow(row) - self.model_paths[path] = path - - # Process events in QT (to keep the interface responsive) - app.processEvents() - - def __init__(self, *args): - - # Create standard model - self.app = get_app() - self.model = TransitionStandardItemModel() - self.model.setColumnCount(4) - self.model_paths = {} - - + def update_model(self, clear=True): + log.info("updating transitions model.") + app = get_app() + + # Get window to check filters + win = app.window + + # Clear all items + if clear: + self.model_paths = {} + self.model.clear() + + # Add Headers + self.model.setHorizontalHeaderLabels(["Thumb", "Name"]) + + # get a list of files in the OpenShot /transitions directory + transitions_dir = os.path.join(info.PATH, "transitions") + common_dir = os.path.join(transitions_dir, "common") + extra_dir = os.path.join(transitions_dir, "extra") + transition_groups = [{"type": "common", "dir": common_dir, "files": os.listdir(common_dir)}, + {"type": "extra", "dir": extra_dir, "files": os.listdir(extra_dir)}] + + for group in transition_groups: + type = group["type"] + dir = group["dir"] + files = group["files"] + + for filename in sorted(files): + path = os.path.join(dir, filename) + (fileBaseName, fileExtension) = os.path.splitext(filename) + + # Skip hidden files (such as .DS_Store, etc...) + if filename[0] == "." or "thumbs.db" in filename.lower(): + continue + + # get name of transition + trans_name = fileBaseName.replace("_", " ").capitalize() + + if not win.actionTransitionsShowAll.isChecked(): + if win.actionTransitionsShowCommon.isChecked(): + if not type == "common": + continue # to next file, didn't match filter + + if win.transitionsFilter.text() != "": + if not win.transitionsFilter.text().lower() in self.app._tr(trans_name).lower(): + continue + + # Generate thumbnail for file (if needed) + thumb_path = os.path.join(info.CACHE_PATH, "{}.png".format(fileBaseName)) + + # Check if thumb exists + if not os.path.exists(thumb_path): + + try: + # Reload this reader + clip = openshot.Clip(path) + reader = clip.Reader() + + # Open reader + reader.Open() + + # Save thumbnail + reader.GetFrame(0).Thumbnail(thumb_path, 98, 64, os.path.join(info.IMAGES_PATH, "mask.png"), "", "#000", True) + reader.Close() + clip.Close() + + except: + # Handle exception + msg = QMessageBox() + msg.setText(app._tr("{} is not a valid image file.".format(filename))) + msg.exec_() + continue + + row = [] + + # Append thumbnail + col = QStandardItem() + col.setIcon(QIcon(thumb_path)) + col.setText(self.app._tr(trans_name)) + col.setToolTip(self.app._tr(trans_name)) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) + row.append(col) + + # Append Filename + col = QStandardItem("Name") + col.setData(self.app._tr(trans_name), Qt.DisplayRole) + col.setText(self.app._tr(trans_name)) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) + row.append(col) + + # Append Media Type + col = QStandardItem("Type") + col.setData(type, Qt.DisplayRole) + col.setText(type) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) + row.append(col) + + # Append Path + col = QStandardItem("Path") + col.setData(path, Qt.DisplayRole) + col.setText(path) + col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled) + row.append(col) + + # Append ROW to MODEL (if does not already exist in model) + if not path in self.model_paths: + self.model.appendRow(row) + self.model_paths[path] = path + + # Process events in QT (to keep the interface responsive) + app.processEvents() + + def __init__(self, *args): + + # Create standard model + self.app = get_app() + self.model = TransitionStandardItemModel() + self.model.setColumnCount(4) + self.model_paths = {} \ No newline at end of file