コード例 #1
0
ファイル: monitorevent.py プロジェクト: jliljebl/flowblade
def _show_trimview_info():
    editorpersistance.prefs.trim_view_message_shown = True
    editorpersistance.save()
    primary_txt = _("On some systems Trim View may update slowly")
    secondary_txt = _("<b>Trim View</b> works best with SSDs and relatively powerful processors.\n\n") + \
                    _("Select <b>'Trim View Off'</b> or<b>'Trim View Single Side Edits Only'</b> options\nif performance is not satisfactory.")
    dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window)
コード例 #2
0
ファイル: workflow.py プロジェクト: jliljebl/flowblade
def _set_workflow_FILM_STYLE():
    editorpersistance.prefs.active_tools = [1, 2, 3, 4, 5, 6, 7]  # appconsts.TLINE_TOOL_ID_<X> values
    editorpersistance.prefs.dnd_action = appconsts.DND_OVERWRITE_NON_V1
    editorpersistance.prefs.box_for_empty_press_in_overwrite_tool = False
    editorpersistance.save()

    modesetting.set_default_edit_mode()
コード例 #3
0
ファイル: app.py プロジェクト: iloveooz/flowblade
def _shutdown_dialog_callback(dialog, response_id):
    dialog.destroy()
    if response_id == Gtk.ResponseType.CLOSE:# "Don't Save"
        pass
    elif response_id ==  Gtk.ResponseType.YES:# "Save"
        if editorstate.PROJECT().last_save_path != None:
            persistance.save_project(editorstate.PROJECT(), editorstate.PROJECT().last_save_path)
        else:
            dialogutils.warning_message(_("Project has not been saved previously"), 
                                    _("Save project with File -> Save As before closing."),
                                    gui.editor_window.window)
            return
    else: # "Cancel"
        return

    # --- APP SHUT DOWN --- #
    print "Exiting app..."

    # No more auto saving
    stop_autosave()

    # Save window dimensions on exit
    alloc = gui.editor_window.window.get_allocation()
    x, y, w, h = alloc.x, alloc.y, alloc.width, alloc.height 
    editorpersistance.prefs.exit_allocation = (w, h)
    editorpersistance.prefs.app_v_paned_position = gui.editor_window.app_v_paned.get_position()
    editorpersistance.prefs.top_paned_position = gui.editor_window.top_paned.get_position()
    editorpersistance.prefs.mm_paned_position = gui.editor_window.mm_paned.get_position()
    editorpersistance.save()

    # Block reconnecting consumer before setting window not visible
    updater.player_refresh_enabled = False
    gui.editor_window.window.set_visible(False)
    # Close and destroy app when gtk finds time to do it after hiding window
    GLib.idle_add(_app_destroy)
コード例 #4
0
ファイル: workflow.py プロジェクト: jliljebl/flowblade
def _set_workflow_STANDARD():
    editorpersistance.prefs.active_tools = [2, 11, 6, 1, 9, 10] # appconsts.TLINE_TOOL_ID_<X> values
    editorpersistance.prefs.dnd_action = appconsts.DND_ALWAYS_OVERWRITE
    editorpersistance.prefs.box_for_empty_press_in_overwrite_tool = True
    editorpersistance.save()

    modesetting.set_default_edit_mode()
コード例 #5
0
ファイル: projectaction.py プロジェクト: BogusCurry/flowblade
def _add_image_sequence_callback(dialog, response_id, data):
    if response_id == Gtk.ResponseType.CANCEL:
        dialog.destroy()
        return

    file_chooser, spin = data
    frame_file = file_chooser.get_filename()
    dialog.destroy()
    
    if frame_file == None:
        dialogutils.info_message(_("No file was selected"), _("Select a numbered file to add an Image Sequence to Project."), gui.editor_window.window)
        return

    (folder, file_name) = os.path.split(frame_file)
    try:
        number_parts = re.findall("[0-9]+", file_name)
        number_part = number_parts[-1] # we want the last number part 
    except:
        dialogutils.info_message(_("Not a sequence file!"), _("Selected file does not have a number part in it,\nso it can't be an image sequence file."), gui.editor_window.window)
        return

    # Create resource name with MLT syntax for MLT producer
    number_index = file_name.find(number_part)
    path_name_part = file_name[0:number_index]
    end_part = file_name[number_index + len(number_part):len(file_name)]

    # The better version with "?begin=xxx" only available after 0.8.7
    if editorstate.mlt_version_is_equal_or_greater("0.8.5"):
        resource_name_str = utils.get_img_seq_resource_name(frame_file, True)
    else:
        resource_name_str = utils.get_img_seq_resource_name(frame_file, False)

    # detect highest file
    # FIX: this fails if two similarily numbered sequences in same dir and both have same substring in frame name
    onlyfiles = [ f for f in listdir(folder) if isfile(join(folder,f)) ]
    highest_number_part = int(number_part)
    for f in onlyfiles:
        try:
            file_number_part = int(re.findall("[0-9]+", f)[-1]) # -1, we want the last number part 
        except:
            continue
        if f.find(path_name_part) == -1:
            continue
        if file_number_part > highest_number_part:
            highest_number_part = file_number_part

    dialog.destroy()

    resource_path = folder + "/" + resource_name_str
    length = highest_number_part - int(number_part)

    PROJECT().add_image_sequence_media_object(resource_path, file_name + "(img_seq)", length)

    gui.media_list_view.fill_data_model()
    gui.bin_list_view.fill_data_model()

    editorpersistance.prefs.last_opened_media_dir = os.path.dirname(resource_path)
    editorpersistance.save()
コード例 #6
0
ファイル: projectaction.py プロジェクト: BogusCurry/flowblade
def select_render_clips_dir_callback(dialog, response_id, file_select):
    folder = file_select.get_filenames()[0]
    dialog.destroy()
    if response_id == Gtk.ResponseType.YES:
        if folder ==  os.path.expanduser("~"):
            dialogs.rendered_clips_no_home_folder_dialog()
        else:
            editorpersistance.prefs.render_folder = folder
            editorpersistance.save()
コード例 #7
0
ファイル: app.py プロジェクト: jliljebl/flowblade
def _shutdown_dialog_callback(dialog, response_id):
    dialog.destroy()
    if response_id == Gtk.ResponseType.CLOSE:# "Don't Save"
        pass
    elif response_id ==  Gtk.ResponseType.YES:# "Save"
        if editorstate.PROJECT().last_save_path != None:
            persistance.save_project(editorstate.PROJECT(), editorstate.PROJECT().last_save_path)
        else:
            dialogutils.warning_message(_("Project has not been saved previously"), 
                                    _("Save project with File -> Save As before closing."),
                                    gui.editor_window.window)
            return
    else: # "Cancel"
        return

    # --- APP SHUT DOWN --- #
    print "Exiting app..."
    # Sep-2018 - SvdB - Stop wave form threads
    for thread_termination in threading.enumerate():
        # We only terminate threads with a 'process', as these are launched
        # by the audiowaveformrenderer
        try:
            thread_termination.process.terminate()
        except:
            None

    # No more auto saving
    stop_autosave()

    # Save window dimensions on exit
    alloc = gui.editor_window.window.get_allocation()
    x, y, w, h = alloc.x, alloc.y, alloc.width, alloc.height 
    editorpersistance.prefs.exit_allocation = (w, h)
    if gui.editor_window.window2 != None:
        alloc = gui.editor_window.window2.get_allocation()
        pos_x, pos_y = gui.editor_window.window2.get_position()
        editorpersistance.prefs.exit_allocation_window_2 = (alloc.width, alloc.height, pos_x, pos_y)       
    editorpersistance.prefs.app_v_paned_position = gui.editor_window.app_v_paned.get_position()
    editorpersistance.prefs.top_paned_position = gui.editor_window.top_paned.get_position()
    try: # This fails if preference for top row layout changed, we just ignore saving these values then.
        if editorwindow.top_level_project_panel() == True:
            editorpersistance.prefs.mm_paned_position = 200  # This is not used until user sets preference to not have top level project panel
        else:
            editorpersistance.prefs.mm_paned_position = gui.editor_window.mm_paned.get_position()
    except: 
        pass
    editorpersistance.save()

    # Block reconnecting consumer before setting window not visible
    updater.player_refresh_enabled = False
    gui.editor_window.window.set_visible(False)
    if gui.editor_window.window2 != None:
        gui.editor_window.window2.set_visible(False)

    # Close and destroy app when gtk finds time to do it after hiding window
    GLib.idle_add(_app_destroy)
コード例 #8
0
ファイル: middlebar.py プロジェクト: iloveooz/flowblade
def _show_monitor_info_toggled(widget):
    editorpersistance.prefs.show_sequence_profile = widget.get_active()
    editorpersistance.save()

    if editorstate.timeline_visible():
        name = editorstate.current_sequence().name
        profile_desc = editorstate.current_sequence().profile.description()
        if editorpersistance.prefs.show_sequence_profile:
            gui.editor_window.monitor_source.set_text(name + " / " + profile_desc)
        else:
            gui.editor_window.monitor_source.set_text(name)
コード例 #9
0
def _preferences_dialog_callback(dialog, response_id, all_widgets):
    if response_id == Gtk.ResponseType.ACCEPT:
        editorpersistance.update_prefs_from_widgets(all_widgets)
        editorpersistance.save()
        dialog.destroy()
        primary_txt = _("Restart required for some setting changes to take effect.")
        secondary_txt = _("If requested change is not in effect, restart application.")
        dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window)
        return

    dialog.destroy()
