static void findtop(VolumeDialog *v) { gfloat f; Document *d = EFFECT_BROWSER(EFFECT_DIALOG(v)->eb)->dl->selected; peak = 0.0; if (d == NULL) return; document_parse(d,findtop_proc,FALSE,TRUE,_("Calculating peak volume...")); gdk_window_raise(GTK_WIDGET(EFFECT_DIALOG(v)->eb)->window); f = 100.0 * maximum_float_value(&(d->chunk->format)) / peak; if (f < 100.0) f = 100.0; floatbox_set(v->start_percent,f); floatbox_set(v->end_percent,f); }
void document_abner(DocumentEdit *edit, DocumentPosition begin, DocumentPosition end) { hale_assert_input(begin <= end); _check_edit(edit); auto document = edit->document; hale_assert(is_valid_position(document, begin)); hale_assert(is_valid_position(document, end)); edit->offset_begin = position_to_offset(document, begin); edit->offset_end = position_to_offset(document, end); edit->length = edit->offset_end - edit->offset_begin; if (edit->length == 0) { return; } edit->type = DocumentEdit::Remove; edit->pos_begin = begin; edit->pos_end = end; edit->block_changed = begin.block; edit->blocks_changed_count = edit->pos_end.block - edit->pos_begin.block; if (!edit->undo) { UndoWriter writer(&edit->document->undo, Document::UndoEvent_Remove); undo_write(writer.undo, &edit->offset_begin, sizeof(memi)); undo_write(writer.undo, &edit->length, sizeof(memi)); void *text = undo_write(writer.undo, edit->length * sizeof(ch)); document_text(document, edit->offset_begin, edit->length, (ch*)text, edit->length); } _buffer_remove(&document->buffer, edit->offset_begin, edit->length); if (edit->blocks_changed_count) { vector_remove(&document->blocks, edit->pos_begin.block, edit->pos_end.block - edit->pos_begin.block); edit->blocks_changed_at = begin.block + 1; } else { edit->blocks_changed_at = begin.block; } for (memi i = begin.block; i != vector_count(document->blocks); i++) { document->blocks[i].end -= edit->length; } document->blocks[edit->block_changed].flags = 0; // Move the parser head if (document_parser_set_head(document, edit->pos_begin.block)) { // TODO(cohen): If the time distance between caret types is small, // do not parse immediately. document_parse(document, 0.01f); } _notify_views_about_abner(edit); }
void document_insert(DocumentEdit *edit, DocumentPosition position, ch *text, memi text_length) { _check_edit(edit); //#ifdef _DEBUG // for (memi i = 0; i < text_length; i++) { // hale_assert(text[i] != '\r'); // } //#endif auto document = edit->document; memi old_document_end = _buffer_length(document->buffer); hale_assert(is_valid_position(document, position)); edit->type = DocumentEdit::Insert; // edit->undo_head = document->undo->writingHead(); edit->offset_begin = position_to_offset(document, position); Vector<memi> offsets; vector_init(&offsets); if (!edit->undo) { UndoWriter writer(&edit->document->undo, Document::UndoEvent_Insert); undo_write(writer.undo, &edit->offset_begin, sizeof(memi)); memi length_index = writer.undo->data.count; undo_write(writer.undo, &edit->length, sizeof(memi)); text_length = convert_and_insert(edit, text, text_length, &offsets); *((memi*)(writer.undo->data.ptr + length_index)) = text_length; } else { text_length = convert_and_insert(edit, text, text_length, &offsets); } edit->offset_end = edit->offset_begin + text_length; edit->length = text_length; edit->blocks_changed_count = vector_count(offsets); if (edit->blocks_changed_count == 0) { edit->block_changed = position.block; edit->blocks_changed_at = position.block; } else if (position.position == 0) { // Inserting at the beginning of a block. if (edit->offset_begin == 0) { // Inserting at document begin. edit->block_changed = position.block + vector_count(offsets); edit->blocks_changed_at = position.block; } else if (edit->offset_begin == old_document_end) { // If we're inserting at the end of the document to an empty block. edit->block_changed = position.block; edit->blocks_changed_at = position.block + 1; } else { // Anywhere at the block begin. // If we're inserting at the beginning of a block, // it's quite possible, that actually nothing changes. // But that depend on the things that use this notification. edit->block_changed = position.block + vector_count(offsets); edit->blocks_changed_at = position.block; } } else { // Inside the block edit->block_changed = position.block; edit->blocks_changed_at = position.block + 1; } // // Blocks // if (edit->blocks_changed_count > 0) { Document::Block block = {}; // We're inserting this *before* the position.block. vector_insert(&document->blocks, position.block, vector_count(offsets), block); for (memi i = 0; i != edit->blocks_changed_count; i++) { document->blocks[position.block + i].end = offsets[i]; } } for (memi i = position.block + edit->blocks_changed_count; i != vector_count(document->blocks); i++) { document->blocks[i].end += text_length; } document->blocks[edit->block_changed].flags = 0; edit->pos_begin = position; edit->pos_end = position_plus_offset(document, edit->pos_begin, text_length); // _write_undo(edit, Document::UndoEvent_Insert, edit->offset_begin, text_length); // Mark all views' layout to be invalid. document->view_flags = HALE_DOCUMENT_VIEW_LAYOUT_INVALID; // Invalidate block // Call this before we go for document_parse, so that the view's // is actually updated. _notify_views_about_insert(edit); // Move the parser head if (document_parser_set_head(document, edit->pos_begin.block)) { // TODO(cohen): If the time distance between inserts is small, // do not parse immediately. document_parse(document, 0.01f); } }