Exemple #1
0
def load():
    """
    If docs fail to load, new ones are created and saved.
    """
    prefs_file_path = utils.get_hidden_user_dir_path() + PREFS_DOC
    recents_file_path = utils.get_hidden_user_dir_path() + RECENT_DOC

    global prefs, recent_projects
    try:
        f = open(prefs_file_path)
        prefs = pickle.load(f)
    except:
        prefs = EditorPreferences()
        write_file = file(prefs_file_path, "wb")
        pickle.dump(prefs, write_file)

    try:
        f = open(recents_file_path)
        recent_projects = pickle.load(f)
    except:
        recent_projects = utils.EmptyClass()
        recent_projects.projects = []
        write_file = file(recents_file_path, "wb")
        pickle.dump(recent_projects, write_file)

    # version of program may have different prefs objects and 
    # we may need to to update prefs on disk if user has e.g.
    # installed later version of Flowblade
    current_prefs = EditorPreferences()
    if len(prefs.__dict__) != len(current_prefs.__dict__):
        current_prefs.__dict__.update(prefs.__dict__)
        prefs = current_prefs
        write_file = file(prefs_file_path, "wb")
        pickle.dump(prefs, write_file)
        print "prefs updated to new version, new param count:", len(prefs.__dict__)
Exemple #2
0
def load():
    """
    If docs fail to load, new ones are created and saved.
    """
    prefs_file_path = userfolders.get_config_dir() + PREFS_DOC
    recents_file_path = userfolders.get_config_dir() + RECENT_DOC

    global prefs, recent_projects

    try:
        prefs = utils.unpickle(prefs_file_path)
    except:
        prefs = EditorPreferences()
        with atomicfile.AtomicFileWriter(prefs_file_path, "wb") as afw:
            write_file = afw.get_file()
            pickle.dump(prefs, write_file)

    # Override deprecated preferences to default values.
    prefs.delta_overlay = True
    prefs.auto_play_in_clip_monitor = False
    prefs.empty_click_exits_trims = True
    prefs.quick_enter_trims = True
    prefs.remember_monitor_clip_frame = True

    try:
        recent_projects = utils.unpickle(recents_file_path)
    except:
        recent_projects = utils.EmptyClass()
        recent_projects.projects = []
        with atomicfile.AtomicFileWriter(recents_file_path, "wb") as afw:
            write_file = afw.get_file()
            pickle.dump(recent_projects, write_file)

    # Remove non-existing projects from recents list
    remove_list = []
    for proj_path in recent_projects.projects:
        if os.path.isfile(proj_path) == False:
            remove_list.append(proj_path)

    if len(remove_list) > 0:
        for proj_path in remove_list:
            recent_projects.projects.remove(proj_path)
        with atomicfile.AtomicFileWriter(recents_file_path, "wb") as afw:
            write_file = afw.get_file()
            pickle.dump(recent_projects, write_file)

    # Versions of program may have different prefs objects and
    # we may need to to update prefs on disk if user has e.g.
    # installed later version of Flowblade.
    current_prefs = EditorPreferences()

    if len(prefs.__dict__) != len(current_prefs.__dict__):
        current_prefs.__dict__.update(prefs.__dict__)
        prefs = current_prefs
        with atomicfile.AtomicFileWriter(prefs_file_path, "wb") as afw:
            write_file = afw.get_file()
            pickle.dump(prefs, write_file)
        print("prefs updated to new version, new param count:",
              len(prefs.__dict__))