コード例 #10
0
ファイル: profilesmanager.py プロジェクト: Mermouy/flowblade
def _unhide_selected_clicked(visible_view, hidden_view):
    hidden_indexes = hidden_view.get_selected_indexes_list()
    prof_names = []
    for i in hidden_indexes:
        pname, profile = mltprofiles.get_hidden_profiles()[i]
        prof_names.append(pname)
    
    editorpersistance.prefs.hidden_profile_names = list(set(editorpersistance.prefs.hidden_profile_names) - set(prof_names))
    editorpersistance.save()
    
    mltprofiles.load_profile_list()
    visible_view.fill_data_model(mltprofiles.get_factory_profiles())
    hidden_view.fill_data_model(mltprofiles.get_hidden_profiles())
コード例 #11
0
ファイル: projectaction.py プロジェクト: admonkey/flowblade
    def run(self): 
        Gdk.threads_enter()
        watch = Gdk.Cursor.new(Gdk.CursorType.WATCH)
        gui.editor_window.window.get_window().set_cursor(watch)
        Gdk.threads_leave()

        is_first_video_load = PROJECT().is_first_video_load()
        duplicates = []
        succes_new_file = None
        filenames = self.filenames
        for new_file in filenames:
            (folder, file_name) = os.path.split(new_file)
            if PROJECT().media_file_exists(new_file):
                duplicates.append(file_name)
            else:
                try:
                    PROJECT().add_media_file(new_file)
                    succes_new_file = new_file
                except projectdata.ProducerNotValidError as err:
                    print err.__str__()
                    dialogs.not_valid_producer_dialog(err.value, gui.editor_window.window)
            
            Gdk.threads_enter()
            gui.media_list_view.fill_data_model()
            max_val = gui.editor_window.media_scroll_window.get_vadjustment().get_upper()
            gui.editor_window.media_scroll_window.get_vadjustment().set_value(max_val)
            Gdk.threads_leave()

        if succes_new_file != None:
            editorpersistance.prefs.last_opened_media_dir = os.path.dirname(succes_new_file)
            editorpersistance.save()

        # Update editor gui
        Gdk.threads_enter()
        gui.media_list_view.fill_data_model()
        update_current_bin_files_count()
        _enable_save()

        normal_cursor = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR) #RTL
        gui.editor_window.window.get_window().set_cursor(normal_cursor)
        Gdk.threads_leave()

        if len(duplicates) > 0:
            GObject.timeout_add(10, _duplicates_info, duplicates)

        if is_first_video_load:
            GObject.timeout_add(10, _first_load_profile_check)
            
        audiowaveformrenderer.launch_audio_levels_rendering(filenames)
コード例 #12
0
def _create_proxy_render_folder_select_callback(dialog, response_id, file_select, media_files):
    try:
        folder = file_select.get_filenames()[0]
    except:
        dialog.destroy()
        return

    dialog.destroy()
    if response_id == Gtk.ResponseType.YES:
        if folder ==  os.path.expanduser("~"):
            dialogs.rendered_clips_no_home_folder_dialog()
        else:
            editorpersistance.prefs.render_folder = folder
            editorpersistance.save()
            _do_create_proxy_files(media_files, True)
コード例 #13
0
ファイル: middlebar.py プロジェクト: ptrg/flowblade
def _show_buttons_COMPONETS_CENTERED_layout(widget):
    global w
    w = gui.editor_window
    if w == None:
        return
    if widget.get_active() == False:
        return

    _clear_container(w.edit_buttons_row)
    _create_buttons(w)
    fill_with_COMPONETS_CENTERED_pattern(w.edit_buttons_row, w)
    w.window.show_all()

    editorpersistance.prefs.midbar_layout = appconsts.MIDBAR_COMPONENTS_CENTERED
    editorpersistance.save()
コード例 #14
0
ファイル: middlebar.py プロジェクト: iloveooz/flowblade
def _show_buttons_TC_MIDDLE_layout(widget):
    global w
    w = gui.editor_window
    if w == None:
        return
    if widget.get_active() == False:
        return

    _clear_container(w.edit_buttons_row)
    _create_buttons(w)
    fill_with_TC_MIDDLE_pattern(w.edit_buttons_row, w)
    w.window.show_all()

    editorpersistance.prefs.midbar_tc_left = False
    editorpersistance.save()
コード例 #15
0
def _add_transition_render_folder_select_callback(dialog, response_id, file_select):
    try:
        folder = file_select.get_filenames()[0]
    except:
        dialog.destroy()
        return

    dialog.destroy()
    if response_id == Gtk.ResponseType.YES:
        if folder ==  os.path.expanduser("~"):
            dialogs.rendered_clips_no_home_folder_dialog()
        else:
            editorpersistance.prefs.render_folder = folder
            editorpersistance.save()
            add_transition_pressed(True)
コード例 #16
0
ファイル: tlineaction.py プロジェクト: pzl/flowblade
def _add_transition_render_folder_select_callback(dialog, response_id, file_select):
    try:
        folder = file_select.get_filenames()[0]
    except:
        dialog.destroy()
        return

    dialog.destroy()
    if response_id == Gtk.ResponseType.YES:
        if folder ==  os.path.expanduser("~"):
            dialogs.rendered_clips_no_home_folder_dialog()
        else:
            editorpersistance.prefs.render_folder = folder
            editorpersistance.save()
            add_transition_pressed(True)
コード例 #17
0
def _show_buttons_TC_LEFT_layout(widget):
    global w
    w = gui.editor_window
    if w == None:
        return
    if widget.get_active() == False:
        return

    _clear_container(w.edit_buttons_row)
    _create_buttons(w)
    fill_with_TC_LEFT_pattern(w.edit_buttons_row, w)
    w.window.show_all()

    editorpersistance.prefs.midbar_tc_left = True
    editorpersistance.save()
コード例 #18
0
ファイル: middlebar.py プロジェクト: cosmo-ruby/flowblade
def _show_buttons_TC_MIDDLE_layout(widget):
    global w
    w = gui.editor_window
    if w == None:
        return
    if widget.get_active() == False:
        return

    _clear_container(w.edit_buttons_row)
    _create_buttons(w)
    fill_with_TC_MIDDLE_pattern(w.edit_buttons_row, w)
    w.window.show_all()

    editorpersistance.prefs.midbar_layout = appconsts.MIDBAR_TC_CENTER
    editorpersistance.save()
コード例 #19
0
def _create_proxy_render_folder_select_callback(dialog, response_id, file_select, media_files):
    try:
        folder = file_select.get_filenames()[0]
    except:
        dialog.destroy()
        return

    dialog.destroy()
    if response_id == gtk.RESPONSE_YES:
        if folder ==  os.path.expanduser("~"):
            dialogs.rendered_clips_no_home_folder_dialog()
        else:
            editorpersistance.prefs.render_folder = folder
            editorpersistance.save()
            _do_create_proxy_files(media_files, True)
コード例 #20
0
ファイル: projectaction.py プロジェクト: LinuXperia/flowblade
def select_thumbnail_dir_callback(dialog, response_id, data):
    file_select, retry_add_media = data
    folder = file_select.get_filenames()[0]
    dialog.destroy()
    if response_id == Gtk.ResponseType.YES:
        if folder ==  os.path.expanduser("~"):
            dialogutils.warning_message(_("Can't make home folder thumbnails folder"), 
                                    _("Please create and select some other folder then \'") + 
                                    os.path.expanduser("~") + _("\' as thumbnails folder"), 
                                    gui.editor_window.window)
        else:
            editorpersistance.prefs.thumbnail_folder = folder
            editorpersistance.save()
    
    if retry_add_media == True:
        add_media_files(True)
コード例 #21
0
ファイル: mltprofiles.py プロジェクト: admonkey/flowblade
def get_default_profile_index():
    """
    We're making sure here that something is returned as default profile even if user may have removed some profiles.
    """
    def_profile_index = get_index_for_name(editorpersistance.prefs.default_profile_name)
    if def_profile_index == -1:
        print "default profile from prefs not found"
        def_profile_index = get_index_for_name(DEFAULT_DEFAULT_PROFILE)
        def_profile_name =  DEFAULT_DEFAULT_PROFILE
        if def_profile_index == -1:
            def_profile_index = 0
            def_profile_name, profile = _profile_list[def_profile_index]
            print "DEFAULT_DEFAULT_PROFILE deleted returning first profile"
        editorpersistance.prefs.default_profile_name = def_profile_name
        editorpersistance.save()
    return def_profile_index
コード例 #22
0
ファイル: mltprofiles.py プロジェクト: swinsey/flowblade
def get_default_profile_index():
    """
    We're making sure here that something is returned as default profile even if user may have removed some profiles.
    """
    def_profile_index = get_index_for_name(editorpersistance.prefs.default_profile_name)
    if def_profile_index == -1:
        print "default profile from prefs not found"
        def_profile_index = get_index_for_name(DEFAULT_DEFAULT_PROFILE)
        def_profile_name =  DEFAULT_DEFAULT_PROFILE
        if def_profile_index == -1:
            def_profile_index = 0
            def_profile_name, profile = _profile_list[def_profile_index]
            print "DEFAULT_DEFAULT_PROFILE deleted returning first profile"
        editorpersistance.prefs.default_profile_name = def_profile_name
        editorpersistance.save()
    return def_profile_index
