33 from PyQt5.QtWidgets import QLabel, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QToolButton, QCheckBox
35 from classes.logger
import log
36 from classes.settings
import get_settings
37 from classes.app
import get_app
49 painter = QPainter(self)
50 painter.setRenderHint(QPainter.Antialiasing)
54 path.addRoundedRect(QRectF(31, 0, self.width()-31, self.height()), 10, 10)
55 painter.setPen(Qt.NoPen)
56 painter.fillPath(path, QColor(
"#53a0ed"))
57 painter.drawPath(path)
61 path.addRoundedRect(QRectF(32, 1, self.width()-33, self.height()-2), 10, 10)
62 painter.setPen(Qt.NoPen)
63 painter.fillPath(path, QColor(
"#424242"))
64 painter.drawPath(path)
71 path.lineTo (31, 35 - arrow_height)
72 path.lineTo (31, (35 - arrow_height) + (arrow_height * 2))
74 painter.fillPath(path, QColor(
"#53a0ed"))
75 painter.drawPath(path)
78 if e.type() == QEvent.WindowActivate:
89 x = self.position_widget.mapToGlobal(self.position_widget.pos()).x()
90 y = self.position_widget.mapToGlobal(self.position_widget.pos()).y()
97 if state == Qt.Checked:
99 s.set(
"send_metrics",
True)
108 s.set(
"send_metrics",
False)
110 def __init__(self, id, text, position_widget, x_offset, y_offset, arrow, *args):
112 QWidget.__init__(self, *args)
127 vbox.setContentsMargins(32,10,10,10)
131 self.label.setText(text)
132 self.label.setTextFormat(Qt.RichText)
133 self.label.setWordWrap(
True)
134 self.label.setStyleSheet(
"margin-left: 20px;")
135 vbox.addWidget(self.
label)
145 checkbox_metrics = QCheckBox()
146 checkbox_metrics.setText(_(
"Yes, I would like to improve OpenShot!"))
147 checkbox_metrics.setStyleSheet(
"margin-left: 25px; margin-bottom: 5px;")
148 if s.get(
"send_metrics"):
149 checkbox_metrics.setCheckState(Qt.Checked)
151 checkbox_metrics.setCheckState(Qt.Unchecked)
153 vbox.addWidget(checkbox_metrics)
157 hbox.setContentsMargins(20,10,0,0)
161 self.btn_close_tips.setText(_(
"Hide Tutorial"))
163 self.btn_next_tip.setText(_(
"Next"))
164 self.btn_next_tip.setStyleSheet(
"font-weight:bold;")
173 self.setMinimumWidth(350)
174 self.setMinimumHeight(100)
177 self.setWindowTitle(
"Tutorial")
178 self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)
179 self.setAttribute(Qt.WA_TranslucentBackground,
True)
180 self.setFocusPolicy(Qt.NoFocus)
186 self.installEventFilter(self)
196 log.info(
"process tutorial dialogs")
206 tutorial_id = tutorial_details[
"id"]
207 tutorial_object_id = tutorial_details[
"object_id"]
208 tutorial_text = tutorial_details[
"text"]
209 tutorial_x_offset = tutorial_details[
"x"]
210 tutorial_y_offset = tutorial_details[
"y"]
211 turorial_arrow = tutorial_details[
"arrow"]
214 tutorial_object = self.
get_object(tutorial_object_id)
221 tutorial_dialog =
TutorialDialog(tutorial_id, tutorial_text, tutorial_object, tutorial_x_offset, tutorial_y_offset, turorial_arrow)
224 tutorial_dialog.btn_next_tip.clicked.connect(functools.partial(self.
next_tip, tutorial_id))
225 tutorial_dialog.btn_close_tips.clicked.connect(functools.partial(self.
hide_tips, tutorial_id,
True))
229 self.current_dialog.show()
235 if object_id ==
"filesTreeView":
236 return self.win.filesTreeView
237 elif object_id ==
"timeline":
238 return self.win.timeline
239 elif object_id ==
"dockVideoContents":
240 return self.win.dockVideoContents
241 elif object_id ==
"propertyTableView":
242 return self.win.propertyTableView
243 elif object_id ==
"transitionsTreeView":
244 return self.win.transitionsTreeView
245 elif object_id ==
"effectsTreeView":
246 return self.win.effectsTreeView
247 elif object_id ==
"export_button":
250 for toolbutton
in self.win.toolBar.children():
251 if type(toolbutton) == QToolButton
and toolbutton.defaultAction()
and toolbutton.defaultAction().objectName() ==
"actionExportVideo":
268 log.info(
"hide_tips")
274 tutorial_id = tutorial_object[
"id"]
275 if tutorial_id == tid:
280 self.tutorial_ids.append(str(tid))
287 s.set(
"tutorial_enabled",
False)
293 self.current_dialog.hide()
300 self.win.dockFiles.visibilityChanged.disconnect()
301 self.win.dockTransitions.visibilityChanged.disconnect()
302 self.win.dockEffects.visibilityChanged.disconnect()
303 self.win.dockProperties.visibilityChanged.disconnect()
304 self.win.dockVideo.visibilityChanged.disconnect()
316 self.current_dialog.showNormal()
317 self.current_dialog.raise_()
323 self.current_dialog.moveWidget()
328 log.info(
"minimize tutorial")
330 self.current_dialog.showMinimized()
349 self.
tutorial_objects = [ {
"id":
"0",
"x":400,
"y":0,
"object_id":
"filesTreeView",
"text":_(
"<b>Welcome!</b> OpenShot Video Editor is an award-winning, open-source video editing application! This tutorial will walk you through the basics.<br><br>Would you like to automatically send errors and metrics to help improve OpenShot?"),
"arrow":
False},
350 {
"id":
"1",
"x":20,
"y":0,
"object_id":
"filesTreeView",
"text":_(
"<b>Project Files:</b> Get started with your project by adding video, audio, and image files here. Drag and drop files from your file system."),
"arrow":
True},
351 {
"id":
"2",
"x":200,
"y":-15,
"object_id":
"timeline",
"text":_(
"<b>Timeline:</b> Arrange your clips on the timeline here. Overlap clips to create automatic transitions. Access lots of fun presets and options by right-clicking on clips."),
"arrow":
True},
352 {
"id":
"3",
"x":150,
"y":100,
"object_id":
"dockVideoContents",
"text":_(
"<b>Video Preview:</b> Watch your timeline video preview here. Use the buttons (play, rewind, fast-forward) to control the video playback."),
"arrow":
True},
353 {
"id":
"4",
"x":20,
"y":-35,
"object_id":
"propertyTableView",
"text":_(
"<b>Properties:</b> View and change advanced properties of clips and effects here. Right-clicking on clips is usually faster than manually changing properties."),
"arrow":
True},
354 {
"id":
"5",
"x":20,
"y":10,
"object_id":
"transitionsTreeView",
"text":_(
"<b>Transitions:</b> Create a gradual fade from one clip to another. Drag and drop a transition onto the timeline and position it on top of a clip (usually at the beginning or ending)."),
"arrow":
True},
355 {
"id":
"6",
"x":20,
"y":20,
"object_id":
"effectsTreeView",
"text":_(
"<b>Effects:</b> Adjust brightness, contrast, saturation, and add exciting special effects. Drag and drop an effect onto the timeline and position it on top of a clip (or track)"),
"arrow":
True},
356 {
"id":
"7",
"x":-265,
"y":-22,
"object_id":
"export_button",
"text":_(
"<b>Export Video:</b> When you are ready to create your finished video, click this button to export your timeline as a single video file."),
"arrow":
True}
360 self.win.dockFiles.visibilityChanged.connect(functools.partial(self.
process,
"dockFiles"))
361 self.win.dockTransitions.visibilityChanged.connect(functools.partial(self.
process,
"dockTransitions"))
362 self.win.dockEffects.visibilityChanged.connect(functools.partial(self.
process,
"dockEffects"))
363 self.win.dockProperties.visibilityChanged.connect(functools.partial(self.
process,
"dockProperties"))
364 self.win.dockVideo.visibilityChanged.connect(functools.partial(self.
process,
"dockVideo"))
def re_position_dialog
Reposition a tutorial dialog next to another widget.
def track_metric_screen
Track a GUI screen being shown.
def paintEvent
Custom paint event.
def get_app
Returns the current QApplication instance of OpenShot.
def next_tip
Mark the current tip completed, and show the next one.
def exit_manager
Disconnect from all signals, and shutdown tutorial manager.
Manage and present a list of tutorial dialogs.
A QWidget used to instruct a user how to use a certain feature.
def moveWidget
Move widget next to its position widget.
def checkbox_metrics_callback
Callback for error and anonymous usage checkbox.
def minimize
Minimize any visible tutorial dialog.
def re_show_dialog
Re show an active dialog.
def hide_tips
Hide the current tip, and don't show anymore.
def get_object
Get an object from the main window by object id.
def close_dialogs
Close any open tutorial dialogs.
def process
Process and show the first non-completed tutorial.
def get_settings
Get the current QApplication's settings instance.