devexpress-richedit
Version:
DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.
153 lines (152 loc) • 9.87 kB
JavaScript
import { CharacterStyle } from '../../model/character/character-style';
import { ApplyParagraphStyleHistoryItem } from '../../model/history/items/apply-style-history-items';
import { FontUseValueHistoryItem } from '../../model/history/items/character-properties-history-items';
import { CreateStyleLinkHistoryItem } from '../../model/history/items/create-style-link-history-item';
import { AddParagraphToListHistoryItem } from '../../model/history/items/numbering-list-history-items';
import { ParagraphUseValueHistoryItem } from '../../model/history/items/paragraph-properties-history-items';
import { NumberingList } from '../../model/numbering-lists/numbering-list';
import { ControlOptions } from '../../model/options/control';
import { RichUtils } from '../../model/rich-utils';
import { StylesManager } from '../../model/styles-manager';
import { SubDocumentInterval } from '../../model/sub-document';
import { FixedInterval } from '@devexpress/utils/lib/intervals/fixed';
import { SearchUtils } from '@devexpress/utils/lib/utils/search';
import { CommandBase } from '../command-base';
import { StringUtils } from '@devexpress/utils/lib/utils/string';
import { ApplyStyleCommandState } from '../command-states';
export class ApplyStyleCommand extends CommandBase {
getState() {
var interval = this.selection.lastSelectedInterval.clone();
var commonParagraphStyle;
var commonCharacterStyle;
if (interval.length === 0)
commonCharacterStyle = this.inputPosition.getCharacterStyle();
if (!commonCharacterStyle || commonCharacterStyle.isDefault) {
var runs = this.selection.activeSubDocument.getRunsByInterval(interval);
var commonParagraphStyle = runs[0].paragraph.paragraphStyle;
var commonCharacterStyle = runs[0].characterStyle;
for (var i = 1, run; run = runs[i]; i++) {
if (commonCharacterStyle && run.characterStyle !== commonCharacterStyle)
commonCharacterStyle = null;
if (commonParagraphStyle && run.paragraph.paragraphStyle !== commonParagraphStyle)
commonParagraphStyle = null;
if (!commonParagraphStyle && !commonCharacterStyle)
break;
}
}
var styleNameWithPrefix = "";
if (commonCharacterStyle && commonCharacterStyle.linkedStyle)
styleNameWithPrefix = StylesManager.paragraphPrefix + this.getStyleName(commonCharacterStyle.linkedStyle);
else if (commonCharacterStyle && !commonCharacterStyle.isDefault)
styleNameWithPrefix = StylesManager.characterPrefix + this.getStyleName(commonCharacterStyle);
else if (commonParagraphStyle && !commonParagraphStyle.isDefault)
styleNameWithPrefix = StylesManager.paragraphPrefix + this.getStyleName(commonParagraphStyle);
else
styleNameWithPrefix = StylesManager.paragraphPrefix + this.getStyleName(this.control.modelManager.model.getDefaultParagraphStyle());
var state = new ApplyStyleCommandState(this.isEnabled(), this.selection.activeSubDocument.isEditable(this.getIntervalsForModifying()), this.selection.activeSubDocument.isEditable(super.getIntervalsForModifying()), interval, styleNameWithPrefix);
state.items = this.control.modelManager.model.stylesManager.characterAndParagraphStyleGalleryItems;
return state;
}
getStyleName(style) {
return style.styleName;
}
executeCore(state, options) {
const parameter = options.param;
if (StringUtils.isNullOrEmpty(parameter))
return false;
let interval = state.interval.clone();
let executed = true;
let isPresetStyle = false;
this.history.beginTransaction();
if (StylesManager.isParagraphStyle(parameter) && state.paragraphStyleChangeEnabled) {
const styleName = StylesManager.getStyleNameWithoutPrefix(parameter);
let paragraphStyle = this.control.modelManager.model.getParagraphStyleByName(styleName);
if (!paragraphStyle) {
const presetStyle = StylesManager.getPresetParagraphStyleByName(styleName);
if (!presetStyle)
return false;
paragraphStyle = StylesManager.getPresetParagraphStyleByName(styleName).clone();
isPresetStyle = true;
}
this.applyParagraphStyle(interval, paragraphStyle, isPresetStyle, options.subDocument);
}
else if (!StylesManager.isParagraphStyle(parameter) && state.characterStyleChangeEnabled) {
const styleName = StylesManager.getStyleNameWithoutPrefix(parameter);
if (interval.length == 0)
interval = options.subDocument.getWholeWordInterval(interval.start);
let characterStyle = this.control.modelManager.model.getCharacterStyleByName(styleName);
if (!characterStyle) {
const presetStyle = StylesManager.getPresetCharacterStyleByName(styleName);
if (!presetStyle)
return false;
characterStyle = presetStyle.clone();
isPresetStyle = true;
}
if (interval.length == 0) {
if (isPresetStyle) {
let fontInfo = characterStyle.maskedCharacterProperties.fontInfo;
if (fontInfo && fontInfo.measurer === undefined)
characterStyle.maskedCharacterProperties.fontInfo = this.control.modelManager.model.cache.fontInfoCache.getItemByName(fontInfo.name);
}
this.inputPosition.setCharacterStyle(characterStyle);
executed = false;
}
else
this.applyCharacterStyle(interval, characterStyle, isPresetStyle, options.subDocument);
}
this.history.endTransaction();
return executed;
}
applyCharacterStyle(interval, style, isPresetStyle, subDocument) {
if (ControlOptions.isEnabled(this.control.modelManager.richOptions.control.characterStyle)) {
this.modelManipulator.style.applyCharacterStyle(new SubDocumentInterval(subDocument, interval), isPresetStyle ? this.control.modelManager.model.stylesManager.addCharacterStyle(style) : style, false);
}
}
applyParagraphStyle(interval, style, isPresetStyle, subDocument) {
var count = this.calculateAffectedParagraphCount(interval, subDocument);
if (count > 0 && ControlOptions.isEnabled(this.control.modelManager.richOptions.control.paragraphStyle)) {
var paragraphIndex = SearchUtils.normedInterpolationIndexOf(subDocument.paragraphs, p => p.startLogPosition.value, interval.start);
for (var i = 0; i < count; i++) {
var paragraph = subDocument.paragraphs[paragraphIndex + i];
var paragraphInterval = new FixedInterval(paragraph.startLogPosition.value, paragraph.length);
var modelManipulator = this.modelManipulator;
this.history.addAndRedo(new ApplyParagraphStyleHistoryItem(modelManipulator, new SubDocumentInterval(subDocument, paragraphInterval), isPresetStyle ? modelManipulator.model.stylesManager.addParagraphStyle(style) : style));
this.history.addAndRedo(new ParagraphUseValueHistoryItem(modelManipulator, new SubDocumentInterval(subDocument, paragraphInterval), 0));
this.history.addAndRedo(new FontUseValueHistoryItem(modelManipulator, new SubDocumentInterval(subDocument, paragraphInterval), 0));
this.history.addAndRedo(new AddParagraphToListHistoryItem(this.modelManipulator, subDocument, paragraphIndex, NumberingList.NumberingListNotSettedIndex, -1));
}
}
else
this.applyParagraphLinkedStyle(interval, style, isPresetStyle, subDocument);
}
applyParagraphLinkedStyle(interval, style, isPresetStyle, subDocument) {
if (ControlOptions.isEnabled(this.control.modelManager.richOptions.control.characterStyle)) {
if (!style.linkedStyle)
this.createCharacterStyle(style);
this.applyCharacterStyle(interval, style.linkedStyle, isPresetStyle, subDocument);
}
}
createCharacterStyle(paragraphStyle) {
var style = new CharacterStyle(paragraphStyle.styleName + " Char", paragraphStyle.localizedName + " Char", false, false, false, false, paragraphStyle.maskedCharacterProperties);
this.history.addAndRedo(new CreateStyleLinkHistoryItem(this.modelManipulator, style, paragraphStyle));
}
calculateAffectedParagraphCount(interval, subDocument) {
var paragraphs = subDocument.getParagraphsByInterval(interval);
if (paragraphs.length > 1)
return paragraphs.length;
var paragraph = paragraphs[0];
var lastParagraphCharSelected = interval.length >= paragraph.length - 1;
if (interval.start === paragraph.startLogPosition.value && lastParagraphCharSelected || interval.length === 0)
return 1;
return 0;
}
isEnabled() {
return super.isEnabled() && (ControlOptions.isEnabled(this.control.modelManager.richOptions.control.characterStyle) || ControlOptions.isEnabled(this.control.modelManager.richOptions.control.paragraphStyle));
}
canModify() {
return this.selection.activeSubDocument.isEditable(this.getIntervalsForModifying()) || this.selection.activeSubDocument.isEditable(super.getIntervalsForModifying());
}
getIntervalsForModifying() {
return RichUtils.getIntervalsOfSelectedParagraphs(this.selection.intervals, this.selection.activeSubDocument);
}
}