コード例 #23
0
ファイル: projectaction.py プロジェクト: mcanthony/flowblade
    def run(self):
        gtk.gdk.threads_enter()
        watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
        gui.editor_window.window.window.set_cursor(watch)
        gtk.gdk.threads_leave()

        duplicates = []
        succes_new_file = None
        filenames = self.filenames
        for new_file in filenames:
            (folder, file_name) = os.path.split(new_file)
            if PROJECT().media_file_exists(new_file):
                duplicates.append(file_name)
            else:
                try:
                    PROJECT().add_media_file(new_file)
                    succes_new_file = new_file
                except projectdata.ProducerNotValidError as err:
                    print err.__str__()
                    dialogs.not_valid_producer_dialog(err.value,
                                                      gui.editor_window.window)

            gtk.gdk.threads_enter()
            gui.media_list_view.fill_data_model()
            max_val = gui.editor_window.media_scroll_window.get_vadjustment(
            ).get_upper()
            gui.editor_window.media_scroll_window.get_vadjustment().set_value(
                max_val)
            gtk.gdk.threads_leave()

        if succes_new_file != None:
            editorpersistance.prefs.last_opened_media_dir = os.path.dirname(
                succes_new_file)
            editorpersistance.save()

        # Update editor gui
        gtk.gdk.threads_enter()
        gui.media_list_view.fill_data_model()
        gui.bin_list_view.fill_data_model()
        _enable_save()

        normal_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)  #RTL
        gui.editor_window.window.window.set_cursor(normal_cursor)
        gtk.gdk.threads_leave()

        if len(duplicates) > 0:
            gobject.timeout_add(10, _duplicates_info, duplicates)
コード例 #24
0
ファイル: gui.py プロジェクト: swinsey/flowblade
def apply_gtk_css():
    gtk_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version())
    if Gtk.get_major_version() == 3 and Gtk.get_minor_version() >= 22:
        print "Gtk version is " + gtk_version + ", Flowblade theme is available."
    else:
        print "Gtk version is " + gtk_version + ", Flowblade theme only available for Gtk >= 3.22"
        editorpersistance.prefs.theme = appconsts.LIGHT_THEME
        editorpersistance.save()
        return False
        
    provider = Gtk.CssProvider.new()
    display = Gdk.Display.get_default()
    screen = display.get_default_screen()
    Gtk.StyleContext.add_provider_for_screen (screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
    provider.load_from_path(respaths.ROOT_PATH + "/res/css/gtk-flowblade-dark.css")

    return True
コード例 #25
0
def _create_new_kb_shortcuts_group(dialog, response_id, entry):
    if response_id != Gtk.ResponseType.REJECT:
        name = entry.get_text()
        if name == "": # No need for info dialog, user should really get this.
            dialog.destroy()
            return
        custom_xml_file_name = shortcuts.create_custom_shortcuts_xml(name)
        editorpersistance.prefs.shortcuts = custom_xml_file_name
        editorpersistance.save()
        shortcuts.shortcut_files.append(custom_xml_file_name)
        root = shortcuts.get_root()
        shortcuts.shortcut_files_display_names.append(root.get('name'))
        shortcuts.set_keyboard_shortcuts()
        guicomponents.update_shortcuts_combo(dialogs.shortcuts_combo)
        dialogs.display_keyboard_shortcuts(editorpersistance.prefs.shortcuts, workflow.get_tline_tool_working_set(), dialogs.scroll_hold_panel)
        
    dialog.destroy()
コード例 #26
0
ファイル: trackaction.py プロジェクト: jliljebl/flowblade
def _audio_levels_item_activated(widget, msg):
    if msg == "all":
        editorstate.display_all_audio_levels = True
        updater.repaint_tline()
    elif msg == "on request":
        editorstate.display_all_audio_levels = False
        current_sequence().drop_audio_levels()
        updater.repaint_tline()
    elif msg == "snapping":
        snapping.snapping_on = widget.get_active()
    elif msg == "scrubbing":
        editorpersistance.prefs.audio_scrubbing = widget.get_active()
        editorpersistance.save()
        PLAYER().set_scrubbing(widget.get_active())
        
    else: # media thumbnails
        editorstate.display_clip_media_thumbnails = widget.get_active()
        updater.repaint_tline()
コード例 #27
0
ファイル: trackaction.py プロジェクト: yichuang-zh/flowblade
def _audio_levels_item_activated(widget, msg):
    if msg == "all":
        editorstate.display_all_audio_levels = True
        updater.repaint_tline()
    elif msg == "on request":
        editorstate.display_all_audio_levels = False
        current_sequence().drop_audio_levels()
        updater.repaint_tline()
    elif msg == "snapping":
        snapping.snapping_on = widget.get_active()
    elif msg == "scrubbing":
        editorpersistance.prefs.audio_scrubbing = widget.get_active()
        editorpersistance.save()
        PLAYER().set_scrubbing(widget.get_active())

    else:  # media thumbnails
        editorstate.display_clip_media_thumbnails = widget.get_active()
        updater.repaint_tline()
コード例 #28
0
def _hide_selected_clicked(visible_view, hidden_view):
    visible_indexes = visible_view.get_selected_indexes_list()
    prof_names = []
    default_profile = mltprofiles.get_default_profile()
    for i in visible_indexes:
        pname, profile = mltprofiles.get_factory_profiles()[i]
        if profile == default_profile:
            dialogutils.warning_message("Can't hide default Profile", 
                                    "Profile '"+ profile.description() + "' is default profile and can't be hidden.", 
                                    None)
            return
        prof_names.append(pname)

    editorpersistance.prefs.hidden_profile_names += prof_names
    editorpersistance.save()

    mltprofiles.load_profile_list()
    visible_view.fill_data_model(mltprofiles.get_factory_profiles())
    hidden_view.fill_data_model(mltprofiles.get_hidden_profiles())
コード例 #29
0
ファイル: projectaction.py プロジェクト: dermetfan/flowblade
    def run(self): 
        gtk.gdk.threads_enter()
        watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
        gui.editor_window.window.window.set_cursor(watch)
        gtk.gdk.threads_leave()

        duplicates = []
        succes_new_file = None
        filenames = self.filenames
        for new_file in filenames:
            (folder, file_name) = os.path.split(new_file)
            if PROJECT().media_file_exists(new_file):
                duplicates.append(file_name)
            else:
                try:
                    PROJECT().add_media_file(new_file)
                    succes_new_file = new_file
                except projectdata.ProducerNotValidError as err:
                    print err.__str__()
                    dialogs.not_valid_producer_dialog(err.value, gui.editor_window.window)
            
            gtk.gdk.threads_enter()
            gui.media_list_view.fill_data_model()
            max_val = gui.editor_window.media_scroll_window.get_vadjustment().get_upper()
            gui.editor_window.media_scroll_window.get_vadjustment().set_value(max_val)
            gtk.gdk.threads_leave()

        if succes_new_file != None:
            editorpersistance.prefs.last_opened_media_dir = os.path.dirname(succes_new_file)
            editorpersistance.save()

        # Update editor gui
        gtk.gdk.threads_enter()
        gui.media_list_view.fill_data_model()
        gui.bin_list_view.fill_data_model()
        _enable_save()

        normal_cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) #RTL
        gui.editor_window.window.window.set_cursor(normal_cursor)
        gtk.gdk.threads_leave()

        if len(duplicates) > 0:
            gobject.timeout_add(10, _duplicates_info, duplicates)
コード例 #30
0
ファイル: workflow.py プロジェクト: realjaadoogar/flowblade
def _workflow_menu_callback(widget, data):
    tool_id, msg = data
    
    if msg == "activity":
        if widget.get_active() == False:
            editorpersistance.prefs.active_tools.remove(tool_id)
        else:
            editorpersistance.prefs.active_tools.append(tool_id)
    elif msg == "preset standard":
        _set_workflow_STANDARD()
    elif msg == "preset filmstyle":
        _set_workflow_FILM_STYLE()
    elif msg == "autofollow":
        active = widget.get_active()
        editorstate.auto_follow = active
        PROJECT().set_project_property(appconsts.P_PROP_AUTO_FOLLOW, active)
        if active == True:
            # Do autofollow update if auto follow activated
            compositor_autofollow_data = edit.get_full_compositor_sync_data()
            edit.do_autofollow_redo(compositor_autofollow_data)
        updater.repaint_tline()
    elif  msg == "always overwrite":
        editorpersistance.prefs.dnd_action = appconsts.DND_ALWAYS_OVERWRITE
    elif  msg == "overwrite nonV1":
        editorpersistance.prefs.dnd_action = appconsts.DND_OVERWRITE_NON_V1
    elif  msg == "always insert":
        editorpersistance.prefs.dnd_action = appconsts.DND_ALWAYS_INSERT
    elif  msg ==  "tooltips":
        editorpersistance.prefs.show_tool_tooltips = widget.get_active()
    elif msg == "delete lift" and widget.get_active() == True:
        print "lift"
    elif msg == "delete splice" and widget.get_active() == True:
        print "splice"
    else:
        try:
            pos = int(msg)
            current_index = editorpersistance.prefs.active_tools.index(tool_id)
            editorpersistance.prefs.active_tools.remove(tool_id)
            editorpersistance.prefs.active_tools.insert(pos - 1, tool_id)
        except:
            pass
    
    editorpersistance.save()