Exemple #3
0
def create_editable_property_for_affine_blend(clip, editable_properties):
    # Build a custom object that duck types for TransitionEditableProperty to use in editor
    #
    ep = utils.EmptyClass()
    # pack real properties to go
    ep.x = [ep for ep in editable_properties if ep.name == "x"][0]
    ep.y = [ep for ep in editable_properties if ep.name == "y"][0]
    ep.x_scale = [ep for ep in editable_properties if ep.name == "x scale"][0]
    ep.y_scale = [ep for ep in editable_properties if ep.name == "y scale"][0]
    ep.rotation = [ep for ep in editable_properties
                   if ep.name == "rotation"][0]
    ep.opacity = [ep for ep in editable_properties if ep.name == "opacity"][0]
    # Screen width and height are needeed for frei0r conversions
    ep.profile_width = current_sequence().profile.width()
    ep.profile_height = current_sequence().profile.height()
    # duck type methods, using opacity is not meaningful, any property with clip member could do
    ep.get_clip_tline_pos = lambda: ep.opacity.clip.clip_in  # clip is compositor, compositor in and out points straight in timeline frames
    ep.get_clip_length = lambda: ep.opacity.clip.clip_out - ep.opacity.clip.clip_in + 1
    ep.get_input_range_adjustment = lambda: Gtk.Adjustment(
        value=float(100), lower=float(0), upper=float(100), step_incr=float(1))
    ep.get_display_name = lambda: "Opacity"
    ep.get_pixel_aspect_ratio = lambda: (float(current_sequence(
    ).profile.sample_aspect_num()) / current_sequence().profile.
                                         sample_aspect_den())
    ep.get_in_value = lambda out_value: out_value  # hard coded for opacity 100 -> 100 range
    ep.write_out_keyframes = lambda w_kf: rotating_ge_write_out_keyframes(
        ep, w_kf)
    ep.update_prop_value = lambda: rotating_ge_update_prop_value(
        ep
    )  # This is needed to get good update after adding kfs with fade buttons, iz all kinda fugly
    # We need this to reinit GUI components after programmatically added kfs.
    # duck type members
    x_tokens = ep.x.value.split(";")
    y_tokens = ep.y.value.split(";")
    x_scale_tokens = ep.x_scale.value.split(";")
    y_scale_tokens = ep.y_scale.value.split(";")
    rotation_tokens = ep.rotation.value.split(";")
    opacity_tokens = ep.opacity.value.split(";")

    value = ""
    for i in range(
            0, len(x_tokens)
    ):  # these better match, same number of keyframes for all values, or this will not work
        frame, x = x_tokens[i].split("=")
        frame, y = y_tokens[i].split("=")
        frame, x_scale = x_scale_tokens[i].split("=")
        frame, y_scale = y_scale_tokens[i].split("=")
        frame, rotation = rotation_tokens[i].split("=")
        frame, opacity = opacity_tokens[i].split("=")

        frame_str = str(frame) + "=" + str(x) + ":" + str(y) + ":" + str(
            x_scale) + ":" + str(y_scale) + ":" + str(rotation) + ":" + str(
                opacity)
        value += frame_str + ";"

    ep.value = value.strip(";")

    return ep
Exemple #4
0
 def make_tailer_state():
     """Return the tailer state "struct" """
     s = utils.EmptyClass()
     s.entries_received = 0  # how many entries were put in the global doc queue
     s.entries_written = 0  # how many entries were written to the output file
     s.alive = True  # is this thread still alive (i.e. working)?
     s.last_received_ts = None  # timestamp of the latest received doc
     s.last_get_none_ts = None  # last time this thread didn't get anything from the tailing cursor
     return s
Exemple #5
0
    def run(self):
        callbacks = utils.EmptyClass()
        callbacks.set_render_progress_gui = set_render_progress_gui
        callbacks.save_render_start_time = save_render_start_time
        callbacks.exit_render_gui = exit_render_gui
        callbacks.maybe_open_rendered_file_in_bin = maybe_open_rendered_file_in_bin

        PLAYER().set_render_callbacks(callbacks)
        PLAYER().start_rendering(self.render_consumer, self.start_frame, self.end_frame)
