34 from urllib.parse
import urlparse
39 from PyQt5.QtWidgets import QListView, QMessageBox, QAbstractItemView, QMenu
41 from classes.app
import get_app
42 from classes.logger
import log
43 from classes.query
import File
44 from windows.models.files_model
import FilesModel
49 import simplejson
as json
58 log.info(
'updateSelection')
61 self.
selected = self.selectionModel().selectedIndexes()
65 self.
win.selected_files = []
67 selected_row = self.
files_model.model.itemFromIndex(selection).row()
68 if selected_row
not in rows:
69 self.
win.selected_files.append(self.
files_model.model.item(selected_row, 5).text())
70 rows.append(selected_row)
78 app.context_menu_object =
"files" 82 menu.addAction(self.
win.actionImportFiles)
83 menu.addAction(self.
win.actionDetailsView)
89 selected_file_id = self.
win.selected_files[0]
90 file = File.get(id=selected_file_id)
91 if file
and file.data.get(
"path").endswith(
".svg"):
92 menu.addAction(self.
win.actionEditTitle)
93 menu.addAction(self.
win.actionDuplicateTitle)
96 menu.addAction(self.
win.actionPreview_File)
97 menu.addAction(self.
win.actionSplitClip)
98 menu.addAction(self.
win.actionAdd_to_Timeline)
99 menu.addAction(self.
win.actionFile_Properties)
101 menu.addAction(self.
win.actionRemove_from_Project)
105 menu.exec_(QCursor.pos())
109 if event.mimeData().hasUrls():
110 event.setDropAction(Qt.CopyAction)
118 selected_row = self.
files_model.model.itemFromIndex(self.selectionModel().selectedIndexes()[0]).row()
119 icon = self.
files_model.model.item(selected_row, 0).icon()
123 drag.setMimeData(self.
files_model.model.mimeData(self.selectionModel().selectedIndexes()))
134 path = file[
"path"].lower()
136 if path.endswith((
".jpg",
".jpeg",
".png",
".bmp",
".svg",
".thm",
".gif",
".bmp",
".pgm",
".tif",
".tiff")):
142 path, filename = os.path.split(filepath)
149 file = File.get(path=filepath)
156 clip = openshot.Clip(filepath)
160 reader = clip.Reader()
161 file_data = json.loads(reader.Json())
164 if file_data[
"has_video"]
and not self.
is_image(file_data):
165 file_data[
"media_type"] =
"video" 166 elif file_data[
"has_video"]
and self.
is_image(file_data):
167 file_data[
"media_type"] =
"image" 168 elif file_data[
"has_audio"]
and not file_data[
"has_video"]:
169 file_data[
"media_type"] =
"audio" 173 file.data = file_data
177 if image_seq_details:
179 folder_path = image_seq_details[
"folder_path"]
180 file_name = image_seq_details[
"file_path"]
181 base_name = image_seq_details[
"base_name"]
182 fixlen = image_seq_details[
"fixlen"]
183 digits = image_seq_details[
"digits"]
184 extension = image_seq_details[
"extension"]
189 zero_pattern =
"%%0%sd" % digits
192 pattern =
"%s%s.%s" % (base_name, zero_pattern, extension)
195 (parentPath, folderName) = os.path.split(folder_path)
198 file.data[
"name"] =
"%s (%s)" % (folderName, pattern)
201 image_seq = openshot.Clip(os.path.join(folder_path, pattern))
204 file.data[
"path"] = os.path.join(folder_path, pattern)
205 file.data[
"media_type"] =
"video" 206 file.data[
"duration"] = image_seq.Reader().info.duration
207 file.data[
"video_length"] = image_seq.Reader().info.video_length
216 msg.setText(_(
"{} is not a valid video, audio, or image file.".format(filename)))
225 (dirName, fileName) = os.path.split(file_path)
226 extensions = [
"png",
"jpg",
"jpeg",
"gif",
"tif"]
227 match = re.findall(
r"(.*[^\d])?(0*)(\d+)\.(%s)" %
"|".join(extensions), fileName, re.I)
234 base_name = match[0][0]
235 fixlen = match[0][1] >
"" 236 number = int(match[0][2])
237 digits = len(match[0][1] + match[0][2])
238 extension = match[0][3]
240 full_base_name = os.path.join(dirName, base_name)
243 fixlen = fixlen
or not (glob.glob(
"%s%s.%s" % (full_base_name,
"[0-9]" * (digits + 1), extension))
245 "%s%s.%s" % (full_base_name,
"[0-9]" * ((digits - 1)
if digits > 1
else 3), extension)))
248 for x
in range(max(0, number - 100), min(number + 101, 50000)):
249 if x != number
and os.path.exists(
"%s%s.%s" % (
250 full_base_name, str(x).rjust(digits,
"0")
if fixlen
else str(x), extension)):
257 log.info(
'Prompt user to import image sequence')
265 ret = QMessageBox.question(self, _(
"Import Image Sequence"), _(
"Would you like to import %s as an image sequence?") % fileName, QMessageBox.No | QMessageBox.Yes)
266 if ret == QMessageBox.Yes:
268 parameters = {
"file_path":file_path,
"folder_path":dirName,
"base_name":base_name,
"fixlen":fixlen,
"digits":digits,
"extension":extension}
280 for uri
in event.mimeData().urls():
281 log.info(
'Processing drop event for {}'.format(uri))
282 filepath = uri.toLocalFile()
283 if os.path.exists(filepath)
and os.path.isfile(filepath):
284 log.info(
'Adding file: {}'.format(filepath))
290 self.
win.filesFilter.setText(
"")
294 if self.
win.filesFilter.text() ==
"":
295 self.
win.actionFilesClear.setEnabled(
False)
297 self.
win.actionFilesClear.setEnabled(
True)
304 log.info(
'currentChanged')
320 QListView.__init__(self, *args)
327 self.setAcceptDrops(
True)
328 self.setDragEnabled(
True)
329 self.setDropIndicatorShown(
True)
335 self.setIconSize(QSize(131, 108))
336 self.setGridSize(QSize(102, 92))
337 self.setViewMode(QListView.IconMode)
338 self.setResizeMode(QListView.Adjust)
339 self.setSelectionMode(QAbstractItemView.ExtendedSelection)
340 self.setUniformItemSizes(
True)
341 self.setWordWrap(
False)
342 self.setTextElideMode(Qt.ElideRight)
343 self.setStyleSheet(
'QListView::item { padding-top: 2px; }')
351 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 prepare_for_delete(self)
Remove signal handlers and prepare for deletion.
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)