OpenShot Video Editor  2.0.0
titles_model.py
Go to the documentation of this file.
1 ##
2 #
3 # @file
4 # @brief This file contains the titles model, used by the title editor window
5 # @author Jonathan Thomas <jonathan@openshot.org>
6 #
7 # @section LICENSE
8 #
9 # Copyright (c) 2008-2018 OpenShot Studios, LLC
10 # (http://www.openshotstudios.com). This file is part of
11 # OpenShot Video Editor (http://www.openshot.org), an open-source project
12 # dedicated to delivering high quality video editing and animation solutions
13 # to the world.
14 #
15 # OpenShot Video Editor is free software: you can redistribute it and/or modify
16 # it under the terms of the GNU General Public License as published by
17 # the Free Software Foundation, either version 3 of the License, or
18 # (at your option) any later version.
19 #
20 # OpenShot Video Editor is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public License
26 # along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
27 #
28 
29 import os
30 import fnmatch
31 
32 from PyQt5.QtCore import QMimeData, Qt, QSize
33 from PyQt5.QtGui import *
34 from PyQt5.QtWidgets import QMessageBox
35 import openshot # Python module for libopenshot (required video editing module installed separately)
36 
37 from classes import info
38 from classes.logger import log
39 from classes.app import get_app
40 
41 try:
42  import json
43 except ImportError:
44  import simplejson as json
45 
46 
47 class TitleStandardItemModel(QStandardItemModel):
48  def __init__(self, parent=None):
49  QStandardItemModel.__init__(self)
50 
51  def mimeData(self, indexes):
52  # Create MimeData for drag operation
53  data = QMimeData()
54 
55  # Get list of all selected file ids
56  files = []
57  for item in indexes:
58  selected_row = self.itemFromIndex(item).row()
59  files.append(self.item(selected_row, 2).text())
60  data.setText(json.dumps(files))
61  data.setHtml("title")
62 
63  # Return Mimedata
64  return data
65 
66 
67 class TitlesModel():
68  def update_model(self, clear=True):
69  log.info("updating title model.")
70  app = get_app()
71 
72  # Get window to check filters
73  win = app.window
74  _ = app._tr
75 
76  # Clear all items
77  if clear:
78  self.model_paths = {}
79  self.model.clear()
80 
81  # Add Headers
82  self.model.setHorizontalHeaderLabels([_("Thumb"), _("Name")])
83 
84  # get a list of files in the OpenShot /transitions directory
85  titles_dir = os.path.join(info.PATH, "titles")
86 
87  # Add build-in templates
88  titles_list = []
89  for filename in sorted(os.listdir(titles_dir)):
90  titles_list.append(os.path.join(titles_dir, filename))
91 
92  # Add user-defined titles (if any)
93  for file in sorted(os.listdir(info.TITLE_PATH)):
94  # pretty up the filename for display purposes
95  if fnmatch.fnmatch(file, '*.svg'):
96  titles_list.append(os.path.join(info.TITLE_PATH, file))
97 
98  for path in sorted(titles_list):
99  (parent_path, filename) = os.path.split(path)
100  (fileBaseName, fileExtension) = os.path.splitext(filename)
101 
102  # Skip hidden files (such as .DS_Store, etc...)
103  if filename[0] == "." or "thumbs.db" in filename.lower() or filename.lower() == "temp.svg":
104  continue
105 
106  # split the name into parts (looking for a number)
107  suffix_number = None
108  name_parts = fileBaseName.split("_")
109  if name_parts[-1].isdigit():
110  suffix_number = name_parts[-1]
111 
112  # get name of transition
113  title_name = fileBaseName.replace("_", " ").capitalize()
114 
115  # replace suffix number with placeholder (if any)
116  if suffix_number:
117  title_name = title_name.replace(suffix_number, "%s")
118  title_name = self.app._tr(title_name) % suffix_number
119  else:
120  title_name = self.app._tr(title_name)
121 
122  # Check for thumbnail path (in build-in cache)
123  thumb_path = os.path.join(info.IMAGES_PATH, "cache", "{}.png".format(fileBaseName))
124 
125  # Check built-in cache (if not found)
126  if not os.path.exists(thumb_path):
127  # Check user folder cache
128  thumb_path = os.path.join(info.CACHE_PATH, "{}.png".format(fileBaseName))
129 
130  # Generate thumbnail (if needed)
131  if not os.path.exists(thumb_path):
132 
133  try:
134  # Reload this reader
135  clip = openshot.Clip(path)
136  reader = clip.Reader()
137 
138  # Open reader
139  reader.Open()
140 
141  # Save thumbnail
142  reader.GetFrame(0).Thumbnail(thumb_path, 98, 64, os.path.join(info.IMAGES_PATH, "mask.png"), "", "#000", True)
143  reader.Close()
144  clip.Close()
145 
146  except:
147  # Handle exception
148  msg = QMessageBox()
149  msg.setText(_("{} is not a valid image file.".format(filename)))
150  msg.exec_()
151  continue
152 
153  row = []
154 
155  # Append thumbnail
156  col = QStandardItem()
157  icon_pixmap = QPixmap(thumb_path)
158  scaled_pixmap = icon_pixmap.scaled(QSize(93, 62), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
159  col.setIcon(QIcon(scaled_pixmap))
160  col.setText(title_name)
161  col.setToolTip(title_name)
162  col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled)
163  row.append(col)
164 
165  # Append Filename
166  col = QStandardItem("Name")
167  col.setData(title_name, Qt.DisplayRole)
168  col.setText(title_name)
169  col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled)
170  row.append(col)
171 
172  # Append Path
173  col = QStandardItem("Path")
174  col.setData(path, Qt.DisplayRole)
175  col.setText(path)
176  col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsDragEnabled)
177  row.append(col)
178 
179  # Append ROW to MODEL (if does not already exist in model)
180  if not path in self.model_paths:
181  self.model.appendRow(row)
182  self.model_paths[path] = path
183 
184  # Process events in QT (to keep the interface responsive)
185  app.processEvents()
186 
187  def __init__(self, *args):
188 
189  # Create standard model
190  self.app = get_app()
192  self.model.setColumnCount(3)
193  self.model_paths = {}
def get_app
Returns the current QApplication instance of OpenShot.
Definition: app.py:55