コード例 #31
0
ファイル: app.py プロジェクト: IanMadlenya/flowblade
def _shutdown_dialog_callback(dialog, response_id):
    dialog.destroy()
    if response_id == Gtk.ResponseType.CLOSE:# "Don't Save"
        pass
    elif response_id ==  Gtk.ResponseType.YES:# "Save"
        if editorstate.PROJECT().last_save_path != None:
            persistance.save_project(editorstate.PROJECT(), editorstate.PROJECT().last_save_path)
        else:
            dialogutils.warning_message(_("Project has not been saved previously"), 
                                    _("Save project with File -> Save As before closing."),
                                    gui.editor_window.window)
            return
    else: # "Cancel"
        return

    # --- APP SHUT DOWN --- #
    print "Exiting app..."

    # No more auto saving
    stop_autosave()

    # Save window dimensions on exit
    alloc = gui.editor_window.window.get_allocation()
    x, y, w, h = alloc.x, alloc.y, alloc.width, alloc.height 
    editorpersistance.prefs.exit_allocation = (w, h)
    if gui.editor_window.window2 != None:
        alloc = gui.editor_window.window2.get_allocation()
        pos_x, pos_y = gui.editor_window.window2.get_position()
        editorpersistance.prefs.exit_allocation_window_2 = (alloc.width, alloc.height, pos_x, pos_y)       
    editorpersistance.prefs.app_v_paned_position = gui.editor_window.app_v_paned.get_position()
    editorpersistance.prefs.top_paned_position = gui.editor_window.top_paned.get_position()
    editorpersistance.prefs.mm_paned_position = gui.editor_window.mm_paned.get_position()
    editorpersistance.save()

    # Block reconnecting consumer before setting window not visible
    updater.player_refresh_enabled = False
    gui.editor_window.window.set_visible(False)
    if gui.editor_window.window2 != None:
        gui.editor_window.window2.set_visible(False)

    # Close and destroy app when gtk finds time to do it after hiding window
    GLib.idle_add(_app_destroy)
コード例 #32
0
ファイル: monitorevent.py プロジェクト: jliljebl/flowblade
def _trim_view_menu_item_activated(widget, msg):
    if msg == "matchclear":
        gui.monitor_widget.set_default_view_force()
        return
    if msg == "clipframematch":
        import tlineaction  # if this is on top level gmic tool get circular import
        clip = tlineaction._get_new_clip_from_clip_monitor()
        if clip == None:
            return
        frame = PLAYER().current_frame()
        gui.monitor_widget.set_frame_match_view(clip, frame)
        return
    
    if widget.get_active() == False:
        return
    
    if msg == "trimon":
        editorstate.show_trim_view = appconsts.TRIM_VIEW_ON
        editorpersistance.prefs.trim_view_default = appconsts.TRIM_VIEW_ON
        editorpersistance.save()
        if editorpersistance.prefs.trim_view_message_shown == False:
            _show_trimview_info()
    if msg == "trimsingle":
        editorstate.show_trim_view = appconsts.TRIM_VIEW_SINGLE
        editorpersistance.prefs.trim_view_default = appconsts.TRIM_VIEW_SINGLE
        editorpersistance.save()
        if editorpersistance.prefs.trim_view_message_shown == False:
            _show_trimview_info()
    if msg == "trimoff":
        editorstate.show_trim_view = appconsts.TRIM_VIEW_OFF
        editorpersistance.prefs.trim_view_default = appconsts.TRIM_VIEW_OFF
        editorpersistance.save()
コード例 #33
0
def _workflow_menu_callback(widget, data):
    tool_id, msg = data

    if msg == "activity":
        if widget.get_active() == False:
            editorpersistance.prefs.active_tools.remove(tool_id)
        else:
            editorpersistance.prefs.active_tools.append(tool_id)
    elif msg == "preset standard":
        _set_workflow_STANDARD()
    elif msg == "preset filmstyle":
        _set_workflow_FILM_STYLE()
    elif msg == "always overwrite":
        editorpersistance.prefs.dnd_action = appconsts.DND_ALWAYS_OVERWRITE
    elif msg == "overwrite nonV1":
        editorpersistance.prefs.dnd_action = appconsts.DND_OVERWRITE_NON_V1
    elif msg == "always insert":
        editorpersistance.prefs.dnd_action = appconsts.DND_ALWAYS_INSERT
    elif msg == "tooltips":
        editorpersistance.prefs.show_tool_tooltips = widget.get_active()
    elif msg == "top down":
        editorpersistance.prefs.default_compositing_mode = appconsts.COMPOSITING_MODE_TOP_DOWN_FREE_MOVE
    elif msg == "top down auto":
        editorpersistance.prefs.default_compositing_mode = appconsts.COMPOSITING_MODE_TOP_DOWN_AUTO_FOLLOW
    elif msg == "standard auto":
        editorpersistance.prefs.default_compositing_mode = appconsts.COMPOSITING_MODE_STANDARD_AUTO_FOLLOW
    elif msg == "delete lift" and widget.get_active() == True:
        print("lift")
    elif msg == "delete splice" and widget.get_active() == True:
        print("splice")
    else:
        try:
            pos = int(msg)
            current_index = editorpersistance.prefs.active_tools.index(tool_id)
            editorpersistance.prefs.active_tools.remove(tool_id)
            editorpersistance.prefs.active_tools.insert(pos - 1, tool_id)
        except:
            pass

    editorpersistance.save()
コード例 #34
0
def _hamburger_item_activated(widget, msg):
    if msg == "cancel_all":
        global _jobs, _remove_list
        _remove_list = []
        for job in _jobs:
            if job.status == RENDERING:
                job.abort_render()
            job.progress = -1.0
            job.text = _("Cancelled")
            job.status = CANCELLED
            _remove_list.append(job)

        _jobs_list_view.fill_data_model()
        _jobs_list_view.scroll.queue_draw()
        GObject.timeout_add(4000, _remove_jobs)

    elif msg == "cancel_selected":
        try:
            jobs_list_index = _jobs_list_view.get_selected_row_index()
        except:
            return # nothing was selected
        
        job = _jobs[jobs_list_index]
        job.abort_render()
        job.progress = -1.0
        job.text = _("Cancelled")
        job.status = CANCELLED
        _remove_list.append(job)

        _jobs_list_view.fill_data_model()
        _jobs_list_view.scroll.queue_draw()
        GObject.timeout_add(4000, _remove_jobs)
        
    elif msg == "open_on_add":
        editorpersistance.prefs.open_jobs_panel_on_add = widget.get_active()
        editorpersistance.save()

    elif msg == "sequential_render":
        editorpersistance.prefs.render_jobs_sequentially = widget.get_active()
        editorpersistance.save()
コード例 #35
0
ファイル: monitorevent.py プロジェクト: jimstory/flowblade
def _trim_view_menu_item_activated(widget, msg):
    if msg == "matchclear":
        gui.monitor_widget.set_default_view_force()
        return
    if msg == "clipframematch":
        import tlineaction  # if this is on top level gmic tool get circular import
        clip = tlineaction._get_new_clip_from_clip_monitor()
        if clip == None:
            return
        frame = PLAYER().current_frame()
        gui.monitor_widget.set_frame_match_view(clip, frame)
        return

    if widget.get_active() == False:
        return

    if msg == "trimon":
        editorstate.show_trim_view = appconsts.TRIM_VIEW_ON
        editorpersistance.prefs.trim_view_default = appconsts.TRIM_VIEW_ON
        editorpersistance.save()
        if editorpersistance.prefs.trim_view_message_shown == False:
            _show_trimview_info()
    if msg == "trimsingle":
        editorstate.show_trim_view = appconsts.TRIM_VIEW_SINGLE
        editorpersistance.prefs.trim_view_default = appconsts.TRIM_VIEW_SINGLE
        editorpersistance.save()
        if editorpersistance.prefs.trim_view_message_shown == False:
            _show_trimview_info()
    if msg == "trimoff":
        editorstate.show_trim_view = appconsts.TRIM_VIEW_OFF
        editorpersistance.prefs.trim_view_default = appconsts.TRIM_VIEW_OFF
        editorpersistance.save()
