34 from urllib.parse
import urlparse
38 from PyQt5.QtWidgets import QTreeView, QMessageBox, QAbstractItemView, QMenu, QSizePolicy
41 from classes.query
import File
42 from classes.logger
import log
43 from classes.app
import get_app
44 from windows.models.files_model
import FilesModel
49 import simplejson
as json
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.actionThumbnailView)
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()))
124 path = file[
"path"].lower()
126 if path.endswith((
".jpg",
".jpeg",
".png",
".bmp",
".svg",
".thm",
".gif",
".bmp",
".pgm",
".tif",
".tiff")):
132 path, filename = os.path.split(filepath)
139 file = File.get(path=filepath)
146 clip = openshot.Clip(filepath)
150 reader = clip.Reader()
151 file_data = json.loads(reader.Json())
154 if file_data[
"has_video"]
and not self.
is_image(file_data):
155 file_data[
"media_type"] =
"video" 156 elif file_data[
"has_video"]
and self.
is_image(file_data):
157 file_data[
"media_type"] =
"image" 158 elif file_data[
"has_audio"]
and not file_data[
"has_video"]:
159 file_data[
"media_type"] =
"audio" 163 file.data = file_data
167 if image_seq_details:
169 folder_path = image_seq_details[
"folder_path"]
170 file_name = image_seq_details[
"file_path"]
171 base_name = image_seq_details[
"base_name"]
172 fixlen = image_seq_details[
"fixlen"]
173 digits = image_seq_details[
"digits"]
174 extension = image_seq_details[
"extension"]
179 zero_pattern =
"%%0%sd" % digits
182 pattern =
"%s%s.%s" % (base_name, zero_pattern, extension)
185 (parentPath, folderName) = os.path.split(folder_path)
188 file.data[
"name"] =
"%s (%s)" % (folderName, pattern)
191 image_seq = openshot.Clip(os.path.join(folder_path, pattern))
194 file.data[
"path"] = os.path.join(folder_path, pattern)
195 file.data[
"media_type"] =
"video" 196 file.data[
"duration"] = image_seq.Reader().info.duration
197 file.data[
"video_length"] = image_seq.Reader().info.video_length
206 msg.setText(_(
"{} is not a valid video, audio, or image file.".
format(filename)))
215 (dirName, fileName) = os.path.split(file_path)
216 extensions = [
"png",
"jpg",
"jpeg",
"gif",
"tif"]
217 match = re.findall(
r"(.*[^\d])?(0*)(\d+)\.(%s)" %
"|".join(extensions), fileName, re.I)
224 base_name = match[0][0]
225 fixlen = match[0][1] >
"" 226 number = int(match[0][2])
227 digits = len(match[0][1] + match[0][2])
228 extension = match[0][3]
230 full_base_name = os.path.join(dirName, base_name)
233 fixlen = fixlen
or not (glob.glob(
"%s%s.%s" % (full_base_name,
"[0-9]" * (digits + 1), extension))
235 "%s%s.%s" % (full_base_name,
"[0-9]" * ((digits - 1)
if digits > 1
else 3), extension)))
238 for x
in range(max(0, number - 100), min(number + 101, 50000)):
239 if x != number
and os.path.exists(
"%s%s.%s" % (
240 full_base_name, str(x).rjust(digits,
"0")
if fixlen
else str(x), extension)):
247 log.info(
'Prompt user to import image sequence')
249 self.ignore_image_sequence_paths.append(dirName)
255 ret = QMessageBox.question(self, _(
"Import Image Sequence"), _(
"Would you like to import %s as an image sequence?") % fileName, QMessageBox.No | QMessageBox.Yes)
256 if ret == QMessageBox.Yes:
258 parameters = {
"file_path":file_path,
"folder_path":dirName,
"base_name":base_name,
"fixlen":fixlen,
"digits":digits,
"extension":extension}
271 for uri
in event.mimeData().urls():
272 file_url = urlparse(uri.toString())
273 if file_url.scheme ==
"file":
274 filepath = file_url.path
275 if filepath[0] ==
"/" and ":" in filepath:
276 filepath = filepath[1:]
277 if os.path.exists(filepath.encode(
'UTF-8'))
and os.path.isfile(filepath.encode(
'UTF-8')):
278 log.info(
'Adding file: {}'.
format(filepath))
284 self.win.filesFilter.setText(
"")
288 if self.win.filesFilter.text() ==
"":
289 self.win.actionFilesClear.setEnabled(
False)
291 self.win.actionFilesClear.setEnabled(
True)
295 self.files_model.update_model()
300 if type(self) == FilesTreeView:
308 self.resizeColumnToContents(2)
309 self.resizeColumnToContents(1)
312 log.info(
'currentChanged')
322 file_id = self.files_model.model.item(item.row(), 5).text()
323 name = self.files_model.model.item(item.row(), 1).text()
324 tags = self.files_model.model.item(item.row(), 2).text()
327 f = File.get(id=file_id)
328 if name != f.data[
"path"]:
329 f.data[
"name"] = name
332 if "tags" in f.data.keys():
333 if tags != f.data[
"tags"]:
334 f.data[
"tags"] = tags
336 f.data[
"tags"] = tags
339 self.files_model.ignore_update_signal =
True 345 self.files_model.ignore_update_signal =
False 349 QTreeView.__init__(self, *args)
358 self.setAcceptDrops(
True)
359 self.setDragEnabled(
True)
360 self.setDropIndicatorShown(
True)
364 self.setModel(self.files_model.model)
365 self.setIconSize(QSize(75, 62))
366 self.setIndentation(0)
367 self.setSelectionBehavior(QTreeView.SelectRows)
368 self.setSelectionMode(QAbstractItemView.ExtendedSelection)
369 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
370 self.setWordWrap(
True)
371 self.setStyleSheet(
'QTreeView::item { padding-top: 2px; }')
381 app.window.actionFilesClear.triggered.connect(self.
clear_filter)
382 self.files_model.model.itemChanged.connect(self.
value_updated)
def startDrag(self, event)
Override startDrag method to display custom icon.
def get_app()
Returns the current QApplication instance of OpenShot.
def contextMenuEvent(self, event)
def dropEvent(self, event)
A TreeView QWidget used on the main window.
def refresh_columns(self)
Resize and hide certain columns.
def updateSelection(self)
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)
def add_file(self, filepath)
def dragEnterEvent(self, event)
def value_updated(self, item)
Name or tags updated.
def dragMoveEvent(self, event)
def resize_contents(self)
ignore_image_sequence_paths