33 from urllib.parse
import urlparse
38 from PyQt5.QtWidgets import QListView, QMessageBox, QAbstractItemView, QMenu
40 from classes.app
import get_app
41 from classes.logger
import log
42 from classes.query
import File
43 from windows.models.files_model
import FilesModel
48 import simplejson
as json
57 log.info(
'updateSelection')
60 self.
selected = self.selectionModel().selectedIndexes()
64 self.win.selected_files = []
66 selected_row = self.files_model.model.itemFromIndex(selection).row()
67 if selected_row
not in rows:
68 self.win.selected_files.append(self.files_model.model.item(selected_row, 5).text())
69 rows.append(selected_row)
77 app.context_menu_object =
"files" 81 menu.addAction(self.win.actionImportFiles)
85 menu.addAction(self.win.actionFile_Properties)
86 menu.addAction(self.win.actionPreview_File)
87 menu.addAction(self.win.actionSplitClip)
88 menu.addAction(self.win.actionAdd_to_Timeline)
91 menu.addAction(self.win.actionRemove_from_Project)
93 menu.addAction(self.win.actionDetailsView)
96 menu.exec_(QCursor.pos())
100 if event.mimeData().hasUrls():
101 event.setDropAction(Qt.CopyAction)
109 selected_row = self.files_model.model.itemFromIndex(self.selectionModel().selectedIndexes()[0]).row()
110 icon = self.files_model.model.item(selected_row, 0).icon()
114 drag.setMimeData(self.files_model.model.mimeData(self.selectionModel().selectedIndexes()))
125 path = file[
"path"].lower()
127 if path.endswith((
".jpg",
".jpeg",
".png",
".bmp",
".svg",
".thm",
".gif",
".bmp",
".pgm",
".tif",
".tiff")):
133 path, filename = os.path.split(filepath)
140 file = File.get(path=filepath)
147 clip = openshot.Clip(filepath)
151 reader = clip.Reader()
152 file_data = json.loads(reader.Json())
155 if file_data[
"has_video"]
and not self.
is_image(file_data):
156 file_data[
"media_type"] =
"video" 157 elif file_data[
"has_video"]
and self.
is_image(file_data):
158 file_data[
"media_type"] =
"image" 159 elif file_data[
"has_audio"]
and not file_data[
"has_video"]:
160 file_data[
"media_type"] =
"audio" 164 file.data = file_data
168 if image_seq_details:
170 folder_path = image_seq_details[
"folder_path"]
171 file_name = image_seq_details[
"file_path"]
172 base_name = image_seq_details[
"base_name"]
173 fixlen = image_seq_details[
"fixlen"]
174 digits = image_seq_details[
"digits"]
175 extension = image_seq_details[
"extension"]
180 zero_pattern =
"%%0%sd" % digits
183 pattern =
"%s%s.%s" % (base_name, zero_pattern, extension)
186 (parentPath, folderName) = os.path.split(folder_path)
189 file.data[
"name"] =
"%s (%s)" % (folderName, pattern)
192 image_seq = openshot.Clip(os.path.join(folder_path, pattern))
195 file.data[
"path"] = os.path.join(folder_path, pattern)
196 file.data[
"media_type"] =
"video" 197 file.data[
"duration"] = image_seq.Reader().info.duration
198 file.data[
"video_length"] = image_seq.Reader().info.video_length
207 msg.setText(_(
"{} is not a valid video, audio, or image file.".
format(filename)))
216 (dirName, fileName) = os.path.split(file_path)
217 extensions = [
"png",
"jpg",
"jpeg",
"gif",
"tif"]
218 match = re.findall(
r"(.*[^\d])?(0*)(\d+)\.(%s)" %
"|".join(extensions), fileName, re.I)
225 base_name = match[0][0]
226 fixlen = match[0][1] >
"" 227 number = int(match[0][2])
228 digits = len(match[0][1] + match[0][2])
229 extension = match[0][3]
231 full_base_name = os.path.join(dirName, base_name)
234 fixlen = fixlen
or not (glob.glob(
"%s%s.%s" % (full_base_name,
"[0-9]" * (digits + 1), extension))
236 "%s%s.%s" % (full_base_name,
"[0-9]" * ((digits - 1)
if digits > 1
else 3), extension)))
239 for x
in range(max(0, number - 100), min(number + 101, 50000)):
240 if x != number
and os.path.exists(
"%s%s.%s" % (
241 full_base_name, str(x).rjust(digits,
"0")
if fixlen
else str(x), extension)):
248 log.info(
'Prompt user to import image sequence')
250 self.ignore_image_sequence_paths.append(dirName)
256 ret = QMessageBox.question(self, _(
"Import Image Sequence"), _(
"Would you like to import %s as an image sequence?") % fileName, QMessageBox.No | QMessageBox.Yes)
257 if ret == QMessageBox.Yes:
259 parameters = {
"file_path":file_path,
"folder_path":dirName,
"base_name":base_name,
"fixlen":fixlen,
"digits":digits,
"extension":extension}
272 for uri
in event.mimeData().urls():
273 file_url = urlparse(uri.toString())
274 if file_url.scheme ==
"file":
275 filepath = file_url.path
276 if filepath[0] ==
"/" and ":" in filepath:
277 filepath = filepath[1:]
278 if os.path.exists(filepath.encode(
'UTF-8'))
and os.path.isfile(filepath.encode(
'UTF-8')):
279 log.info(
'Adding file: {}'.
format(filepath))
285 self.win.filesFilter.setText(
"")
289 if self.win.filesFilter.text() ==
"":
290 self.win.actionFilesClear.setEnabled(
False)
292 self.win.actionFilesClear.setEnabled(
True)
296 self.files_model.update_model()
299 log.info(
'currentChanged')
307 QListView.__init__(self, *args)
314 self.setAcceptDrops(
True)
315 self.setDragEnabled(
True)
316 self.setDropIndicatorShown(
True)
321 self.setModel(self.files_model.model)
322 self.setIconSize(QSize(131, 108))
323 self.setViewMode(QListView.IconMode)
324 self.setResizeMode(QListView.Adjust)
325 self.setSelectionMode(QAbstractItemView.ExtendedSelection)
326 self.setUniformItemSizes(
True)
327 self.setWordWrap(
True)
328 self.setStyleSheet(
'QListView::item { padding-top: 2px; }')
336 app.window.actionFilesClear.triggered.connect(self.
clear_filter)
def get_app()
Returns the current QApplication instance of OpenShot.
def add_file(self, filepath)
def resize_contents(self)
def updateSelection(self)
def dragMoveEvent(self, event)
def get_image_sequence_details(self, file_path)
Inspect a file path and determine if this is an image sequence.
def currentChanged(self, selected, deselected)
A ListView QWidget used on the main window.
def startDrag(self, event)
Override startDrag method to display custom icon.
ignore_image_sequence_paths
def dragEnterEvent(self, event)
def dropEvent(self, event)
def contextMenuEvent(self, event)