コード例 #36
0
def apply_gtk_css(theme):
    gtk_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version())
    if Gtk.get_major_version() == 3 and Gtk.get_minor_version() >= 22:
        print("Gtk version is " + gtk_version + ", Flowblade theme is available.")
    else:
        print("Gtk version is " + gtk_version + ", Flowblade theme only available for Gtk >= 3.22")
        editorpersistance.prefs.theme = appconsts.LIGHT_THEME
        editorpersistance.save()
        return False
        
    provider = Gtk.CssProvider.new()
    display = Gdk.Display.get_default()
    screen = display.get_default_screen()
    Gtk.StyleContext.add_provider_for_screen (screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
    if theme == appconsts.FLOWBLADE_THEME:
        css_path = "/res/css/gtk-flowblade-dark.css"
    elif theme == appconsts.FLOWBLADE_THEME_NEUTRAL:
        css_path = "/res/css3/gtk-flowblade-dark.css"
    else: # appconsts.FLOWBLADE_THEME_GRAY
        css_path = "/res/css2/gtk-flowblade-dark.css"
    provider.load_from_path(respaths.ROOT_PATH + css_path)

    return True
コード例 #37
0
def _alpha_info_dialog_cb(dialog, response_id, dont_show_check):
    if dont_show_check.get_active() == True:
        editorpersistance.prefs.show_alpha_info_message = False
        editorpersistance.save()

    dialog.destroy()
コード例 #38
0
 def encoding_changed(self, enc_index):
     editorpersistance.prefs.tline_render_encoding = enc_index
     editorpersistance.save()
コード例 #39
0
ファイル: jackaudio.py プロジェクト: Mermouy/flowblade
def output_type_changed(output_type):
    editorpersistance.prefs.jack_output_type = output_type
    editorpersistance.save()
コード例 #40
0
 def size_changed(self, size_index):
     editorpersistance.prefs.tline_render_size = size_index
     editorpersistance.save()
コード例 #41
0
 def _show_tabs_down(self, widget):
     if widget.get_active() == False:
         return
     self.notebook.set_tab_pos(gtk.POS_BOTTOM)
     editorpersistance.prefs.tabs_on_top = False
     editorpersistance.save()
コード例 #42
0
def main(root_path):
    """
    Called at application start.
    Initializes application with a default project.
    """
    # DEBUG: Direct output to log file if log file set
    if _log_file != None:
        log_print_output_to_file()

    print "Application version: " + editorstate.appversion

    # Print OS, Python version and GTK+ version
    try:
        os_release_file = open("/etc/os-release","r")
        os_text = os_release_file.read()
        s_index = os_text.find("PRETTY_NAME=")
        e_index = os_text.find("\n", s_index)
        print "OS: " + os_text[s_index + 13:e_index - 1]
    except:
        pass

    print "Python", sys.version

    gtk_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version())
    print "GTK+ version:", gtk_version
    editorstate.gtk_version = gtk_version
    try:
        editorstate.mlt_version = mlt.LIBMLT_VERSION
    except:
        editorstate.mlt_version = "0.0.99" # magic string for "not found"

    #print "SDL version:", str(editorstate.get_sdl_version())
    
    # passing -xdg as a flag will change the user_dir location with XDG_CONFIG_HOME
    # For full xdg-app support all the launch processes need to add this too, currently not impl.

    for arg in sys.argv:
        if arg.lower() == "-xdg":
            editorstate.use_xdg = True

    # Create hidden folders if not present
    user_dir = utils.get_hidden_user_dir_path()

    print "User dir:",user_dir
    if not os.path.exists(user_dir):
        os.mkdir(user_dir)
    if not os.path.exists(user_dir + mltprofiles.USER_PROFILES_DIR):
        os.mkdir(user_dir + mltprofiles.USER_PROFILES_DIR)
    if not os.path.exists(user_dir + AUTOSAVE_DIR):
        os.mkdir(user_dir + AUTOSAVE_DIR)
    if not os.path.exists(user_dir + BATCH_DIR):
        os.mkdir(user_dir + BATCH_DIR)
    if not os.path.exists(user_dir + appconsts.AUDIO_LEVELS_DIR):
        os.mkdir(user_dir + appconsts.AUDIO_LEVELS_DIR)
    if not os.path.exists(utils.get_hidden_screenshot_dir_path()):
        os.mkdir(utils.get_hidden_screenshot_dir_path())
    if not os.path.exists(user_dir + appconsts.GMIC_DIR):
        os.mkdir(user_dir + appconsts.GMIC_DIR)
    if not os.path.exists(user_dir + appconsts.MATCH_FRAME_DIR):
        os.mkdir(user_dir + appconsts.MATCH_FRAME_DIR)
    if not os.path.exists(user_dir + appconsts.TRIM_VIEW_DIR):
        os.mkdir(user_dir + appconsts.TRIM_VIEW_DIR)
    if not os.path.exists(user_dir + appconsts.NATRON_DIR):
        os.mkdir(user_dir + appconsts.NATRON_DIR)
       
    # Set paths.
    respaths.set_paths(root_path)

    # Load editor prefs and list of recent projects
    editorpersistance.load()
    if editorpersistance.prefs.theme != appconsts.LIGHT_THEME:
        respaths.apply_dark_theme()
    if editorpersistance.prefs.display_all_audio_levels == False:
        editorstate.display_all_audio_levels = False
    editorpersistance.create_thumbs_folder_if_needed(user_dir)
    editorpersistance.create_rendered_clips_folder_if_needed(user_dir)

    editorpersistance.save()

    # Init translations module with translations data
    translations.init_languages()
    translations.load_filters_translations()
    mlttransitions.init_module()

    # Apr-2017 - SvdB - Keyboard shortcuts
    shortcuts.load_shortcut_files()
    shortcuts.load_shortcuts()

    # We respaths and translations data available so we need to init in a function.
    workflow.init_data()

    # RHEL7/CentOS compatibility fix
    if gtk_version == "3.8.8":
        GObject.threads_init()

    # Init gtk threads
    Gdk.threads_init()
    Gdk.threads_enter()

    # Themes
    if editorpersistance.prefs.theme == appconsts.FLOWBLADE_THEME:
        success = gui.apply_gtk_css()
        if not success:
            editorpersistance.prefs.theme = appconsts.LIGHT_THEME
            editorpersistance.save()

    if editorpersistance.prefs.theme != appconsts.LIGHT_THEME:
        Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", True)
        
    # Load drag'n'drop images
    dnd.init()

    # Adjust gui parameters for smaller screens
    scr_w = Gdk.Screen.width()
    scr_h = Gdk.Screen.height()
    editorstate.SCREEN_WIDTH = scr_w
    editorstate.SCREEN_HEIGHT = scr_h

    print "Screen size:", scr_w, "x", scr_h
    print "Small height:", editorstate.screen_size_small_height()
    print "Small width:",  editorstate.screen_size_small_width()

    _set_draw_params()

    # Refuse to run on too small screen.
    if scr_w < 1151 or scr_h < 767:
        _too_small_screen_exit()
        return

    # Splash screen
    if editorpersistance.prefs.display_splash_screen == True: 
        show_splash_screen()

    # Init MLT framework
    repo = mlt.Factory().init()
    processutils.prepare_mlt_repo(repo)

    # Set numeric locale to use "." as radix, MLT initilizes this to OS locale and this causes bugs.
    locale.setlocale(locale.LC_NUMERIC, 'C')

    # Check for codecs and formats on the system.
    mltenv.check_available_features(repo)
    renderconsumer.load_render_profiles()

    # Load filter and compositor descriptions from xml files.
    mltfilters.load_filters_xml(mltenv.services)
    mlttransitions.load_compositors_xml(mltenv.transitions)
    
    # Replace some services if better replacements available.
    mltfilters.replace_services(mltenv.services)

    # Create list of available mlt profiles.
    mltprofiles.load_profile_list()
    
    # Save assoc file path if found in arguments.
    global assoc_file_path
    assoc_file_path = get_assoc_file_path()
        
    # There is always a project open, so at startup we create a default project.
    # Set default project as the project being edited.
    editorstate.project = projectdata.get_default_project()
    check_crash = True

    # Audiomonitoring being available needs to be known before GUI creation.
    audiomonitoring.init(editorstate.project.profile)

    # Set trim view mode to current default value.
    editorstate.show_trim_view = editorpersistance.prefs.trim_view_default

    # Check for tools and init tools integration.
    gmic.test_availablity()
    toolnatron.init()
    toolsintegration.init()
    #toolsintegration.test()
    
    # Create player object.
    create_player()

    # Create main window and set widget handles in gui.py for more convenient reference.
    create_gui()

    # Inits widgets with project data.
    init_project_gui()

    # Inits widgets with current sequence data.
    init_sequence_gui()

    # Launch player now that data and gui exist
    launch_player()

    # Editor and modules need some more initializing.
    init_editor_state()

    # Tracks need to be recentered if window is resized.
    # Connect listener for this now that the tline panel size allocation is sure to be available.
    global window_resize_id, window_state_id
    window_resize_id = gui.editor_window.window.connect("size-allocate", lambda w, e:updater.window_resized())
    window_state_id = gui.editor_window.window.connect("window-state-event", lambda w, e:updater.window_resized())

    # Get existing autosave files
    autosave_files = get_autosave_files()

    # Show splash
    if ((editorpersistance.prefs.display_splash_screen == True) and len(autosave_files) == 0) and not editorstate.runtime_version_greater_then_test_version(editorpersistance.prefs.workflow_dialog_last_version_shown, editorstate.appversion):
        global splash_timeout_id
        splash_timeout_id = GLib.timeout_add(2600, destroy_splash_screen)
        splash_screen.show_all()

    appconsts.SAVEFILE_VERSION = projectdata.SAVEFILE_VERSION # THIS IS A QUESTIONABLE IDEA TO SIMPLIFY IMPORTS, NOT DRY. WHEN DOING TOOLS THAT RUN IN ANOTHER PROCESSES AND SAVE PROJECTS, THIS LINE NEEDS TO BE THERE ALSO.

    # Every running instance has unique autosave file which is deleted at exit
    set_instance_autosave_id()

    # Existance of autosave file hints that program was exited abnormally.
    if check_crash == True and len(autosave_files) > 0:
        if len(autosave_files) == 1:
            GObject.timeout_add(10, autosave_recovery_dialog)
        else:
            GObject.timeout_add(10, autosaves_many_recovery_dialog)
    else:
        start_autosave()

    # We prefer to monkeypatch some callbacks into some modules, usually to
    # maintain a simpler and/or non-circular import structure.
    monkeypatch_callbacks()

    # File in assoc_file_path is opened after very short delay.
    if not(check_crash == True and len(autosave_files) > 0):
        if assoc_file_path != None:
            print "Launch assoc file:", assoc_file_path
            global assoc_timeout_id
            assoc_timeout_id = GObject.timeout_add(10, open_assoc_file)

    if editorpersistance.prefs.theme == appconsts.FLOWBLADE_THEME:
        gui.apply_flowblade_theme_fixes()
        
    # SDL 2 consumer needs to created after Gtk.main() has run enough for window to be visble
    #if editorstate.get_sdl_version() == editorstate.SDL_2: # needs more state considerion still
    #    print "SDL2 timeout launch"
    #    global sdl2_timeout_id
    #    sdl2_timeout_id = GObject.timeout_add(1500, create_sdl_2_consumer)
    
    # In PositionNumericalEntries we are using Gtk.Entry objects in a way that works for us nicely, but is somehow "error" for Gtk, so we just kill this.
    Gtk.Settings.get_default().set_property("gtk-error-bell", False)
    
    # Show first run worflow info dialog if not shown for this version of application.
    if editorstate.runtime_version_greater_then_test_version(editorpersistance.prefs.workflow_dialog_last_version_shown, editorstate.appversion):
        GObject.timeout_add(500, show_worflow_info_dialog)
        
    # Launch gtk+ main loop
    Gtk.main()

    Gdk.threads_leave()
