devexpress-richedit
Version:
DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.
160 lines (159 loc) • 10.3 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 { 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;
}
DEPRECATEDConvertOptionsParameter(parameter) {
return typeof parameter === 'string' ? { styleName: parameter } : parameter;
}
executeCore(state, options) {
const parameter = options.param;
if (StringUtils.isNullOrEmpty(parameter.styleName))
return false;
const subDocumentInterval = new SubDocumentInterval(options.subDocument, state.interval.clone());
let executed = true;
let isPresetStyle = false;
this.history.beginTransaction();
if (StylesManager.isParagraphStyle(parameter.styleName) && state.paragraphStyleChangeEnabled) {
const styleName = StylesManager.getStyleNameWithoutPrefix(parameter.styleName);
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(subDocumentInterval, paragraphStyle, isPresetStyle, parameter.keepCustomFormatting);
}
else if (!StylesManager.isParagraphStyle(parameter.styleName) && state.characterStyleChangeEnabled) {
const styleName = StylesManager.getStyleNameWithoutPrefix(parameter.styleName);
if (subDocumentInterval.interval.length == 0)
subDocumentInterval.interval = options.subDocument.getWholeWordInterval(subDocumentInterval.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 (subDocumentInterval.interval.length == 0) {
if (isPresetStyle) {
const 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(subDocumentInterval, characterStyle, isPresetStyle);
}
this.history.endTransaction();
return executed;
}
applyCharacterStyle(subDocumentInterval, style, isPresetStyle) {
if (ControlOptions.isEnabled(this.control.modelManager.richOptions.control.characterStyle)) {
const characterStyle = isPresetStyle ? this.control.modelManager.model.stylesManager.addCharacterStyle(style) : style;
this.modelManipulator.style.applyCharacterStyle(subDocumentInterval, characterStyle, false);
}
}
applyParagraphStyle(subDocumentInterval, style, isPresetStyle, keepCustomFormatting = false) {
const count = this.calculateAffectedParagraphCount(subDocumentInterval);
if (count > 0 && ControlOptions.isEnabled(this.control.modelManager.richOptions.control.paragraphStyle)) {
const { interval, subDocument } = subDocumentInterval;
const paragraphs = subDocument.paragraphs;
const paragraphIndex = SearchUtils.normedInterpolationIndexOf(paragraphs, p => p.startLogPosition.value, interval.start);
for (let i = 0; i < count; i++) {
const paragraph = paragraphs[paragraphIndex + i];
const modelManipulator = this.modelManipulator;
const paragraphSubDocumentInterval = new SubDocumentInterval(subDocument, paragraph.interval);
style = isPresetStyle ? modelManipulator.model.stylesManager.addParagraphStyle(style) : style;
this.history.addAndRedo(new ApplyParagraphStyleHistoryItem(modelManipulator, paragraphSubDocumentInterval, style));
this.history.addAndRedo(new ParagraphUseValueHistoryItem(modelManipulator, paragraphSubDocumentInterval, 0));
this.history.addAndRedo(new FontUseValueHistoryItem(modelManipulator, paragraphSubDocumentInterval, 0, keepCustomFormatting));
this.history.addAndRedo(new AddParagraphToListHistoryItem(modelManipulator, subDocument, paragraphIndex, NumberingList.NumberingListNotSettedIndex, -1));
}
}
else
this.applyParagraphLinkedStyle(subDocumentInterval, style, isPresetStyle);
}
applyParagraphLinkedStyle(subDocumentInterval, style, isPresetStyle) {
if (ControlOptions.isEnabled(this.control.modelManager.richOptions.control.characterStyle)) {
if (!style.linkedStyle)
this.addLinkedCharacterStyle(style);
this.applyCharacterStyle(subDocumentInterval, style.linkedStyle, isPresetStyle);
}
}
addLinkedCharacterStyle(paragraphStyle) {
const 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(subDocumentInterval) {
const { interval, subDocument } = subDocumentInterval;
const paragraphs = subDocument.getParagraphsByInterval(interval);
if (paragraphs.length > 1)
return paragraphs.length;
const paragraph = paragraphs[0];
const 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);
}
}