def _create_rotion_geometry_editor(clip, editable_properties):
    # Build a custom object that duck types for TransitionEditableProperty to use in editor
    ep = utils.EmptyClass()
    # pack real properties to go
    ep.x = filter(lambda ep: ep.name == "x", editable_properties)[0]
    ep.y = filter(lambda ep: ep.name == "y", editable_properties)[0]
    ep.x_scale = filter(lambda ep: ep.name == "x scale",
                        editable_properties)[0]
    ep.y_scale = filter(lambda ep: ep.name == "y scale",
                        editable_properties)[0]
    ep.rotation = filter(lambda ep: ep.name == "rotation",
                         editable_properties)[0]
    ep.opacity = filter(lambda ep: ep.name == "opacity",
                        editable_properties)[0]
    # Screen width and height are needeed for frei0r conversions
    ep.profile_width = current_sequence().profile.width()
    ep.profile_height = current_sequence().profile.height()
    # duck type methods, using opacity is not meaningful, any property with clip member could do
    ep.get_clip_tline_pos = lambda: ep.opacity.clip.clip_in  # clip is compositor, compositor in and out points staright in timeline frames
    ep.get_clip_length = lambda: ep.opacity.clip.clip_out - ep.opacity.clip.clip_in + 1
    ep.get_input_range_adjustment = lambda: Gtk.Adjustment(
        float(100), float(0), float(100), float(1))
    ep.get_display_name = lambda: "Opacity"
    ep.get_pixel_aspect_ratio = lambda: (float(current_sequence(
    ).profile.sample_aspect_num()) / current_sequence().profile.
                                         sample_aspect_den())
    ep.get_in_value = lambda out_value: out_value  # hard coded for opacity 100 -> 100 range
    ep.write_out_keyframes = lambda w_kf: keyframeeditor.rotating_ge_write_out_keyframes(
        ep, w_kf)
    # duck type members
    x_tokens = ep.x.value.split(";")
    y_tokens = ep.y.value.split(";")
    x_scale_tokens = ep.x_scale.value.split(";")
    y_scale_tokens = ep.y_scale.value.split(";")
    rotation_tokens = ep.rotation.value.split(";")
    opacity_tokens = ep.opacity.value.split(";")

    value = ""
    for i in range(
            0, len(x_tokens)
    ):  # these better match, same number of keyframes for all values, or this will not work
        frame, x = x_tokens[i].split("=")
        frame, y = y_tokens[i].split("=")
        frame, x_scale = x_scale_tokens[i].split("=")
        frame, y_scale = y_scale_tokens[i].split("=")
        frame, rotation = rotation_tokens[i].split("=")
        frame, opacity = opacity_tokens[i].split("=")

        frame_str = str(frame) + "=" + str(x) + ":" + str(y) + ":" + str(
            x_scale) + ":" + str(y_scale) + ":" + str(rotation) + ":" + str(
                opacity)
        value += frame_str + ";"

    ep.value = value.strip(";")

    kf_edit = keyframeeditor.RotatingGeometryEditor(ep, False)
    return kf_edit
Exemple #7
0
 def make_tailer_state():
     """Return the tailer state "struct" """
     s = utils.EmptyClass()
     s.entries_received = 0
     s.entries_written = 0
     s.alive = True
     s.last_received_ts = None
     s.last_get_none_ts = None
     return s
 def _create_coords(self):
     self.coords = utils.EmptyClass()
     panel_w = self.widget.get_allocation().width
     panel_h = self.widget.get_allocation().height
     self.coords.screen_h = panel_h * self.y_fract
     self.coords.screen_w = self.coords.screen_h * self.screen_ratio * self.pixel_aspect_ratio
     self.coords.orig_x = (panel_w - self.coords.screen_w) / 2.0
     self.coords.orig_y = (panel_h - self.coords.screen_h) / 2.0
     self.coords.x_scale = self.source_width / self.coords.screen_w
     self.coords.y_scale = self.source_height / self.coords.screen_h
Exemple #9
0
def autosaves_many_recovery_dialog():
    autosaves_file_names = get_autosave_files()
    now = time.time()
    autosaves = []
    for a_file_name in autosaves_file_names:
        autosave_path = utils.get_hidden_user_dir_path() + AUTOSAVE_DIR + a_file_name
        autosave_object = utils.EmptyClass()
        autosave_object.age = now - os.stat(autosave_path).st_mtime
        autosave_object.path = autosave_path
        autosaves.append(autosave_object)
    autosaves = sorted(autosaves, key=lambda autosave_object: autosave_object.age)

    dialogs.autosaves_many_recovery_dialog(autosaves_many_dialog_callback, autosaves, gui.editor_window.window)
    return False