コード例 #43
0
def show_worflow_info_dialog():
    editorpersistance.prefs.workflow_dialog_last_version_shown = editorstate.appversion
    editorpersistance.save()
    
    worflow_info_dialog = workflow.WorkflowDialog()
    return False
コード例 #44
0
def _alpha_info_dialog_cb(dialog, response_id, dont_show_check):
    if dont_show_check.get_active() == True:
        editorpersistance.prefs.show_alpha_info_message = False
        editorpersistance.save()

    dialog.destroy()
コード例 #45
0
def _set_workflow_FILM_STYLE():
    editorpersistance.prefs.active_tools = [1, 2, 3, 4, 5, 6, 7]
    editorpersistance.save()

    editevent.set_default_edit_mode()
コード例 #46
0
ファイル: app.py プロジェクト: jimstory/flowblade
def _shutdown_dialog_callback(dialog, response_id):
    dialog.destroy()
    if response_id == Gtk.ResponseType.CLOSE:  # "Don't Save"
        pass
    elif response_id == Gtk.ResponseType.YES:  # "Save"
        if editorstate.PROJECT().last_save_path != None:
            persistance.save_project(editorstate.PROJECT(),
                                     editorstate.PROJECT().last_save_path)
        else:
            dialogutils.warning_message(
                _("Project has not been saved previously"),
                _("Save project with File -> Save As before closing."),
                gui.editor_window.window)
            return
    else:  # "Cancel"
        return

    # --- APP SHUT DOWN --- #
    print("Exiting app...")
    # Sep-2018 - SvdB - Stop wave form threads
    for thread_termination in threading.enumerate():
        # We only terminate threads with a 'process', as these are launched
        # by the audiowaveformrenderer
        try:
            thread_termination.process.terminate()
        except:
            None

    # No more auto saving
    stop_autosave()

    # Save window dimensions on exit
    alloc = gui.editor_window.window.get_allocation()
    x, y, w, h = alloc.x, alloc.y, alloc.width, alloc.height
    editorpersistance.prefs.exit_allocation = (w, h)
    if gui.editor_window.window2 != None:
        alloc = gui.editor_window.window2.get_allocation()
        pos_x, pos_y = gui.editor_window.window2.get_position()
        editorpersistance.prefs.exit_allocation_window_2 = (alloc.width,
                                                            alloc.height,
                                                            pos_x, pos_y)
    editorpersistance.prefs.app_v_paned_position = gui.editor_window.app_v_paned.get_position(
    )
    editorpersistance.prefs.top_paned_position = gui.editor_window.top_paned.get_position(
    )
    try:  # This fails if preference for top row layout changed, we just ignore saving these values then.
        if editorwindow.top_level_project_panel() == True:
            editorpersistance.prefs.mm_paned_position = 200  # This is not used until user sets preference to not have top level project panel
        else:
            editorpersistance.prefs.mm_paned_position = gui.editor_window.mm_paned.get_position(
            )
    except:
        pass
    editorpersistance.save()

    # Block reconnecting consumer before setting window not visible
    updater.player_refresh_enabled = False
    gui.editor_window.window.set_visible(False)
    if gui.editor_window.window2 != None:
        gui.editor_window.window2.set_visible(False)

    # Close and destroy app when gtk finds time to do it after hiding window
    GLib.idle_add(_app_destroy)
コード例 #47
0
def init_languages():
    langs = []
    lc, encoding = locale.getdefaultlocale()
    if (lc):
        langs = [lc]
    print("Locale:", lc)

    language = os.environ.get('LANGUAGE', None)
    if (language):
        langs += language.split(":")

    if editorstate.app_running_from == editorstate.RUNNING_FROM_INSTALLATION or editorstate.app_running_from == editorstate.RUNNING_FROM_FLATPAK:
        # Use /usr/share/locale first if available and running from installation
        # Look for installed translation in distro install
        # Were using Russian as test language
        if os.path.isfile("/usr/share/locale/ru/LC_MESSAGES/flowblade.mo"): # fi is the translation controlled by program author
            print("Found translations at /usr/share/locale, using those.")
            locale_path = "/usr/share/locale/"
        #  Look for installed translations in flatpak install 
        elif os.path.isfile("/app/share/flowblade/Flowblade/locale/ru/LC_MESSAGES/flowblade.mo"): # fi is the translation controlled by program author
            print("Found translations at /app/share/flowblade/Flowblade/locale, using those.")
            locale_path = "/app/share/flowblade/Flowblade/locale"
        else:
            print("Translations at /usr/share/locale were not found, using program root directory translations.")
            locale_path = respaths.LOCALE_PATH
    else:
        # Use translations in program folder first if NOT running from installation
        # Were using Russian as test language
        locale_file = respaths.LOCALE_PATH + "ru/LC_MESSAGES/flowblade.mo"
        if os.path.isfile(locale_file): # fi is the translation controlled by program author
            print("Found translations at " +  respaths.LOCALE_PATH + ", using those.")
            locale_path = respaths.LOCALE_PATH
        else:
            print("Translations at " + locale_file + " were not found, using /usr/share/locale translations.")
            locale_path = "/usr/share/locale/"

    gettext.bindtextdomain(APP_NAME, locale_path)
    gettext.textdomain(APP_NAME)

    # Get the language to use
    global lang
    if editorpersistance.prefs.use_english_always == True:
        lang_code = "English"
        editorpersistance.prefs.use_english_always = False
        editorpersistance.prefs.force_language = "English"
        editorpersistance.save()
    else:
        lang_code = editorpersistance.prefs.force_language
    
    if editorpersistance.prefs.force_language == "English":
        print("Force use English.")
        lang = gettext.translation(APP_NAME, locale_path, languages=["dummy"], fallback=True)
    elif editorpersistance.prefs.force_language != "None":
        print("Force use ", editorpersistance.prefs.force_language)
        lang = gettext.translation(APP_NAME, locale_path, languages=[str(editorpersistance.prefs.force_language)], fallback=True)
    else:
        print("Use OS locale language.")
        lang = gettext.translation(APP_NAME, locale_path, languages=langs, fallback=True)

    # Un-comment for translations tests
    #lang = gettext.translation(APP_NAME, locale_path, languages=["it"], fallback=True)

    lang.install(APP_NAME) # makes _() a build-in available in all modules without imports
コード例 #48
0
ファイル: editorwindow.py プロジェクト: BogusCurry/flowblade
 def _show_tabs_down(self, widget):
     if widget.get_active() == False:
         return
     self.notebook.set_tab_pos(Gtk.PositionType.BOTTOM)
     editorpersistance.prefs.tabs_on_top = False
     editorpersistance.save()
