def _get_affine_filt_geom_sliders(ep): scr_width = PROJECT().profile.width() scr_height = PROJECT().profile.width() # "0=0,0:SCREENSIZE:100" frame_value = ep.value.split("=") tokens = frame_value[1].split(":") pos_tokens = tokens[0].split("/") size_tokens = tokens[1].split("x") x_adj = Gtk.Adjustment(float(pos_tokens[0]), float(-scr_width), float(scr_width), float(1)) y_adj = Gtk.Adjustment(float(pos_tokens[1]), float(-scr_height), float(scr_height), float(1)) h_adj = Gtk.Adjustment(float(size_tokens[1]), float(0), float(scr_height * 5), float(1)) x_slider, x_spin, x_row = _get_affine_slider("X", x_adj) y_slider, y_spin, y_row = _get_affine_slider("Y", y_adj) h_slider, h_spin, h_row = _get_affine_slider(_("Size/Height"), h_adj) all_sliders = (x_slider, y_slider, h_slider) x_slider.get_adjustment().connect( "value-changed", lambda w: ep.slider_values_changed(all_sliders, scr_width)) x_spin.get_adjustment().connect( "value-changed", lambda w: ep.slider_values_changed(all_sliders, scr_width)) y_slider.get_adjustment().connect( "value-changed", lambda w: ep.slider_values_changed(all_sliders, scr_width)) y_spin.get_adjustment().connect( "value-changed", lambda w: ep.slider_values_changed(all_sliders, scr_width)) h_slider.get_adjustment().connect( "value-changed", lambda w: ep.slider_values_changed(all_sliders, scr_width)) h_spin.get_adjustment().connect( "value-changed", lambda w: ep.slider_values_changed(all_sliders, scr_width)) vbox = Gtk.VBox(False, 4) vbox.pack_start(x_row, True, True, 0) vbox.pack_start(y_row, True, True, 0) vbox.pack_start(h_row, True, True, 0) return vbox
def _group_action_pressed(widget, event): actions_menu = gtk.Menu() actions_menu.add( guiutils.get_menu_item(_("New Group..."), _actions_callback, "new")) actions_menu.add( guiutils.get_menu_item(_("New Group From Selected..."), _actions_callback, "newfromselected")) guiutils.add_separetor(actions_menu) item = guiutils.get_menu_item(_("Rename Current Group..."), _actions_callback, "rename") _unsensitive_for_all_view(item) actions_menu.add(item) guiutils.add_separetor(actions_menu) move_menu_item = gtk.MenuItem( _("Move Selected Items To Group").encode('utf-8')) move_menu = gtk.Menu() if len(PROJECT().media_log_groups) == 0: move_menu.add( guiutils.get_menu_item( _("No Groups").encode('utf-8'), _actions_callback, "dummy", False)) else: index = 0 for group in PROJECT().media_log_groups: name, items = group move_menu.add( guiutils.get_menu_item(name, _actions_callback, str(index))) index = index + 1 move_menu_item.set_submenu(move_menu) actions_menu.add(move_menu_item) move_menu_item.show() guiutils.add_separetor(actions_menu) item = guiutils.get_menu_item(_("Delete Current Group"), _actions_callback, "delete") _unsensitive_for_all_view(item) actions_menu.add(item) #item = guiutils.get_menu_item(_("Delete Current Group and Items"), _actions_callback, "deletewithitems") #_unsensitive_for_all_view(item) #actions_menu.add(item) actions_menu.popup(None, None, None, event.button, event.time)
def write_image(self): """ Writes thumbnail image from file producer """ clip_path = self.clip.path # Create consumer matchframe_new_path = userfolders.get_cache_dir( ) + appconsts.MATCH_FRAME_NEW consumer = mlt.Consumer(PROJECT().profile, "avformat", matchframe_new_path) consumer.set("real_time", 0) consumer.set("vcodec", "png") # Create one frame producer producer = mlt.Producer(PROJECT().profile, str(clip_path)) producer = producer.cut(int(self.clip_frame), int(self.clip_frame)) # Delete new match frame try: os.remove(matchframe_new_path) except: # This fails when done first time ever pass # Connect and write image consumer.connect(producer) consumer.run() # Wait until new file exists while os.path.isfile(matchframe_new_path) != True: time.sleep(0.1) # Copy to match frame matchframe_path = userfolders.get_cache_dir() + appconsts.MATCH_FRAME shutil.copyfile(matchframe_new_path, matchframe_path) # Update timeline data # Get frame of clip.clip_in_in on timeline. clip_index = self.track.clips.index(self.clip) clip_start_in_tline = self.track.clip_start(clip_index) tline_match_frame = clip_start_in_tline + (self.clip_frame - self.clip.clip_in) tlinewidgets.set_match_frame(tline_match_frame, self.track.id, self.display_on_right) # Update view updater.repaint_tline()
def run(self): print("Starting XML render") player = PLAYER() # Don't try anything if somehow this was started # while timeline rendering is running if player.is_rendering: print("Can't render XML when another render is already running!") return # Stop all playback before producer is disconnected self.current_playback_frame = player.producer.frame() player.ticker.stop_ticker() player.consumer.stop() player.producer.set_speed(0) player.producer.seek(0) # Wait until producer is at start while player.producer.frame() != 0: time.sleep(0.1) # Get render producer if self.rendered_sequence == None: # default is current sequence timeline_producer = PROJECT().c_seq.tractor else: timeline_producer = self.rendered_sequence.tractor # Get render consumer xml_consumer = mlt.Consumer(PROJECT().profile, "xml", str(self.file_name)) # Connect and start rendering xml_consumer.connect(timeline_producer) xml_consumer.start() timeline_producer.set_speed(1) # Wait until done while xml_consumer.is_stopped() == False: print("In XML render wait loop...") time.sleep(0.1) print("XML render done") # Get app player going again player.connect_and_start() player.seek_frame(0) self.render_done_callback(self.data)
def _do_rendering(): print "timeline render..." global aborted aborted = False render_consumer = get_render_consumer() if render_consumer == None: return # Set render start and end points if widgets.range_cb.get_active() == 0: start_frame = 0 end_frame = -1 # renders till finish else: start_frame = current_sequence().tractor.mark_in end_frame = current_sequence().tractor.mark_out # Only render a range if it is defined. if start_frame == -1 or end_frame == -1: if widgets.range_cb.get_active() == 1: rendergui.no_good_rander_range_info() return file_path = get_file_path() project_event = projectdata.ProjectEvent(projectdata.EVENT_RENDERED, file_path) PROJECT().events.append(project_event) projectinfogui.update_project_info() # See if project and render fps match cnum = render_consumer.profile().frame_rate_num() cden = render_consumer.profile().frame_rate_den() pnum = PROJECT().profile.frame_rate_num() pden = PROJECT().profile.frame_rate_den() if (cnum == pnum) and (cden == pden): frames_rates_match = True else: frames_rates_match = False global progress_window progress_window = rendergui.render_progress_dialog( _render_cancel_callback, gui.editor_window.window, frames_rates_match) set_render_gui() render_launch = RenderLauncher(render_consumer, start_frame, end_frame) render_launch.start()
def set_timeline_height(): orig_pos = gui.editor_window.app_v_paned.get_position() orig_height = tlinewidgets.HEIGHT if len(current_sequence().tracks) == 11 or PROJECT().get_project_property( appconsts.P_PROP_TLINE_SHRINK_VERTICAL) == False: tlinewidgets.HEIGHT = appconsts.TLINE_HEIGHT set_v_paned = False else: tlinewidgets.HEIGHT = current_sequence().get_shrunk_tline_height_min() set_v_paned = True gui.tline_canvas.widget.set_size_request(tlinewidgets.WIDTH, tlinewidgets.HEIGHT) gui.tline_column.widget.set_size_request(tlinewidgets.COLUMN_WIDTH, tlinewidgets.HEIGHT) if set_v_paned == True: new_pos = orig_pos + orig_height - tlinewidgets.HEIGHT gui.editor_window.app_v_paned.set_position(new_pos) current_sequence().resize_tracks_to_fit( gui.tline_canvas.widget.get_allocation()) tlinewidgets.set_ref_line_y(gui.tline_canvas.widget.get_allocation()) gui.tline_column.init_listeners() repaint_tline()
def render_single_track_transition_clip(transition_producer, encoding_option_index, quality_option_index, file_ext, transition_render_complete_cb, window_text): # Set render complete callback to availble render stop callback using global variable global transition_render_done_callback transition_render_done_callback = transition_render_complete_cb # Profile profile = PROJECT().profile folder = editorpersistance.prefs.render_folder file_name = md5.new(str(os.urandom(32))).hexdigest() write_file = folder + "/"+ file_name + file_ext # Render consumer consumer = renderconsumer.get_render_consumer_for_encoding_and_quality(write_file, profile, encoding_option_index, quality_option_index) # start and end frames start_frame = 0 end_frame = transition_producer.get_length() - 1 # Launch render # TODO: fix naming this isn't motion renderer global motion_renderer, motion_progress_update motion_renderer = renderconsumer.FileRenderPlayer(write_file, transition_producer, consumer, start_frame, end_frame) motion_renderer.start() title = _("Rendering Transition Clip") progress_bar = Gtk.ProgressBar() dialog = rendergui.clip_render_progress_dialog(_transition_render_stop, title, window_text, progress_bar, gui.editor_window.window) motion_progress_update = renderconsumer.ProgressWindowThread(dialog, progress_bar, motion_renderer, _transition_render_stop) motion_progress_update.start()
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 == "magnet": snapping.show_magnet_icon = widget.get_active() 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 == "pointer_sensitive_item": editorstate.cursor_is_tline_sensitive = widget.get_active() else: # media thumbnails editorstate.display_clip_media_thumbnails = widget.get_active() updater.repaint_tline()
def _set_fade_length_dialog_callback(dialog, response_id, spin): if response_id == Gtk.ResponseType.ACCEPT: default_length = int(spin.get_value()) PROJECT().set_project_property(appconsts.P_PROP_DEFAULT_FADE_LENGTH, default_length) dialog.destroy()
def _create_color_pulse_clip_callback(dialog, response_id, widgets): if response_id == Gtk.ResponseType.ACCEPT: media_object = BinColorPulseClip(PROJECT().next_media_file_id, _("Color Pulse")) s1_slider, s2_slider, s3_slider, s4_slider, m1_slider, m2_slider = widgets media_object.set_property_values(s1_slider.get_adjustment().get_value() / 100.0, s2_slider.get_adjustment().get_value() / 100.0, s3_slider.get_adjustment().get_value() / 100.0, s4_slider.get_adjustment().get_value() / 100.0, m1_slider.get_adjustment().get_value() / 100.0, m2_slider.get_adjustment().get_value() / 100.0) PROJECT().add_pattern_producer_media_object(media_object) _update_gui_for_pattern_producer_media_object_add() dialog.destroy()
def replace_values_using_clip_data(properties, info, clip): """ Property value expressions may need to be replaced with expressions that can only be created with knowing clip. """ replacement_happened = False for i in range(0, len(properties)): prop_name, value, prop_type = properties[i] if prop_type == PROP_EXPRESSION: args_str = info.property_args[prop_name] args_dict = args_string_to_args_dict(args_str) for arg_name in args_dict: if arg_name == VALUE_REPLACEMENT: arg_val = args_dict[arg_name] clip_length = clip.clip_length() fade_length = PROJECT().get_project_property(appconsts.P_PROP_DEFAULT_FADE_LENGTH) if arg_val == FADE_IN_REPLAMENT: frame_1 = clip.clip_in frame_2 = clip.clip_in + fade_length value = "" if frame_1 != 0: value += "0=0;" value += str(frame_1) + "=0;" + str(frame_2) + "=1" properties[i] = (prop_name, value, prop_type) replacement_happened = True elif arg_val == FADE_OUT_REPLAMENT: frame_1 = clip.clip_out - fade_length frame_2 = clip.clip_out if clip_length > fade_length: value = "0=1;" + str(frame_1) + "=1;" + str(frame_2) + "=0" else: value = "0=1;" + str(frame_2) + "=0" properties[i] = (prop_name, value, prop_type) replacement_happened = True elif arg_val == FADE_IN_OUT_REPLAMENT: frame_1 = clip.clip_in frame_2 = clip.clip_in + fade_length frame_3 = clip.clip_out - fade_length frame_4 = clip.clip_out value = "" if frame_1 != 0: value += "0=0;" if clip_length > 40: value += str(frame_1) + "=0;" + str(frame_2) + "=1;" value += str(frame_3) + "=1;" + str(frame_4) + "=0" else: clip_half = int(clip_length//2) value += str(frame_1) + "=0;" + str(frame_1 + clip_half) + "=1;" + str(frame_4) + "=0" properties[i] = (prop_name, value, prop_type) replacement_happened = True return replacement_happened
def _launch_render(self, clip, range_in, range_out, clip_start_offset): self.create_data_dirs_if_needed() self.render_range_in = range_in self.render_range_out = range_out self.clip_start_offset = clip_start_offset mltxmlheadless.clear_flag_files(self.get_container_program_id()) # We need data to be available for render process, # create video_render_data object with default values if not available. if self.container_data.render_data == None: self.container_data.render_data = toolsencoding.create_container_clip_default_render_data_object(current_sequence().profile) mltxmlheadless.set_render_data(self.get_container_program_id(), self.container_data.render_data) job_msg = self.get_job_queue_message() job_msg.text = _("Render Starting...") job_msg.status = jobs.RENDERING jobs.update_job_queue(job_msg) args = ("session_id:" + self.get_container_program_id(), "clip_path:" + str(self.container_data.unrendered_media), "range_in:" + str(range_in), "range_out:"+ str(range_out), "profile_desc:" + PROJECT().profile.description().replace(" ", "_"), "xml_file_path:" + str(self.container_data.unrendered_media)) # Create command list and launch process. command_list = [sys.executable] command_list.append(respaths.LAUNCH_DIR + "flowblademltxmlheadless") for arg in args: command_list.append(arg) subprocess.Popen(command_list)
def _save_project_in_last_saved_path(): updater.set_info_icon(gtk.STOCK_SAVE) PROJECT().events.append( projectdata.ProjectEvent(projectdata.EVENT_SAVED, PROJECT().last_save_path)) persistance.save_project(PROJECT(), PROJECT().last_save_path) #<----- HERE global save_icon_remove_event_id save_icon_remove_event_id = gobject.timeout_add(500, remove_save_icon) global save_time save_time = time.clock() projectinfogui.update_project_info()
def _fluxity_unredered_media_creation_complete(created_unrendered_clip_path, container_clip_data): # This called from inside Gdk.threads_enter(), entering second time here crashes. # Now that unrendered media has been created we have full container data info. data_object = container_clip_data.data_slots["fluxity_plugin_edit_data"] container_clip_data.editable = True container_clip_data.unrendered_length = data_object["length"] container_clip_data.unrendered_media = created_unrendered_clip_path container_clip_data.unrendered_type = appconsts.VIDEO container_clip = ContainerClipMediaItem(PROJECT().next_media_file_id, data_object["name"], container_clip_data) PROJECT().add_container_clip_media_object(container_clip) _update_gui_for_media_object_add()
def delete_selected_bin(): """ Deletes current bin if it's empty and at least one will be left. """ if len(current_bin().file_ids) != 0: dialogutils.warning_message(_("Can't remove a non-empty bin"), _("You must remove all files from the bin before deleting it."), gui.editor_window.window) return # Get iter and index for (current) selected bin selection = gui.bin_list_view.treeview.get_selection() model, iter = selection.get_selected() if len(model) < 2: dialogutils.warning_message(_("Can't remove last bin"), _("There must always exist at least one bin."), gui.editor_window.window) return (model, rows) = selection.get_selected_rows() row = max(rows[0]) # Remove from gui and project data model.remove(iter) PROJECT().bins.pop(row) # Set first bin selected, listener 'bin_selection_changed' updates editorstate.project.c_bin selection.select_path("0") _enable_save()
def log_range_clicked(): media_file = editorstate.MONITOR_MEDIA_FILE() if media_file == None: return if media_file.type == appconsts.PATTERN_PRODUCER: # INFOWINDOW ??? return if media_file.mark_in == -1 or media_file.mark_out == -1: return file_path = media_file.path if PROJECT().proxy_data.proxy_mode == appconsts.USE_PROXY_MEDIA: if media_file.second_file_path != None: file_path = media_file.second_file_path # proxy file exists else: file_path = media_file.path # no proxy file created log_event = MediaLogEvent(appconsts.MEDIA_LOG_MARKS_SET, media_file.mark_in, media_file.mark_out, media_file.name, file_path) log_event.ttl = media_file.ttl editorstate.PROJECT().media_log.append(log_event) editorstate.PROJECT().add_to_group(_get_current_group_index(), [log_event]) _update_list_view(log_event)
def render_slowmo_from_item(row): log_events = get_current_filtered_events() event_item = log_events[row] media_file = PROJECT().get_media_file_for_path(event_item.path) media_file.mark_in = event_item.mark_in media_file.mark_out = event_item.mark_out render.render_frame_buffer_clip(media_file, True)
def delete_selected(): selected = widgets.media_log_view.get_selected_rows_list() log_events = get_current_filtered_events() delete_events = [] for row in selected: index = max(row) # these are tuple, max to extract only value delete_events.append(log_events[index]) current_group_index = _get_current_group_index() if current_group_index != -1: # When user created group is displayed item is only deleted from that group PROJECT().remove_from_group(current_group_index, delete_events) else: # When "All Items" group is displayed item is deleted from "All Items" list and from all groups too for i in range(0, len(PROJECT().media_log_groups)): PROJECT().remove_from_group(i, delete_events) PROJECT().delete_media_log_events(delete_events) widgets.media_log_view.fill_data_model()
def _rename_callback(dialog, response_id, entry): new_name = entry.get_text() dialog.destroy() if response_id == Gtk.ResponseType.CANCEL: return if len(new_name) == 0: return current_group_index = _get_current_group_index() old_name, items = PROJECT().media_log_groups[current_group_index] PROJECT().media_log_groups.pop(current_group_index) PROJECT().media_log_groups.insert(current_group_index, (new_name, items)) _create_group_select() widgets.group_view_select.set_active(current_group_index + 1) _mark_log_changed()
def run(self): tractor = self.tractor tractor.set_speed(0) tractor.seek(0) # Wait until producer is at start while tractor.frame() != 0: time.sleep(0.1) # Get render consumer xml_consumer = mlt.Consumer(PROJECT().profile, "xml", str(self.file_name)) # Connect and start rendering xml_consumer.connect(tractor) xml_consumer.start() tractor.set_speed(1) # Wait until done while xml_consumer.is_stopped() == False: print "In XML render wait loop..." time.sleep(0.1) print "XML compound clip render done" self.render_done_callback(self.file_name, self.media_name)
def run(self): Gdk.threads_enter() recreate_progress_window = dialogs.recreate_icons_progress_dialog() time.sleep(0.1) Gdk.threads_leave() no_icon_path = respaths.IMAGE_PATH + projectdata.FALLBACK_THUMB loaded = 0 for key in PROJECT().media_files.iterkeys(): media_file = PROJECT().media_files[key] Gdk.threads_enter() recreate_progress_window.info.set_text(media_file.name) Gdk.threads_leave() if ((not isinstance(media_file, patternproducer.AbstractBinClip)) and (not isinstance(media_file, projectdata.BinColorClip))): if media_file.type == appconsts.AUDIO: icon_path = respaths.IMAGE_PATH + "audio_file.png" media_file.info = None else: (icon_path, length, info) = projectdata.thumbnailer.write_image( media_file.path) media_file.info = info media_file.icon_path = icon_path media_file.create_icon() loaded = loaded + 1 Gdk.threads_enter() loaded_frac = float(loaded) / float(len(PROJECT().media_files)) recreate_progress_window.progress_bar.set_fraction(loaded_frac) time.sleep(0.01) Gdk.threads_leave() # Update editor gui Gdk.threads_enter() recreate_progress_window.destroy() time.sleep(0.3) Gdk.threads_leave() Gdk.threads_enter() gui.media_list_view.fill_data_model() gui.bin_list_view.fill_data_model() gui.enable_save() Gdk.threads_leave()
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)
def reset_filter_values(): treeselection = widgets.effect_stack_view.treeview.get_selection() (model, rows) = treeselection.get_selected_rows() row = rows[0] row_index = max(row) clip.filters[row_index].reset_values(PROJECT().profile, clip) effect_selection_changed()
def display_item(row): log_events = get_current_filtered_events() event_item = log_events[row] media_file = PROJECT().get_media_file_for_path(event_item.path) media_file.mark_in = event_item.mark_in media_file.mark_out = event_item.mark_out updater.set_and_display_monitor_media_file(media_file) monitorevent.to_mark_in_pressed()
def get_current_profile(): profile_index = widgets.profile_panel.out_profile_combo.widget.get_active() if profile_index == 0: # project_profile is first selection in combo box profile = PROJECT().profile else: profile = mltprofiles.get_profile_for_index(profile_index - 1) return profile
def _open_clip_in_clip_monitor(data): clip, track, item_id, x = data media_file = PROJECT().get_media_file_for_path(clip.path) media_file.mark_in = clip.clip_in media_file.mark_out = clip.clip_out updater.set_and_display_monitor_media_file(media_file) gui.pos_bar.widget.grab_focus()
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()
def move_files_to_bin(new_bin, bin_indexes): # If we're moving clips to bin that they're already in, do nothing. if PROJECT().bins[new_bin] == current_bin(): return # Delete from current bin moved_ids = [] bin_indexes.sort() bin_indexes.reverse() for i in bin_indexes: moved_ids.append(current_bin().file_ids.pop(i)) # Add to target bin for file_id in moved_ids: PROJECT().bins[new_bin].file_ids.append(file_id) gui.media_list_view.fill_data_model() gui.bin_list_view.fill_data_model()
def fill_data_model(self): self.storemodel.clear() for e in PROJECT().events: t = e.get_date_str() desc, path = e.get_desc_and_path() row_data = [t, desc, path] self.storemodel.append(row_data) self.scroll.queue_draw()
def _blender_unredered_media_creation_complete(created_unrendered_clip_path, container_clip_data): rand_id_str = str(os.urandom(16)) clip_id_str = hashlib.md5(rand_id_str.encode('utf-8')).hexdigest() unrendered_clip_path = userfolders.get_data_dir( ) + appconsts.CONTAINER_CLIPS_UNRENDERED + "/" + clip_id_str + ".mp4" os.replace(created_unrendered_clip_path, unrendered_clip_path) # Now that unrendere media has been created we have full container data info. container_clip_data.unrendered_media = unrendered_clip_path container_clip_data.unrendered_type = appconsts.VIDEO container_clip = ContainerClipMediaItem( PROJECT().next_media_file_id, container_clip_data.get_program_name(), container_clip_data) PROJECT().add_container_clip_media_object(container_clip) _update_gui_for_media_object_add()