Exemple #10
0
def create_widgets(def_profile_index, disable_audio=True, create_container_file_panel=False):
    """
    Widgets for editing render properties and viewing render progress.
    """
    global widgets, disable_audio_encoding, default_profile_index
    default_profile_index = def_profile_index
    if disable_audio:
        disable_audio_encoding = True

    widgets = utils.EmptyClass()
     
    widgets.file_panel = RenderFilePanel(create_container_file_panel)
    widgets.profile_panel = RenderProfilePanel(_out_profile_changed)
    widgets.encoding_panel = RenderEncodingPanel(widgets.file_panel.extension_label)

    widgets.profile_panel.out_profile_combo.fill_options()
    _display_default_profile()
Exemple #11
0
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Flowblade Movie Editor.  If not, see <http://www.gnu.org/licenses/>.
"""

from gi.repository import Gtk
from gi.repository import GObject
from gi.repository import Pango

from editorstate import PROJECT
import guicomponents
import guiutils
import utils

widgets = utils.EmptyClass()

PROJECT_INFO_PANEL_HEIGHT = 200
PROJECT_TOP_LEVEL_PANE_HEIGHT = 150


def get_project_info_panel():
    project_name_label = Gtk.Label(label=PROJECT().name)
    name_row = guiutils.get_left_justified_box([project_name_label])
    name_panel = guiutils.get_named_frame(_("Name"), name_row, 4)

    profile = PROJECT().profile
    desc_label = Gtk.Label(label=profile.description())
    info_box = guicomponents.get_profile_info_small_box(profile)
    vbox = Gtk.VBox()
    vbox.pack_start(guiutils.get_left_justified_box([desc_label]), False, True,
Exemple #12
0
def show_reverse_dialog(media_file, default_range_render, _response_callback):
    folder, file_name = os.path.split(media_file.path)
    if media_file.is_proxy_file:
        folder, file_name = os.path.split(media_file.second_file_path)

    name, ext = os.path.splitext(file_name)
        
    dialog = Gtk.Dialog(_("Render Reverse Motion Video File"), gui.editor_window.window,
                        Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
                        (Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT,
                        _("Render").encode('utf-8'), Gtk.ResponseType.ACCEPT))

    media_file_label = Gtk.Label(label=_("Source Media File: "))
    media_name = Gtk.Label(label="<b>" + media_file.name + "</b>")
    media_name.set_use_markup(True)
    SOURCE_PAD = 8
    SOURCE_HEIGHT = 20
    mf_row = guiutils.get_left_justified_box([media_file_label,  guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), media_name])
    
    mark_in = Gtk.Label(label=_("<b>not set</b>"))
    mark_out = Gtk.Label(label=_("<b>not set</b>"))
    if media_file.mark_in != -1:
        mark_in = Gtk.Label(label="<b>" + utils.get_tc_string(media_file.mark_in) + "</b>")
    if media_file.mark_out != -1:
        mark_out = Gtk.Label(label="<b>" + utils.get_tc_string(media_file.mark_out) + "</b>")
    mark_in.set_use_markup(True)
    mark_out.set_use_markup(True)
    
    fb_widgets = utils.EmptyClass()

    fb_widgets.file_name = Gtk.Entry()
    fb_widgets.file_name.set_text(name + "_REVERSE")
    
    fb_widgets.extension_label = Gtk.Label()
    fb_widgets.extension_label.set_size_request(45, 20)

    name_row = Gtk.HBox(False, 4)
    name_row.pack_start(fb_widgets.file_name, True, True, 0)
    name_row.pack_start(fb_widgets.extension_label, False, False, 4)
    
    fb_widgets.out_folder = Gtk.FileChooserButton(_("Select Target Folder"))
    fb_widgets.out_folder.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
    fb_widgets.out_folder.set_current_folder(folder)
    
    label = Gtk.Label(label=_("Speed %:"))

    adjustment = Gtk.Adjustment(float(-100), float(-600), float(-1), float(1))
    fb_widgets.hslider = Gtk.HScale()
    fb_widgets.hslider.set_adjustment(adjustment)
    fb_widgets.hslider.set_draw_value(False)

    spin = Gtk.SpinButton()
    spin.set_numeric(True)
    spin.set_adjustment(adjustment)

    fb_widgets.hslider.set_digits(0)
    spin.set_digits(0)

    slider_hbox = Gtk.HBox(False, 4)
    slider_hbox.pack_start(fb_widgets.hslider, True, True, 0)
    slider_hbox.pack_start(spin, False, False, 4)
    slider_hbox.set_size_request(450,35)

    hbox = Gtk.HBox(False, 2)
    hbox.pack_start(guiutils.pad_label(8, 8), False, False, 0)
    hbox.pack_start(slider_hbox, False, False, 0)

    profile_selector = ProfileSelector()
    profile_selector.fill_options()
    profile_selector.widget.set_sensitive(True)
    fb_widgets.out_profile_combo = profile_selector.widget

    quality_selector = RenderQualitySelector()
    fb_widgets.quality_cb = quality_selector.widget
    
    # Encoding
    encoding_selector = RenderEncodingSelector(quality_selector, fb_widgets.extension_label, None)
    encoding_selector.encoding_selection_changed()
    fb_widgets.encodings_cb = encoding_selector.widget
    
    objects_list = Gtk.TreeStore(str, bool)
    objects_list.append(None, [_("Full Source Length"), True])
    if media_file.mark_in != -1 and media_file.mark_out != -1:
        range_available = True
    else:
        range_available = False
    objects_list.append(None, [_("Source Mark In to Mark Out"), range_available])
    
    fb_widgets.render_range = Gtk.ComboBox.new_with_model(objects_list)
    
    renderer_text = Gtk.CellRendererText()
    fb_widgets.render_range.pack_start(renderer_text, True)
    fb_widgets.render_range.add_attribute(renderer_text, "text", 0)
    fb_widgets.render_range.add_attribute(renderer_text, 'sensitive', 1)
    if default_range_render == False:
        fb_widgets.render_range.set_active(0)
    else:
        fb_widgets.render_range.set_active(1)
    fb_widgets.render_range.show()

    # To update rendered length display
    clip_length = _get_rendered_slomo_clip_length(media_file, fb_widgets.render_range, 100)
    clip_length_label = Gtk.Label(label=utils.get_tc_string(clip_length))
    fb_widgets.hslider.connect("value-changed", _reverse_speed_changed, media_file, fb_widgets.render_range, clip_length_label)
    fb_widgets.render_range.connect("changed", _reverse_range_changed,  media_file, fb_widgets.hslider,  clip_length_label)

    # Build gui
    vbox = Gtk.VBox(False, 2)
    vbox.pack_start(mf_row, False, False, 0)
    vbox.pack_start(guiutils.get_left_justified_box([Gtk.Label(label=_("Source Mark In: ")), guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), mark_in]), False, False, 0)
    vbox.pack_start(guiutils.get_left_justified_box([Gtk.Label(label=_("Source Mark Out: ")), guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), mark_out]), False, False, 0)
    vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
    vbox.pack_start(label, False, False, 0)
    vbox.pack_start(hbox, False, False, 0)
    vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target File:")), name_row, 120), False, False, 0)
    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target Folder:")), fb_widgets.out_folder, 120), False, False, 0)
    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target Profile:")), fb_widgets.out_profile_combo, 200), False, False, 0)
    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target Encoding:")), fb_widgets.encodings_cb, 200), False, False, 0)
    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target Quality:")), fb_widgets.quality_cb, 200), False, False, 0)
    vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Render Range:")), fb_widgets.render_range, 180), False, False, 0)
    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Rendered Clip Length:")), clip_length_label, 180), False, False, 0)
    
    alignment = guiutils.set_margins(vbox, 6, 24, 24, 24)
    
    dialog.vbox.pack_start(alignment, True, True, 0)
    dialogutils.set_outer_margins(dialog.vbox)
    dialogutils.default_behaviour(dialog)
    dialog.connect('response', _response_callback, fb_widgets, media_file)
    dialog.show_all()