コード例 #49
0
ファイル: app.py プロジェクト: iloveooz/flowblade
def main(root_path):
    """
    Called at application start.
    Initializes application with a default project.
    """
    # Print OS, Python version and GTK+ version
    try:
        os_release_file = open("/etc/os-release","r")
        os_text = os_release_file.read()
        s_index = os_text.find("PRETTY_NAME=")
        e_index = os_text.find("\n", s_index)
        print "OS: " + os_text[s_index + 13:e_index - 1]
    except:
        pass

    print "Python", sys.version

    gtk_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version())
    print "GTK+ version:", gtk_version
    editorstate.gtk_version = gtk_version
    try:
        editorstate.mlt_version = mlt.LIBMLT_VERSION
    except:
        editorstate.mlt_version = "0.0.99" # magic string for "not found"

    # passing -xdg as a flag will change the user_dir location with XDG_CONFIG_HOME
    # For full xdg-app support all the launch processes need to add this too, currently not impl.
    for arg in sys.argv:
        if arg.lower() == "-xdg":
            editorstate.use_xdg = True

    # Create hidden folders if not present
    user_dir = utils.get_hidden_user_dir_path()
    print "User dir:",user_dir
    if not os.path.exists(user_dir):
        os.mkdir(user_dir)
    if not os.path.exists(user_dir + mltprofiles.USER_PROFILES_DIR):
        os.mkdir(user_dir + mltprofiles.USER_PROFILES_DIR)
    if not os.path.exists(user_dir + AUTOSAVE_DIR):
        os.mkdir(user_dir + AUTOSAVE_DIR)
    if not os.path.exists(user_dir + BATCH_DIR):
        os.mkdir(user_dir + BATCH_DIR)
    if not os.path.exists(user_dir + appconsts.AUDIO_LEVELS_DIR):
        os.mkdir(user_dir + appconsts.AUDIO_LEVELS_DIR)
    if not os.path.exists(utils.get_hidden_screenshot_dir_path()):
        os.mkdir(utils.get_hidden_screenshot_dir_path())
    if not os.path.exists(user_dir + appconsts.GMIC_DIR):
        os.mkdir(user_dir + appconsts.GMIC_DIR)


    # Set paths.
    respaths.set_paths(root_path)

    # Load editor prefs and list of recent projects
    editorpersistance.load()
    if editorpersistance.prefs.dark_theme == True:
        respaths.apply_dark_theme()
    if editorpersistance.prefs.display_all_audio_levels == False:
        editorstate.display_all_audio_levels = False
    editorpersistance.create_thumbs_folder_if_needed(user_dir)
    editorpersistance.create_rendered_clips_folder_if_needed(user_dir)
    editorpersistance.save()

    # Init translations module with translations data
    translations.init_languages()
    translations.load_filters_translations()
    mlttransitions.init_module()

    # RHEL7/CentOS compatibility fix
    if gtk_version == "3.8.8":
        GObject.threads_init()

    # Init gtk threads
    Gdk.threads_init()
    Gdk.threads_enter()

    # Request dark them if so desired
    if editorpersistance.prefs.dark_theme == True:
        Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", True)

    # Load drag'n'drop images
    dnd.init()

    # Adjust gui parameters for smaller screens
    scr_w = Gdk.Screen.width()
    scr_h = Gdk.Screen.height()
    editorstate.SCREEN_WIDTH = scr_w
    editorstate.SCREEN_HEIGHT = scr_h

    print "Small height:", editorstate.screen_size_small_height()
    print "Small width:",  editorstate.screen_size_small_width()

    _set_draw_params()

    # Refuse to run on too small screen.
    if scr_w < 1151 or scr_h < 767:
        _too_small_screen_exit()
        return

    # Splash screen
    if editorpersistance.prefs.display_splash_screen == True: 
        show_splash_screen()

    # Init MLT framework
    repo = mlt.Factory().init()

    # Set numeric locale to use "." as radix, MLT initilizes this to OS locale and this causes bugs 
    locale.setlocale(locale.LC_NUMERIC, 'C')

    # Check for codecs and formats on the system
    mltenv.check_available_features(repo)
    renderconsumer.load_render_profiles()

    # Load filter and compositor descriptions from xml files.
    mltfilters.load_filters_xml(mltenv.services)
    mlttransitions.load_compositors_xml(mltenv.transitions)
    
    # Replace some services if better replacements available
    mltfilters.replace_services(mltenv.services)

    # Create list of available mlt profiles
    mltprofiles.load_profile_list()
    
    # Launch association file if found in arguments
    launch_file_path = get_assoc_file_path()
    if launch_file_path != None:
        try:
            print "Launching assoc file:" +  launch_file_path
            persistance.show_messages = False
            editorstate.project = persistance.load_project(launch_file_path)
            persistance.show_messages = True
            check_crash = False
        except:
            editorstate.project = projectdata.get_default_project()
            persistance.show_messages = True
            check_crash = True
    else:
        # There is always a project open, so at startup we create a default project.
        # Set default project as the project being edited.
        editorstate.project = projectdata.get_default_project()
        check_crash = True

    # Audiomonitoring being available needs to be known before GUI creation
    audiomonitoring.init(editorstate.project.profile)

    # Create player object
    create_player()

    # Create main window and set widget handles in gui.py for more convenient reference.
    create_gui()

    # Inits widgets with project data
    init_project_gui()

    # Inits widgets with current sequence data
    init_sequence_gui()

    # Launch player now that data and gui exist
    launch_player()

    # Editor and modules need some more initializing
    init_editor_state()

    # Tracks need to be recentered if window is resized.
    # Connect listener for this now that the tline panel size allocation is sure to be available.
    global window_resize_id, window_state_id
    window_resize_id = gui.editor_window.window.connect("size-allocate", lambda w, e:updater.window_resized())
    window_state_id = gui.editor_window.window.connect("window-state-event", lambda w, e:updater.window_resized())

    # Get existing autosave files
    autosave_files = get_autosave_files()

    # Show splash
    if ((editorpersistance.prefs.display_splash_screen == True) and len(autosave_files) == 0):
        global splash_timeout_id
        splash_timeout_id = GLib.timeout_add(2600, destroy_splash_screen)
        splash_screen.show_all()

    appconsts.SAVEFILE_VERSION = projectdata.SAVEFILE_VERSION # THIS IS A QUESTIONABLE IDEA TO SIMPLIFY IMPORTS, NOT DRY. WHEN DOING TOOLS THAT RUN IN ANOTHER PROCESSES AND SAVE PROJECTS, THIS LINE NEEDS TO BE THERE ALSO.

    # Every running instance has unique autosave file which is deleted at exit
    set_instance_autosave_id()

    # Existance of autosave file hints that program was exited abnormally
    if check_crash == True and len(autosave_files) > 0:
        if len(autosave_files) == 1:
            GObject.timeout_add(10, autosave_recovery_dialog)
        else:
            GObject.timeout_add(10, autosaves_many_recovery_dialog)
    else:
        start_autosave()

    # We prefer to monkeypatch some callbacks into some modules, usually to
    # maintain a simpler and/or non-circular import structure
    monkeypatch_callbacks()
    
    # Launch gtk+ main loop
    Gtk.main()

    Gdk.threads_leave()
コード例 #50
0
def _TLINE_TOOL_OVERWRITE_box_selection_pref(check_menu_item):
    editorpersistance.prefs.box_for_empty_press_in_overwrite_tool = check_menu_item.get_active(
    )
    editorpersistance.save()
コード例 #51
0
ファイル: editorwindow.py プロジェクト: BogusCurry/flowblade
 def _show_vu_meter(self, widget):
     editorpersistance.prefs.show_vu_meter = widget.get_active()
     editorpersistance.save()
     
     self._update_top_row(True)
コード例 #52
0
ファイル: editorwindow.py プロジェクト: dermetfan/flowblade
 def _show_tabs_up(self, widget):
     if widget.get_active() == False:
         return
     self.notebook.set_tab_pos(gtk.POS_TOP)
     editorpersistance.prefs.tabs_on_top = True
     editorpersistance.save()
