30 from PyQt5.QtCore import Qt, QRectF, QLocale, pyqtSignal, Qt, QObject, QTimer
32 from PyQt5.QtWidgets import QTableView, QAbstractItemView, QMenu, QSizePolicy, QHeaderView, QColorDialog, QItemDelegate, QStyle, QLabel, QPushButton, QHBoxLayout, QFrame
34 from classes.logger
import log
35 from classes.app
import get_app
36 from classes
import info
37 from classes.query
import Clip, Effect, Transition
38 from windows.models.properties_model
import PropertiesModel
45 import simplejson
as json
50 QItemDelegate.__init__(self, parent, *args)
53 self.
curve_pixmaps = { openshot.BEZIER: QPixmap(os.path.join(info.IMAGES_PATH,
"keyframe-%s.png" % openshot.BEZIER)),
54 openshot.LINEAR: QPixmap(os.path.join(info.IMAGES_PATH,
"keyframe-%s.png" % openshot.LINEAR)),
55 openshot.CONSTANT: QPixmap(os.path.join(info.IMAGES_PATH,
"keyframe-%s.png" % openshot.CONSTANT))
58 def paint(self, painter, option, index):
60 painter.setRenderHint(QPainter.Antialiasing)
63 model =
get_app().window.propertyTableView.clip_properties_model.model
64 row = model.itemFromIndex(index).row()
65 selected_label = model.item(row, 0)
66 selected_value = model.item(row, 1)
67 property = selected_label.data()
70 property_name = property[1][
"name"]
71 property_type = property[1][
"type"]
72 property_max = property[1][
"max"]
73 property_min = property[1][
"min"]
74 readonly = property[1][
"readonly"]
75 keyframe = property[1][
"keyframe"]
76 points = property[1][
"points"]
77 interpolation = property[1][
"interpolation"]
80 if property_type
in [
"float",
"int"]:
82 current_value = QLocale().system().toDouble(selected_value.text())[0]
85 if property_min < 0.0:
86 property_shift = 0.0 - property_min
87 property_min += property_shift
88 property_max += property_shift
89 current_value += property_shift
92 min_max_range = float(property_max) - float(property_min)
93 value_percent = current_value / min_max_range
98 painter.setPen(QPen(Qt.NoPen))
99 if property_type ==
"color":
101 red = property[1][
"red"][
"value"]
102 green = property[1][
"green"][
"value"]
103 blue = property[1][
"blue"][
"value"]
104 painter.setBrush(QBrush(QColor(QColor(red, green, blue))))
107 if option.state & QStyle.State_Selected:
108 painter.setBrush(QBrush(QColor(
"#575757")))
110 painter.setBrush(QBrush(QColor(
"#3e3e3e")))
113 path = QPainterPath()
114 path.addRoundedRect(QRectF(option.rect), 15, 15)
115 painter.fillPath(path, QColor(
"#3e3e3e"))
116 painter.drawPath(path)
119 painter.setBrush(QBrush(QColor(
"#000000")))
120 mask_rect = QRectF(option.rect)
121 mask_rect.setWidth(option.rect.width() * value_percent)
122 painter.setClipRect(mask_rect, Qt.IntersectClip)
125 gradient = QLinearGradient(option.rect.topLeft(), option.rect.topRight())
126 gradient.setColorAt(0, QColor(
"#828282"))
127 gradient.setColorAt(1, QColor(
"#828282"))
130 painter.setBrush(gradient)
131 path = QPainterPath()
132 value_rect = QRectF(option.rect)
133 path.addRoundedRect(value_rect, 15, 15);
134 painter.fillPath(path, gradient)
135 painter.drawPath(path);
136 painter.setClipping(
False)
140 painter.drawPixmap(option.rect.x() + option.rect.width() - 30.0, option.rect.y() + 4, self.
curve_pixmaps[interpolation])
143 painter.setPen(QPen(Qt.white))
144 value = index.data(Qt.DisplayRole)
146 painter.drawText(option.rect, Qt.AlignCenter, value)
154 loadProperties = pyqtSignal(str, str)
158 model = self.clip_properties_model.model
159 row = self.indexAt(event.pos()).row()
160 column = self.indexAt(event.pos()).column()
161 if model.item(row, 0):
167 frame_number = self.clip_properties_model.frame_number
170 value_column_x = self.columnViewportPosition(1)
171 value_column_y = value_column_x + self.columnWidth(1)
172 cursor_value = event.x() - value_column_x
173 cursor_value_percent = cursor_value / self.columnWidth(1)
175 property = self.selected_label.data()
176 property_name = property[1][
"name"]
177 property_type = property[1][
"type"]
178 property_max = property[1][
"max"]
179 property_min = property[1][
"min"]
180 property_value = property[1][
"value"]
181 readonly = property[1][
"readonly"]
188 if property_type
in [
"float",
"int"]:
189 min_max_range = float(property_max) - float(property_min)
192 if min_max_range > 1000.0:
194 new_value = QLocale().system().toDouble(self.selected_item.text())[0]
212 new_value = property_min + (min_max_range * cursor_value_percent)
215 new_value = max(property_min, new_value)
216 new_value = min(property_max, new_value)
219 self.clip_properties_model.value_updated(self.
selected_item, -1, new_value)
222 self.viewport().update()
229 model = self.clip_properties_model.model
231 row = model_index.row()
232 selected_label = model.item(row, 0)
236 property = selected_label.data()
237 property_type = property[1][
"type"]
239 if property_type ==
"color":
241 red = property[1][
"red"][
"value"]
242 green = property[1][
"green"][
"value"]
243 blue = property[1][
"blue"][
"value"]
246 currentColor = QColor(red, green, blue)
247 newColor = QColorDialog.getColor(currentColor)
250 self.clip_properties_model.color_update(self.
selected_item, newColor)
260 self.clip_properties_model.update_item(item_id, item_type)
267 self.clip_properties_model.update_frame(frame_number)
274 self.clip_properties_model.update_model(value)
278 model = self.clip_properties_model.model
279 row = self.indexAt(event.pos()).row()
280 selected_label = model.item(row, 0)
281 selected_value = model.item(row, 1)
283 frame_number = self.clip_properties_model.frame_number
291 property = selected_label.data()
292 property_name = property[1][
"name"]
294 points = property[1][
"points"]
296 property_key = property[0]
297 clip_id, item_type = selected_value.data()
299 log.info(
"Context menu shown for %s (%s) for clip %s on frame %s" % (
300 property_name, property_key, clip_id, frame_number))
301 log.info(
"Points: %s" % points)
302 log.info(
"Property: %s" % str(property))
304 bezier_icon = QIcon(QPixmap(os.path.join(info.IMAGES_PATH,
"keyframe-%s.png" % openshot.BEZIER)))
305 linear_icon = QIcon(QPixmap(os.path.join(info.IMAGES_PATH,
"keyframe-%s.png" % openshot.LINEAR)))
306 constant_icon = QIcon(QPixmap(os.path.join(info.IMAGES_PATH,
"keyframe-%s.png" % openshot.CONSTANT)))
312 Bezier_Action = menu.addAction(_(
"Bezier"))
313 Bezier_Action.setIcon(bezier_icon)
315 Linear_Action = menu.addAction(_(
"Linear"))
316 Linear_Action.setIcon(linear_icon)
318 Constant_Action = menu.addAction(_(
"Constant"))
319 Constant_Action.setIcon(constant_icon)
322 Remove_Action = menu.addAction(_(
"Remove Keyframe"))
324 menu.popup(QCursor.pos())
327 Remove_Action = menu.addAction(_(
"Remove Keyframe"))
329 menu.popup(QCursor.pos())
334 Choice_Action = menu.addAction(_(choice[
"name"]))
335 Choice_Action.setData(choice[
"value"])
338 menu.popup(QCursor.pos())
341 log.info(
"Bezier_Action_Triggered")
344 self.clip_properties_model.value_updated(self.
selected_item, 0)
347 self.clip_properties_model.color_update(self.
selected_item, QColor(
"#000"), 0)
350 log.info(
"Linear_Action_Triggered")
353 self.clip_properties_model.value_updated(self.
selected_item, 1)
356 self.clip_properties_model.color_update(self.
selected_item, QColor(
"#000"), 1)
359 log.info(
"Constant_Action_Triggered")
362 self.clip_properties_model.value_updated(self.
selected_item, 2)
365 self.clip_properties_model.color_update(self.
selected_item, QColor(
"#000"), 2)
368 log.info(
"Remove_Action_Triggered")
369 self.clip_properties_model.remove_keyframe(self.
selected_item)
372 log.info(
"Choice_Action_Triggered")
373 choice_value = self.sender().data()
376 self.clip_properties_model.value_updated(self.
selected_item, value=choice_value)
380 QTableView.__init__(self, *args)
393 self.setModel(self.clip_properties_model.model)
394 self.setSelectionBehavior(QAbstractItemView.SelectRows)
395 self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
396 self.setWordWrap(
True)
400 self.setItemDelegateForColumn(1, delegate)
404 horizontal_header = self.horizontalHeader()
405 horizontal_header.setSectionResizeMode(QHeaderView.Stretch)
406 vertical_header = self.verticalHeader()
407 vertical_header.setVisible(
False)
410 self.clip_properties_model.update_model()
413 self.resizeColumnToContents(0)
414 self.resizeColumnToContents(1)
442 for item_id
in get_app().window.selected_clips:
443 clip = Clip.get(id=item_id)
444 item_name = clip.title()
445 item_icon = QIcon(QPixmap(clip.data.get(
'image')))
446 action = menu.addAction(item_name)
447 action.setIcon(item_icon)
448 action.setData({
'item_id':item_id,
'item_type':
'clip'})
452 for effect
in clip.data.get(
'effects'):
453 item_name = Effect.get(id=effect.get(
'id')).title()
454 item_icon = QIcon(QPixmap(os.path.join(info.PATH,
"effects",
"icons",
"%s.png" % effect.get(
'class_name').lower())))
455 action = menu.addAction(
' > %s' % _(item_name))
456 action.setIcon(item_icon)
457 action.setData({
'item_id': effect.get(
'id'),
'item_type':
'effect'})
461 for item_id
in get_app().window.selected_transitions:
462 trans = Transition.get(id=item_id)
463 item_name = _(trans.title())
464 item_icon = QIcon(QPixmap(trans.data.get(
'reader',{}).get(
'path')))
465 action = menu.addAction(_(item_name))
466 action.setIcon(item_icon)
467 action.setData({
'item_id': item_id,
'item_type':
'transition'})
471 for item_id
in get_app().window.selected_effects:
472 effect = Effect.get(id=item_id)
473 item_name = _(effect.title())
474 item_icon = QIcon(QPixmap(os.path.join(info.PATH,
"effects",
"icons",
"%s.png" % effect.data.get(
'class_name').lower())))
475 action = menu.addAction(_(item_name))
476 action.setIcon(item_icon)
477 action.setData({
'item_id': item_id,
'item_type':
'effect'})
485 item_id = self.sender().data()[
'item_id']
486 item_type = self.sender().data()[
'item_type']
487 log.info(
'switch selection to %s:%s' % (item_id, item_type))
490 get_app().window.propertyTableView.loadProperties.emit(item_id, item_type)
498 self.update_timer.start()
509 self.update_timer.stop()
516 clip = Clip.get(id=self.
item_id)
518 self.
item_icon = QIcon(QPixmap(clip.data.get(
'image')))
520 trans = Transition.get(id=self.
item_id)
522 self.
item_icon = QIcon(QPixmap(trans.data.get(
'reader', {}).get(
'path')))
524 effect = Effect.get(id=self.
item_id)
526 self.
item_icon = QIcon(QPixmap(os.path.join(info.PATH,
"effects",
"icons",
"%s.png" % effect.data.get(
'class_name').lower())))
534 self.lblSelection.setText(
"<strong>%s</strong>" % _(
"Selection:"))
535 self.btnSelectionName.setText(self.
item_name)
536 self.btnSelectionName.setVisible(
True)
538 self.btnSelectionName.setIcon(self.
item_icon)
540 self.lblSelection.setText(
"<strong>%s</strong>" % _(
"No Selection"))
541 self.btnSelectionName.setVisible(
False)
544 self.btnSelectionName.setMenu(self.
getMenu())
548 QFrame.__init__(self, *args)
557 self.lblSelection.setText(
"<strong>%s</strong>" % _(
"No Selection"))
559 self.btnSelectionName.setVisible(
False)
560 self.btnSelectionName.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
563 self.lblSelection.setTextFormat(Qt.RichText)
566 hbox.setContentsMargins(0,0,0,0)
574 self.update_timer.setInterval(100)
576 self.update_timer.stop()
def __init__(self, parent=None, args)
def get_app()
Returns the current QApplication instance of OpenShot.
def paint(self, painter, option, index)
def double_click(self, model_index)
Double click handler for the property table.
def select_item(self, item_id, item_type)
Update the selected item in the properties window.
def mouseMoveEvent(self, event)
def filter_changed(self, value=None)
Filter the list of properties.
def contextMenuEvent(self, event)
def Choice_Action_Triggered(self, event)
def Linear_Action_Triggered(self, event)
def update_item_timeout(self)
The label to display selections.
def select_frame(self, frame_number)
Update the values of the selected clip, based on the current frame.
A Properties Table QWidget used on the main window.
def Bezier_Action_Triggered(self, event)
def select_item(self, item_id, item_type)
def Action_Triggered(self, event)
def Constant_Action_Triggered(self, event)
def Remove_Action_Triggered(self, event)