コード例 #53
0
ファイル: app.py プロジェクト: mcanthony/flowblade
def main(root_path):
    """
    Called at application start.
    Initializes application with a default project.
    """
    # Print OS, Python version and GTK+ version
    try:
        os_release_file = open("/etc/os-release", "r")
        os_text = os_release_file.read()
        s_index = os_text.find("PRETTY_NAME=")
        e_index = os_text.find("\n", s_index)
        print "OS: " + os_text[s_index + 13:e_index - 1]
    except:
        pass

    print "Python", sys.version

    print "GTK+ version:", gtk.gtk_version
    editorstate.gtk_version = gtk.gtk_version
    try:
        editorstate.mlt_version = mlt.LIBMLT_VERSION
    except:
        editorstate.mlt_version = "0.0.99"  # magic string for "not found"

    # Create hidden folders if not present
    user_dir = utils.get_hidden_user_dir_path()
    if not os.path.exists(user_dir):
        os.mkdir(user_dir)
    if not os.path.exists(user_dir + mltprofiles.USER_PROFILES_DIR):
        os.mkdir(user_dir + mltprofiles.USER_PROFILES_DIR)
    if not os.path.exists(user_dir + AUTOSAVE_DIR):
        os.mkdir(user_dir + AUTOSAVE_DIR)
    if not os.path.exists(user_dir + BATCH_DIR):
        os.mkdir(user_dir + BATCH_DIR)
    if not os.path.exists(user_dir + appconsts.AUDIO_LEVELS_DIR):
        os.mkdir(user_dir + appconsts.AUDIO_LEVELS_DIR)
    if not os.path.exists(utils.get_hidden_screenshot_dir_path()):
        os.mkdir(utils.get_hidden_screenshot_dir_path())

    # Set paths.
    respaths.set_paths(root_path)

    # Init translations module with translations data
    translations.init_languages()
    translations.load_filters_translations()
    mlttransitions.init_module()

    # Load editor prefs and list of recent projects
    editorpersistance.load()
    if editorpersistance.prefs.dark_theme == True:
        respaths.apply_dark_theme()
    editorpersistance.create_thumbs_folder_if_needed(user_dir)
    editorpersistance.create_rendered_clips_folder_if_needed(user_dir)
    editorpersistance.save()

    # Init gtk threads
    gtk.gdk.threads_init()
    gtk.gdk.threads_enter()

    # Load drag'n'drop images
    dnd.init()

    # Adjust gui parameters for smaller screens
    scr_w = gtk.gdk.screen_width()
    scr_h = gtk.gdk.screen_height()
    editorstate.SCREEN_WIDTH = scr_w
    editorstate.SCREEN_HEIGHT = scr_h
    _set_draw_params(scr_w, scr_h)

    # Refuse to run on too small screen.
    if scr_w < 1151 or scr_h < 767:
        _too_small_screen_exit()
        return

    # Splash screen
    if editorpersistance.prefs.display_splash_screen == True:
        show_splash_screen()

    # Init MLT framework
    repo = mlt.Factory().init()

    # Set numeric locale to use "." as radix, MLT initilizes this to OS locale and this causes bugs
    locale.setlocale(locale.LC_NUMERIC, 'C')

    # Check for codecs and formats on the system
    mltenv.check_available_features(repo)
    renderconsumer.load_render_profiles()

    # Load filter and compositor descriptions from xml files.
    mltfilters.load_filters_xml(mltenv.services)
    mlttransitions.load_compositors_xml(mltenv.transitions)

    # Replace some services if better replacements available
    mltfilters.replace_services(mltenv.services)

    # Create list of available mlt profiles
    mltprofiles.load_profile_list()

    # Launch association file if found in arguments
    launch_file_path = get_assoc_file_path()
    if launch_file_path != None:
        try:
            print "Launching assoc file:" + launch_file_path
            persistance.show_messages = False
            editorstate.project = persistance.load_project(launch_file_path)
            persistance.show_messages = True
            check_crash = False
        except:
            editorstate.project = projectdata.get_default_project()
            persistance.show_messages = True
            check_crash = True
    else:
        # There is always a project open, so at startup we create a default project.
        # Set default project as the project being edited.
        editorstate.project = projectdata.get_default_project()
        check_crash = True

    # Audiomonitoring being available needs to be known before GUI creation
    audiomonitoring.init(editorstate.project.profile)

    # Do JACK audio start-up action
    jackaudio.start_up()

    # Create player object
    create_player()

    # Create main window and set widget handles in gui.py for more convenient reference.
    create_gui()

    # Inits widgets with project data
    init_project_gui()

    # Inits widgets with current sequence data
    init_sequence_gui()

    # Launch player now that data and gui exist
    launch_player()

    # Editor and modules need some more initializing
    init_editor_state()

    # Tracks need to be recentered if window is resized.
    # Connect listener for this now that the tline panel size allocation is sure to be available.
    gui.editor_window.window.connect("size-allocate",
                                     lambda w, e: updater.window_resized())
    gui.editor_window.window.connect("window-state-event",
                                     lambda w, e: updater.window_resized())

    # Get existing autosave files
    autosave_files = get_autosave_files()

    # Show splash
    if ((editorpersistance.prefs.display_splash_screen == True)
            and len(autosave_files) == 0):
        global splash_timeout_id
        splash_timeout_id = gobject.timeout_add(2600, destroy_splash_screen)
        splash_screen.show_all()

    appconsts.SAVEFILE_VERSION = projectdata.SAVEFILE_VERSION  # THIS IS A QUESTIONABLE IDEA TO SIMPLIFY IMPORTS, NOT DRY. WHEN DOING TOOLS THAT RUN IN ANOTHER PROCESSES AND SAVE PROJECTS, THIS LINE NEEDS TO BE THERE ALSO.

    # Every running instance has unique autosave file which is deleted at exit
    set_instance_autosave_id()

    # Existance of autosave file hints that program was exited abnormally
    if check_crash == True and len(autosave_files) > 0:
        if len(autosave_files) == 1:
            gobject.timeout_add(10, autosave_recovery_dialog)
        else:
            gobject.timeout_add(10, autosaves_many_recovery_dialog)
    else:
        start_autosave()

    # We prefer to monkeypatch some callbacks into some modules, usually to
    # maintain a simpler and non-circular import structure
    monkeypatch_callbacks()

    # Launch gtk+ main loop
    gtk.main()

    gtk.gdk.threads_leave()
コード例 #54
0
ファイル: workflow.py プロジェクト: jliljebl/flowblade
def _TLINE_TOOL_OVERWRITE_box_selection_pref(check_menu_item):
    editorpersistance.prefs.box_for_empty_press_in_overwrite_tool = check_menu_item.get_active()
    editorpersistance.save()
コード例 #55
0
ファイル: editorlayout.py プロジェクト: ddennedy/flowblade
def init_layout_data():
    global _panel_positions, _positions_names, _panels_names, _position_notebooks
    _panel_positions = editorpersistance.prefs.panel_positions

    # Use default panels positons if nothing available yet or too small screen
    if panel_positioning_available() == False or _panel_positions == None:
        _panel_positions = copy.deepcopy(DEFAULT_PANEL_POSITIONS)
        editorpersistance.prefs.panel_positions = _panel_positions
        editorpersistance.save()

    if editorpersistance.prefs.positions_tabs == None:
        editorpersistance.prefs.positions_tabs = DEFAULT_TABS_POSITIONS
        editorpersistance.save()

    # Force media panel positioning to work with both one and two window modes
    if editorpersistance.prefs.global_layout == appconsts.SINGLE_WINDOW:
        if _panel_positions[
                appconsts.
                PANEL_MEDIA] == appconsts.PANEL_PLACEMENT_TWO_WINDOWS_MEDIA_PANEL_POS:
            _panel_positions[
                appconsts.
                PANEL_MEDIA] = appconsts.PANEL_PLACEMENT_TOP_ROW_DEFAULT
    else:
        if _panel_positions[
                appconsts.
                PANEL_MEDIA] == appconsts.PANEL_PLACEMENT_TOP_ROW_DEFAULT:
            _panel_positions[
                appconsts.
                PANEL_MEDIA] = appconsts.PANEL_PLACEMENT_TWO_WINDOWS_MEDIA_PANEL_POS

    # We are using different media panels for differnt screen sizes,
    # make sure that are using and displaying the right one here even screen size has changed.
    if top_level_project_panel() == True:
        if appconsts.PANEL_PROJECT_SMALL_SCREEN in _panel_positions:
            _panel_positions[
                appconsts.
                PANEL_PROJECT] = appconsts.PANEL_PLACEMENT_TOP_ROW_PROJECT_DEFAULT
            del (_panel_positions[appconsts.PANEL_PROJECT_SMALL_SCREEN])
    else:
        if appconsts.PANEL_PROJECT in _panel_positions:
            _panel_positions[
                appconsts.
                PANEL_PROJECT_SMALL_SCREEN] = appconsts.PANEL_PLACEMENT_TOP_ROW_DEFAULT
            del (_panel_positions[appconsts.PANEL_PROJECT])

    # Translations need to be initialized after modules have been loaded.
    _positions_names = { \
        appconsts.PANEL_PLACEMENT_TOP_ROW_DEFAULT: _("Top Row Default Notebook"),
        appconsts.PANEL_PLACEMENT_TOP_ROW_RIGHT: _("Top Row Right"),
        appconsts.PANEL_PLACEMENT_LEFT_COLUMN: _("Left Column"),
        appconsts.PANEL_PLACEMENT_BOTTOM_ROW_LEFT: _("Bottom Row Left"),
        appconsts.PANEL_PLACEMENT_BOTTOM_ROW_RIGHT: _("Bottom Row Right"),
        appconsts.PANEL_PLACEMENT_NOT_VISIBLE: _("Not Visible"),
        appconsts.PANEL_PLACEMENT_TOP_ROW_PROJECT_DEFAULT: _("Top Row Project Panel Default"),
    }

    _panels_names = { \
        appconsts.PANEL_MEDIA: _("Media"),
        appconsts.PANEL_FILTERS: _("Filters"),
        appconsts.PANEL_COMPOSITORS: _("Compositors"),
        appconsts.PANEL_RANGE_LOG: _("Range Log"),
        appconsts.PANEL_RENDERING: _("Render"),
        appconsts.PANEL_JOBS: _("Jobs"),
        appconsts.PANEL_PROJECT: _("Project"),
        appconsts.PANEL_PROJECT_SMALL_SCREEN: _("Project"),
        appconsts.PANEL_MEDIA_AND_BINS_SMALL_SCREEN: "tba",
        appconsts.PANEL_FILTER_SELECT: _("Filter Select")
    }

    # Values are possibly set to other then None as layout is being build
    _position_notebooks = { \
        appconsts.PANEL_PLACEMENT_TOP_ROW_DEFAULT: None,
        appconsts.PANEL_PLACEMENT_TOP_ROW_RIGHT: None,
        appconsts.PANEL_PLACEMENT_LEFT_COLUMN: None,
        appconsts.PANEL_PLACEMENT_BOTTOM_ROW_LEFT: None,
        appconsts.PANEL_PLACEMENT_BOTTOM_ROW_RIGHT: None,
        appconsts.PANEL_PLACEMENT_TOP_ROW_PROJECT_DEFAULT: None
    }
コード例 #56
0
    def _show_vu_meter(self, widget):
        editorpersistance.prefs.show_vu_meter = widget.get_active()
        editorpersistance.save()

        self._update_top_row(True)