Commit 173c7192 authored by Ilya.Kirillov's avatar Ilya.Kirillov Committed by Alexander.Trofimov

Сделано применение текстовых настроек в новом варианте параграфа (по...

Сделано применение текстовых настроек в новом варианте параграфа (по выделению, по курсору в середине слова и по курсору в начале или конце слова).

git-svn-id: svn://192.168.3.15/activex/AVS/Sources/TeamlabOffice/trunk/OfficeWeb@54064 954022d7-b5bf-4e40-9824-e11837661b57
parent 219bbb26
......@@ -349,6 +349,29 @@ Paragraph.prototype =
OtherParagraph.Style_Add( this.Style_Get(), true );
},
Split_Element_ByPos : function(SplitType, ContentPos)
{
// SplitType
// 0 - только ран разбиваем
var CurPos = ContentPos.Get(0);
var Element = this.Content[CurPos];
if ( 0 === SplitType )
{
var Result = Element.Split_Element_ByPos( SplitType, ContentPos, 1 );
if ( para_Run === Element.Type )
{
this.Content[CurPos].Split_Element_ByPos( ContentPos, 1 );
}
}
else
{
}
},
// Добавляем элемент в содержимое параграфа. (Здесь передвигаются все позиции
// CurPos.ContentPos, Selection.StartPos, Selection.EndPos)
Internal_Content_Add : function (Pos, Item, bCorrectPos)
......@@ -419,6 +442,15 @@ Paragraph.prototype =
{
History.Add( this, { Type : historyitem_Paragraph_AddItem, Pos : Pos, EndPos : Pos, Items : [ Item ] } );
this.Content.splice( Pos, 0, Item );
if ( this.CurPos.ContentPos >= Pos )
this.CurPos.ContentPos++;
if ( this.Selection.StartPos >= Pos )
this.Selection.StartPos++;
if ( this.Selection.EndPos >= Pos )
this.Selection.EndPos++;
}
},
......@@ -477,90 +509,108 @@ Paragraph.prototype =
// CurPos.ContentPos, Selection.StartPos, Selection.EndPos)
Internal_Content_Remove : function (Pos, bCorrectPos)
{
var Item = this.Content[Pos];
if ( true === Item.Is_RealContent() )
if ( true !== Debug_ParaRunMode )
{
var ClearPos = this.Internal_Get_ClearPos( Pos );
History.Add( this, { Type : historyitem_Paragraph_RemoveItem, Pos : ClearPos, EndPos : ClearPos, Items : [ Item ] } );
}
var Item = this.Content[Pos];
if ( true === Item.Is_RealContent() )
{
var ClearPos = this.Internal_Get_ClearPos( Pos );
History.Add( this, { Type : historyitem_Paragraph_RemoveItem, Pos : ClearPos, EndPos : ClearPos, Items : [ Item ] } );
}
if ( this.Selection.StartPos <= this.Selection.EndPos )
{
if ( this.Selection.StartPos > Pos )
this.Selection.StartPos--;
if ( this.Selection.StartPos <= this.Selection.EndPos )
{
if ( this.Selection.StartPos > Pos )
this.Selection.StartPos--;
if ( this.Selection.EndPos > Pos )
this.Selection.EndPos--;
}
else
{
if ( this.Selection.StartPos > Pos )
this.Selection.StartPos--;
if ( this.Selection.EndPos > Pos )
this.Selection.EndPos--;
}
else
{
if ( this.Selection.StartPos > Pos )
this.Selection.StartPos--;
if ( this.Selection.EndPos > Pos )
this.Selection.EndPos--;
}
if ( this.Selection.EndPos > Pos )
this.Selection.EndPos--;
}
if ( this.Numbering.Pos > Pos )
this.Numbering.Pos--;
if ( this.Numbering.Pos > Pos )
this.Numbering.Pos--;
// Также передвинем всем метки переносов страниц и строк
var LinesCount = this.Lines.length;
for ( var CurLine = 0; CurLine < LinesCount; CurLine++ )
{
if ( this.Lines[CurLine].StartPos > Pos )
this.Lines[CurLine].StartPos--;
// Также передвинем всем метки переносов страниц и строк
var LinesCount = this.Lines.length;
for ( var CurLine = 0; CurLine < LinesCount; CurLine++ )
{
if ( this.Lines[CurLine].StartPos > Pos )
this.Lines[CurLine].StartPos--;
if ( this.Lines[CurLine].EndPos >= Pos )
this.Lines[CurLine].EndPos--;
if ( this.Lines[CurLine].EndPos >= Pos )
this.Lines[CurLine].EndPos--;
var RangesCount = this.Lines[CurLine].Ranges.length;
for ( var CurRange = 0; CurRange < RangesCount; CurRange++ )
var RangesCount = this.Lines[CurLine].Ranges.length;
for ( var CurRange = 0; CurRange < RangesCount; CurRange++ )
{
if ( this.Lines[CurLine].Ranges[CurRange].StartPos > Pos )
this.Lines[CurLine].Ranges[CurRange].StartPos--;
}
}
// TODO: Как только мы избавимся от ParaNumbering в контенте параграфа, можно будет здесь такую обработку убрать
// и делать ее конкретно на Replace
// Передвинем все метки поиска
for ( var CurSearch in this.SearchResults )
{
if ( this.Lines[CurLine].Ranges[CurRange].StartPos > Pos )
this.Lines[CurLine].Ranges[CurRange].StartPos--;
if ( this.SearchResults[CurSearch].StartPos > Pos )
this.SearchResults[CurSearch].StartPos--;
if ( this.SearchResults[CurSearch].EndPos > Pos )
this.SearchResults[CurSearch].EndPos--;
}
}
// TODO: Как только мы избавимся от ParaNumbering в контенте параграфа, можно будет здесь такую обработку убрать
// и делать ее конкретно на Replace
// Передвинем все метки поиска
for ( var CurSearch in this.SearchResults )
{
if ( this.SearchResults[CurSearch].StartPos > Pos )
this.SearchResults[CurSearch].StartPos--;
for ( var Id in this.NearPosArray )
{
var NearPos = this.NearPosArray[Id];
if ( NearPos.ContentPos > Pos )
NearPos.ContentPos--;
}
if ( this.SearchResults[CurSearch].EndPos > Pos )
this.SearchResults[CurSearch].EndPos--;
}
this.Content.splice( Pos, 1 );
for ( var Id in this.NearPosArray )
{
var NearPos = this.NearPosArray[Id];
if ( NearPos.ContentPos > Pos )
NearPos.ContentPos--;
}
if ( this.CurPos.ContentPos > Pos )
this.Set_ContentPos( this.CurPos.ContentPos - 1, bCorrectPos );
this.Content.splice( Pos, 1 );
// Комментарий удаляем после, чтобы не нарушить позиции
if ( true === this.DeleteCommentOnRemove && ( para_CommentStart === Item.Type || para_CommentEnd === Item.Type ) )
{
// Удаляем комментарий, если у него было удалено начало или конец
if ( this.CurPos.ContentPos > Pos )
this.Set_ContentPos( this.CurPos.ContentPos - 1, bCorrectPos );
if ( para_CommentStart === Item.Type )
editor.WordControl.m_oLogicDocument.Comments.Set_StartInfo( Item.Id, 0, 0, 0, 0, null );
else
editor.WordControl.m_oLogicDocument.Comments.Set_EndInfo( Item.Id, 0, 0, 0, 0, null );
editor.WordControl.m_oLogicDocument.Remove_Comment( Item.Id, true );
}
// Комментарий удаляем после, чтобы не нарушить позиции
if ( true === this.DeleteCommentOnRemove && ( para_CommentStart === Item.Type || para_CommentEnd === Item.Type ) )
// Передвинем все метки слов для проверки орфографии
this.SpellChecker.Update_OnRemove( this, Pos, 1 );
}
else
{
// Удаляем комментарий, если у него было удалено начало или конец
var Item = this.Content[Pos];
History.Add( this, { Type : historyitem_Paragraph_RemoveItem, Pos : Pos, EndPos : Pos, Items : [ Item ] } );
this.Content.splice( Pos, 1 );
if ( para_CommentStart === Item.Type )
editor.WordControl.m_oLogicDocument.Comments.Set_StartInfo( Item.Id, 0, 0, 0, 0, null );
else
editor.WordControl.m_oLogicDocument.Comments.Set_EndInfo( Item.Id, 0, 0, 0, 0, null );
if ( this.Selection.StartPos > Pos )
this.Selection.StartPos--;
editor.WordControl.m_oLogicDocument.Remove_Comment( Item.Id, true );
}
if ( this.Selection.EndPos > Pos )
this.Selection.EndPos--;
// Передвинем все метки слов для проверки орфографии
this.SpellChecker.Update_OnRemove( this, Pos, 1 );
if ( this.CurPos.ContentPos > Pos )
this.CurPos.ContentPos--;
}
},
// Удаляем несколько элементов
......@@ -7749,7 +7799,94 @@ Paragraph.prototype =
}
case para_TextPr:
{
// TODO: Сделать добавление TextPr
var TextPr = Item.Value;
if ( undefined != TextPr.FontFamily )
{
var FName = TextPr.FontFamily.Name;
var FIndex = TextPr.FontFamily.Index;
TextPr.RFonts = new CRFonts();
TextPr.RFonts.Ascii = { Name : FName, Index : FIndex };
TextPr.RFonts.EastAsia = { Name : FName, Index : FIndex };
TextPr.RFonts.HAnsi = { Name : FName, Index : FIndex };
TextPr.RFonts.CS = { Name : FName, Index : FIndex };
}
// Удалим все лишние пустые раны из параграфа
this.Remove_EmptyRuns();
if ( true === this.ApplyToAll )
{
// Применяем настройки ко всем элементам параграфа
var ContentLen = this.Content.length;
for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
{
this.Content[CurPos].Apply_TextPr( TextPr );
}
// Выставляем настройки для символа параграфа
this.TextPr.Apply_TextPr( TextPr );
}
else
{
if ( true === this.Selection.Use )
{
this.Apply_TextPr(TextPr);
}
else
{
var CurParaPos = this.Get_ParaContentPos( false, false );
var CurPos = CurParaPos.Get(0);
// Сначала посмотрим на элемент слева и справа(текущий)
var SearchLPos = new CParagraphSearchPos();
this.Get_LeftPos( SearchLPos, CurParaPos );
var RItem = this.Get_RunElementByPos( CurParaPos );
var LItem = ( false === SearchLPos.Found ? null : this.Get_RunElementByPos( SearchLPos.Pos ) );
// 1. Если мы находимся в конце параграфа, тогда применяем заданную настройку к знаку параграфа
// и добавляем пустой ран с заданными настройками.
// 2. Если мы находимся в середине слова (справа и слева текстовый элемент, причем оба не пунктуация),
// тогда меняем настройки для данного слова.
// 3. Во всех остальных случаях вставляем пустой ран с заданными настройкми и переносим курсор в этот
// ран, чтобы при последующем наборе текст отрисовывался с нужными настройками.
if ( null === RItem || para_End === RItem.Type )
{
this.Apply_TextPr( TextPr );
this.TextPr.Apply_TextPr( TextPr );
}
else if ( null !== RItem && null !== LItem && para_Text === RItem.Type && para_Text === LItem.Type && false === RItem.Is_Punctuation() && false === LItem.Is_Punctuation() )
{
var SearchSPos = new CParagraphSearchPos();
var SearchEPos = new CParagraphSearchPos();
this.Get_WordStartPos( SearchSPos, CurParaPos );
this.Get_WordEndPos( SearchEPos, CurParaPos );
// Такого быть не должно, т.к. мы уже проверили, что справа и слева точно есть текст
if ( true !== SearchSPos.Found || true !== SearchEPos.Found )
return;
// Выставим временно селект от начала и до конца слова
this.Selection.Use = true;
this.Set_SelectionContentPos( SearchSPos.Pos, SearchEPos.Pos );
this.Apply_TextPr( TextPr );
// Убираем селект
this.Selection_Remove();
}
else
{
this.Apply_TextPr( TextPr );
}
}
}
break;
}
case para_HyperlinkStart:
......@@ -8721,6 +8858,29 @@ Paragraph.prototype =
}
},
// Получаем по заданной позиции элемент текста
Get_RunElementByPos : function(ContentPos)
{
var CurPos = ContentPos.Get(0);
var ContentLen = this.Content.length;
// Сначала ищем в текущем элементе
var Element = this.Content[CurPos].Get_RunElementByPos( ContentPos, 1 );
// Если заданная позиция была последней в текущем элементе, то ищем в следующем
while ( null === Element )
{
CurPos++;
if ( CurPos >= ContentLen )
break;
Element = this.Content[CurPos].Get_RunElementByPos();
}
return Element;
},
Get_LeftPos : function(SearchPos, ContentPos)
{
var Depth = 0;
......@@ -10591,8 +10751,6 @@ Paragraph.prototype =
Internal_AddTextPr : function(TextPr)
{
this.Internal_Clear_EmptyTextPr();
if ( undefined != TextPr.FontFamily )
{
var FName = TextPr.FontFamily.Name;
......@@ -10605,151 +10763,280 @@ Paragraph.prototype =
TextPr.RFonts.CS = { Name : FName, Index : FIndex };
}
if ( true === this.ApplyToAll )
if ( true !== Debug_ParaRunMode )
{
this.Internal_Content_Add( 0, new ParaTextPr( TextPr ) );
this.Internal_Clear_EmptyTextPr();
// Внутри каждого TextPr меняем те настройки, которые пришли в TextPr. Например,
// у нас изменен только размер шрифта, то изменяем запись о размере шрифта.
for ( var Pos = 0; Pos < this.Content.length; Pos++ )
if ( true === this.ApplyToAll )
{
if ( this.Content[Pos].Type == para_TextPr )
this.Content[Pos].Apply_TextPr( TextPr );
}
this.Internal_Content_Add( 0, new ParaTextPr( TextPr ) );
// Выставляем настройки для символа параграфа
this.TextPr.Apply_TextPr( TextPr );
// Внутри каждого TextPr меняем те настройки, которые пришли в TextPr. Например,
// у нас изменен только размер шрифта, то изменяем запись о размере шрифта.
for ( var Pos = 0; Pos < this.Content.length; Pos++ )
{
if ( this.Content[Pos].Type == para_TextPr )
this.Content[Pos].Apply_TextPr( TextPr );
}
return;
}
// Выставляем настройки для символа параграфа
this.TextPr.Apply_TextPr( TextPr );
// найдем текущую позицию
var Line = this.Content;
var CurPos = this.CurPos.ContentPos;
if ( true === this.Selection.Use )
{
var StartPos = this.Selection.StartPos;
var EndPos = this.Selection.EndPos;
return;
}
if ( StartPos > EndPos )
// найдем текущую позицию
var Line = this.Content;
var CurPos = this.CurPos.ContentPos;
if ( true === this.Selection.Use )
{
var Temp = EndPos;
EndPos = StartPos;
StartPos = Temp;
var StartPos = this.Selection.StartPos;
var EndPos = this.Selection.EndPos;
if ( StartPos > EndPos )
{
var Temp = EndPos;
EndPos = StartPos;
StartPos = Temp;
}
// Если селект продолжается до конца параграфа, не ставим отметку в конце
var LastPos = this.Internal_GetEndPos();
var bEnd = false;
if ( EndPos > LastPos )
{
EndPos = LastPos;
bEnd = true;
}
// Рассчитываем шрифт, который используется после слова
var TextPr_end = this.Internal_GetTextPr( EndPos );
var TextPr_start = this.Internal_GetTextPr( StartPos );
TextPr_start.Merge( TextPr );
this.Internal_Content_Add( StartPos, new ParaTextPr( TextPr_start ) );
if ( false === bEnd )
this.Internal_Content_Add( EndPos + 1, new ParaTextPr( TextPr_end ) );
else
{
// Выставляем настройки для символа параграфа
this.TextPr.Apply_TextPr( TextPr );
}
// Если внутри слова были изменения текстовых настроек, тогда удаляем только те записи, которые
// меняются сейчас. Например, у нас изменен только размер шрифта, то удаляем запись о размере шрифта.
for ( var Pos = StartPos + 1; Pos < EndPos; Pos++ )
{
if ( this.Content[Pos].Type == para_TextPr )
{
this.Content[Pos].Apply_TextPr( TextPr );
}
}
return;
}
// Если селект продолжается до конца параграфа, не ставим отметку в конце
var LastPos = this.Internal_GetEndPos();
var bEnd = false;
if ( EndPos > LastPos )
// При изменении шрифта ведем себе следующим образом:
// 1. Если мы в конце параграфа, тогда добавляем запись о шрифте (применимо к знаку конца параграфа)
// 2. Если справа или слева стоит пробел (начало параграфа или перенос строки(командный)), тогда ставим метку со шрифтом и фокусим канву.
// 3. Если мы посередине слова, тогда меняем шрифт для данного слова
var oEnd = this.Internal_FindForward ( CurPos, [para_PageNum, para_Drawing, para_Tab, para_Text, para_Space, para_End, para_NewLine] );
var oStart = this.Internal_FindBackward( CurPos - 1, [para_PageNum, para_Drawing, para_Tab, para_Text, para_Space, para_NewLine] );
var CurType = this.Content[CurPos].Type;
if ( !oEnd.Found )
return;
if ( para_End == oEnd.Type )
{
EndPos = LastPos;
bEnd = true;
// Вставляем запись о новых настройках перед концом параграфа, а текущую позицию выставляем на конец параграфа
var Pos = oEnd.LetterPos;
var TextPr_start = this.Internal_GetTextPr( Pos );
TextPr_start.Merge( TextPr );
this.Internal_Content_Add( Pos, new ParaTextPr( TextPr_start ) );
this.Set_ContentPos( Pos + 1, false, -1 );
if ( true === this.IsEmpty() && undefined === this.Numbering_Get() )
{
// Выставляем настройки для символа параграфа
this.TextPr.Apply_TextPr( TextPr );
}
}
else if ( para_PageNum === CurType || para_Drawing === CurType || para_Tab == CurType || para_Space == CurType || para_NewLine == CurType || !oStart.Found || para_NewLine == oEnd.Type || para_Space == oEnd.Type || para_NewLine == oStart.Type || para_Space == oStart.Type || para_Tab == oEnd.Type || para_Tab == oStart.Type || para_Drawing == oEnd.Type || para_Drawing == oStart.Type || para_PageNum == oEnd.Type || para_PageNum == oStart.Type )
{
var TextPr_old = this.Internal_GetTextPr( CurPos );
var TextPr_new = TextPr_old.Copy();
TextPr_new.Merge( TextPr );
// Рассчитываем шрифт, который используется после слова
var TextPr_end = this.Internal_GetTextPr( EndPos );
var TextPr_start = this.Internal_GetTextPr( StartPos );
TextPr_start.Merge( TextPr );
this.Internal_Content_Add( CurPos, new ParaTextPr( TextPr_old ) );
this.Internal_Content_Add( CurPos, new ParaTextPr( TextPr_new ) );
this.Internal_Content_Add( StartPos, new ParaTextPr( TextPr_start ) );
if ( false === bEnd )
this.Internal_Content_Add( EndPos + 1, new ParaTextPr( TextPr_end ) );
this.Set_ContentPos( CurPos + 1, false, -1 );
this.RecalculateCurPos();
}
else
{
// Выставляем настройки для символа параграфа
this.TextPr.Apply_TextPr( TextPr );
// Мы находимся посередине слова. В начале слова ставим запись о новом шрифте,
// а в конце слова старый шрифт. Кроме этого, надо удалить все записи о шрифте внутри слова.
// Найдем начало слова
var oWordStart = this.Internal_FindBackward( CurPos, [para_PageNum, para_Drawing, para_Tab, para_Space, para_NewLine] );
if ( !oWordStart.Found )
oWordStart = this.Internal_FindForward( 0, [para_Text] );
else
oWordStart.LetterPos++;
var oWordEnd = this.Internal_FindForward( CurPos, [para_PageNum, para_Drawing, para_Tab, para_Space, para_End, para_NewLine] );
if ( !oWordStart.Found || !oWordEnd.Found )
return;
// Рассчитываем настройки, которые используются после слова
var TextPr_end = this.Internal_GetTextPr( oWordEnd.LetterPos );
var TextPr_start = this.Internal_GetTextPr( oWordStart.LetterPos );
TextPr_start.Merge( TextPr );
this.Internal_Content_Add( oWordStart.LetterPos, new ParaTextPr( TextPr_start ) );
this.Internal_Content_Add( oWordEnd.LetterPos + 1 /* из-за предыдущего Internal_Content_Add */, new ParaTextPr( TextPr_end ) );
this.Set_ContentPos( CurPos + 1, false, -1 );
// Если внутри слова были изменения текстовых настроек, тогда удаляем только те записи, которые
// меняются сейчас. Например, у нас изменен только размер шрифта, то удаляем запись о размере шрифта.
for ( var Pos = oWordStart.LetterPos + 1; Pos < oWordEnd.LetterPos; Pos++ )
{
if ( this.Content[Pos].Type == para_TextPr )
this.Content[Pos].Apply_TextPr( TextPr );
}
}
}
},
// Если внутри слова были изменения текстовых настроек, тогда удаляем только те записи, которые
// меняются сейчас. Например, у нас изменен только размер шрифта, то удаляем запись о размере шрифта.
for ( var Pos = StartPos + 1; Pos < EndPos; Pos++ )
Remove_EmptyRuns : function()
{
var ContentLen = this.Content.length;
for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
{
var Element = this.Content[CurPos];
if ( para_Run === Element.Type )
{
if ( this.Content[Pos].Type == para_TextPr )
if ( CurPos !== this.CurPos.ContentPos && true === Element.Is_Empty(false) )
{
this.Content[Pos].Apply_TextPr( TextPr );
this.Internal_Content_Remove( CurPos );
CurPos--;
ContentLen--;
}
}
return;
else
Element.Remove_EmptyRuns();
}
},
// При изменении шрифта ведем себе следующим образом:
// 1. Если мы в конце параграфа, тогда добавляем запись о шрифте (применимо к знаку конца параграфа)
// 2. Если справа или слева стоит пробел (начало параграфа или перенос строки(командный)), тогда ставим метку со шрифтом и фокусим канву.
// 3. Если мы посередине слова, тогда меняем шрифт для данного слова
Apply_TextPr : function(TextPr)
{
// Данная функция работает по следующему принципу: если задано выделение, тогда применяем настройки к
// выделенной части, а если выделения нет, тогда в текущее положение вставляем пустой ран с заданными настройками
// и переносим курсор в данный ран.
var oEnd = this.Internal_FindForward ( CurPos, [para_PageNum, para_Drawing, para_Tab, para_Text, para_Space, para_End, para_NewLine] );
var oStart = this.Internal_FindBackward( CurPos - 1, [para_PageNum, para_Drawing, para_Tab, para_Text, para_Space, para_NewLine] );
var CurType = this.Content[CurPos].Type;
if ( true === this.Selection.Use )
{
var StartPos = this.Selection.StartPos;
var EndPos = this.Selection.EndPos;
if ( !oEnd.Found )
return;
if ( StartPos === EndPos )
{
var NewElements = this.Content[EndPos].Apply_TextPr( TextPr );
if ( para_End == oEnd.Type )
{
// Вставляем запись о новых настройках перед концом параграфа, а текущую позицию выставляем на конец параграфа
var Pos = oEnd.LetterPos;
if ( para_Run === this.Content[EndPos].Type )
{
var CenterRunPos = this.Internal_ReplaceRun( EndPos, NewElements );
var TextPr_start = this.Internal_GetTextPr( Pos );
TextPr_start.Merge( TextPr );
// TODO: разобраться здесь получше, как правильно обновлять позицию
if ( StartPos === this.CurPos.ContentPos )
this.CurPos.ContentPos = CenterRunPos;
this.Internal_Content_Add( Pos, new ParaTextPr( TextPr_start ) );
this.Set_ContentPos( Pos + 1, false, -1 );
// Подправим селект
this.Selection.StartPos = CenterRunPos;
this.Selection.EndPos = CenterRunPos;
if ( true === this.IsEmpty() && undefined === this.Numbering_Get() )
{
// Выставляем настройки для символа параграфа
this.TextPr.Apply_TextPr( TextPr );
}
}
}
else if ( para_PageNum === CurType || para_Drawing === CurType || para_Tab == CurType || para_Space == CurType || para_NewLine == CurType || !oStart.Found || para_NewLine == oEnd.Type || para_Space == oEnd.Type || para_NewLine == oStart.Type || para_Space == oStart.Type || para_Tab == oEnd.Type || para_Tab == oStart.Type || para_Drawing == oEnd.Type || para_Drawing == oStart.Type || para_PageNum == oEnd.Type || para_PageNum == oStart.Type )
{
var TextPr_old = this.Internal_GetTextPr( CurPos );
var TextPr_new = TextPr_old.Copy();
TextPr_new.Merge( TextPr );
else
{
var Direction = 1;
if ( StartPos > EndPos )
{
var Temp = StartPos;
StartPos = EndPos;
EndPos = Temp;
this.Internal_Content_Add( CurPos, new ParaTextPr( TextPr_old ) );
this.Internal_Content_Add( CurPos, new ParaTextPr( TextPr_new ) );
Direction = -1;
}
this.Set_ContentPos( CurPos + 1, false, -1 );
this.RecalculateCurPos();
for ( var CurPos = StartPos + 1; CurPos < EndPos; CurPos++ )
{
this.Content[CurPos].Apply_TextPr( TextPr );
}
var NewElements = this.Content[EndPos].Apply_TextPr( TextPr );
if ( para_Run === this.Content[EndPos].Type )
this.Internal_ReplaceRun( EndPos, NewElements );
var NewElements = this.Content[StartPos].Apply_TextPr( TextPr );
if ( para_Run === this.Content[StartPos].Type )
this.Internal_ReplaceRun( StartPos, NewElements );
// Заметим, что здесь не нужно подправлять метки выделения, за счет того, что EndPos - StartPos > 1 и
// сами метки подправляются в функиях Internal_Content_Add.
}
}
else
{
// Мы находимся посередине слова. В начале слова ставим запись о новом шрифте,
// а в конце слова старый шрифт. Кроме этого, надо удалить все записи о шрифте внутри слова.
var Pos = this.CurPos.ContentPos;
var Element = this.Content[Pos];
var NewElements = Element.Apply_TextPr( TextPr );
// Найдем начало слова
var oWordStart = this.Internal_FindBackward( CurPos, [para_PageNum, para_Drawing, para_Tab, para_Space, para_NewLine] );
if ( !oWordStart.Found )
oWordStart = this.Internal_FindForward( 0, [para_Text] );
else
oWordStart.LetterPos++;
if ( para_Run === Element.Type )
{
var CenterRunPos = this.Internal_ReplaceRun( Pos, NewElements );
this.CurPos.ContentPos = CenterRunPos;
this.CurPos.Line = -1;
}
}
},
var oWordEnd = this.Internal_FindForward( CurPos, [para_PageNum, para_Drawing, para_Tab, para_Space, para_End, para_NewLine] );
Internal_ReplaceRun : function(Pos, NewRuns)
{
// По логике, можно удалить Run, стоящий в позиции Pos и добавить все раны, которые не null в массиве NewRuns.
// Но, согласно работе ParaRun.Apply_TextPr, в массиве всегда идет ровно 3 рана (возможно null). Второй ран
// всегда не null. Первый не null ран и есть ран, идущий в позиции Pos.
if ( !oWordStart.Found || !oWordEnd.Found )
return;
var LRun = NewRuns[0];
var CRun = NewRuns[1];
var RRun = NewRuns[2];
// Рассчитываем настройки, которые используются после слова
var TextPr_end = this.Internal_GetTextPr( oWordEnd.LetterPos );
var TextPr_start = this.Internal_GetTextPr( oWordStart.LetterPos );
TextPr_start.Merge( TextPr );
// CRun - всегда не null
var CenterRunPos = Pos;
this.Internal_Content_Add( oWordStart.LetterPos, new ParaTextPr( TextPr_start ) );
this.Internal_Content_Add( oWordEnd.LetterPos + 1 /* из-за предыдущего Internal_Content_Add */, new ParaTextPr( TextPr_end ) );
if ( null !== LRun )
{
this.Internal_Content_Add( Pos + 1, CRun );
CenterRunPos = Pos + 1;
}
else
{
// Если LRun - null, значит CRun - это и есть тот ран который стоит уже в позиции Pos
}
this.Set_ContentPos( CurPos + 1, false, -1 );
if ( null !== RRun )
this.Internal_Content_Add( CenterRunPos + 1, RRun );
// Если внутри слова были изменения текстовых настроек, тогда удаляем только те записи, которые
// меняются сейчас. Например, у нас изменен только размер шрифта, то удаляем запись о размере шрифта.
for ( var Pos = oWordStart.LetterPos + 1; Pos < oWordEnd.LetterPos; Pos++ )
{
if ( this.Content[Pos].Type == para_TextPr )
this.Content[Pos].Apply_TextPr( TextPr );
}
}
return CenterRunPos;
},
Internal_AddHyperlink : function(Hyperlink_start)
......@@ -18660,6 +18947,11 @@ CParagraphContentPos.prototype =
this.Depth = Depth + 1;
},
Update2 : function(Pos, Depth)
{
this.Data[Depth] = Pos;
},
Set : function(OtherPos)
{
// Копируем позицию
......
......@@ -121,7 +121,7 @@ ParaRun.prototype =
// Добавляем элемент в позицию с сохранием в историю
Add_ToContent : function(Pos, Item, UpdatePosition)
{
History.Add( this, { Type : historyitem_Run_AddItem, Pos : Pos, EndPos : Pos, Items : [ Item ] } );
History.Add( this, { Type : historyitem_ParaRun_AddItem, Pos : Pos, EndPos : Pos, Items : [ Item ] } );
this.Content.splice( Pos, 0, Item );
if ( true === UpdatePosition )
......@@ -200,7 +200,7 @@ ParaRun.prototype =
this.State.ContentPos = Pos;
// Обновим начало и конец селекта
if ( true === this.Selection.Use )
if ( true === this.State.Selection.Use )
{
if ( this.State.Selection.StartPos <= this.State.Selection.EndPos )
{
......@@ -270,6 +270,17 @@ ParaRun.prototype =
this.RecalcInfo.Measure = true;
},
Concat_ToContent : function(NewItems)
{
var StartPos = this.Content.length;
this.Content = this.Content.concat( NewItems );
History.Add( this, { Type : historyitem_ParaRun_AddItem, Pos : StartPos, EndPos : this.Content.length - 1, Items : NewItems } );
// Отмечаем, что надо перемерить элементы в данном ране
this.RecalcInfo.Measure = true;
},
// Определим строку и отрезок текущей позиции
Get_CurrentParaPos : function()
{
......@@ -483,7 +494,7 @@ ParaRun.prototype =
return false;
var Type = Changes[0].Data.Type;
if ( historyitem_Run_AddItem === Type || historyitem_Run_RemoveItem === Type )
if ( historyitem_ParaRun_AddItem === Type || historyitem_ParaRun_RemoveItem === Type )
return true;
return false;
......@@ -493,7 +504,7 @@ ParaRun.prototype =
Get_SimpleChanges_ParaPos : function(Changes)
{
var Change = Changes[0].Data;
var Pos = ( Changes[0].Data.Type === historyitem_Run_AddItem ? Change.Pos : Change.StartPos );
var Pos = ( Changes[0].Data.Type === historyitem_ParaRun_AddItem ? Change.Pos : Change.StartPos );
var CurLine = 0;
var CurRange = 0;
......@@ -512,6 +523,23 @@ ParaRun.prototype =
return new CParaPos( this.StartRange, this.StartLine, 0, 0 );
},
Split : function (ContentPos, Depth)
{
var CurPos = ContentPos.Get(Depth);
// Создаем новый ран
var NewRun = new ParaRun(this.Document, this.Parent);
// Копируем настройки
NewRun.Set_Pr( this.Pr.Copy() );
// Разделяем содержимое по ранам
NewRun.Concat_ToContent( this.Content.slice(CurPos) );
this.Remove_FromContent( CurPos, this.Content.length - CurPos, true );
return NewRun;
},
//-----------------------------------------------------------------------------------
// Функции пересчета
//-----------------------------------------------------------------------------------
......@@ -2376,6 +2404,9 @@ ParaRun.prototype =
// Проверяем нужно ли поправить позицию курсора
Cursor_Is_NeededCorrectPos : function()
{
if ( true === this.Is_Empty(false) )
return true;
var NewRangeStart = false;
var RangeEnd = false;
......@@ -2566,6 +2597,27 @@ ParaRun.prototype =
this.State.ContentPos = Pos;
},
Get_RunElementByPos : function(ContentPos, Depth)
{
if ( undefined !== ContentPos )
{
var CurPos = ContentPos.Get(Depth);
var ContentLen = this.Content.length;
if ( CurPos >= this.Content.length || CurPos < 0 )
return null;
return this.Content[CurPos];
}
else
{
if ( this.Content.length > 0 )
return this.Content[0];
else
return null;
}
},
Get_LeftPos : function(SearchPos, ContentPos, Depth, UseContentPos)
{
var CurPos = ( true === UseContentPos ? ContentPos.Get(Depth) : this.Content.length );
......@@ -3133,12 +3185,143 @@ ParaRun.prototype =
Set_Pr : function(TextPr)
{
var OldValue = this.Pr;
this.Pr = Value;
this.Pr = TextPr;
History.Add( this, { Type : historyitem_ParaRun_TextPr, New : Value, Old : OldValue } );
History.Add( this, { Type : historyitem_ParaRun_TextPr, New : TextPr, Old : OldValue } );
this.Recalc_CompiledPr(true);
},
Apply_TextPr : function(TextPr)
{
var Result = [];
var LRun = this, CRun = null, RRun = null;
if ( true === this.State.Selection.Use )
{
var StartPos = this.State.Selection.StartPos;
var EndPos = this.State.Selection.EndPos;
if ( StartPos > EndPos )
{
var Temp = StartPos;
StartPos = EndPos;
EndPos = Temp;
}
// Если выделено не до конца, тогда разделяем по последней точке
if ( EndPos < this.Content.length )
{
RRun = LRun.Split_Run( EndPos );
}
// Если выделено не с начала, тогда делим по начальной точке
if ( StartPos > 0 )
{
CRun = LRun.Split_Run( StartPos );
}
else
{
CRun = LRun;
LRun = null;
}
if ( null !== LRun )
LRun.Selection_Remove();
CRun.Select_All();
CRun.Apply_Pr( TextPr );
if ( null !== RRun )
RRun.Selection_Remove();
}
else
{
var CurPos = this.State.ContentPos;
// Если выделено не до конца, тогда разделяем по последней точке
if ( CurPos < this.Content.length )
{
RRun = LRun.Split_Run( CurPos );
}
if ( CurPos > 0 )
{
CRun = LRun.Split_Run( CurPos );
}
else
{
CRun = LRun;
LRun = null;
}
if ( null !== LRun )
LRun.Selection_Remove();
CRun.Selection_Remove();
CRun.Cursor_MoveToStartPos();
CRun.Apply_Pr( TextPr );
if ( null !== RRun )
RRun.Selection_Remove();
}
Result.push( LRun );
Result.push( CRun );
Result.push( RRun );
return Result;
},
Split_Run : function(Pos)
{
// Создаем новый ран
var NewRun = new ParaRun(this.Document, this.Parent);
// Копируем настройки
NewRun.Set_Pr( this.Pr.Copy() );
var OldCrPos = this.State.ContentPos;
var OldSSPos = this.State.Selection.StartPos;
var OldSEPos = this.State.Selection.EndPos;
// Разделяем содержимое по ранам
NewRun.Concat_ToContent( this.Content.slice(Pos) );
this.Remove_FromContent( Pos, this.Content.length - Pos, true );
// Подправим точки селекта и текущей позиции
if ( OldCrPos >= Pos )
{
NewRun.State.ContentPos = OldCrPos - Pos;
this.State.ContentPos = this.Content.length;
}
else
{
NewRun.State.ContentPos = 0;
}
if ( OldSSPos >= Pos )
{
NewRun.State.Selection.StartPos = OldSSPos - Pos;
this.State.Selection.StartPos = this.Content.length;
}
else
{
NewRun.State.Selection.StartPos = 0;
}
if ( OldSEPos >= Pos )
{
NewRun.State.Selection.EndPos = OldSEPos - Pos;
this.State.Selection.EndPos = this.Content.length;
}
else
{
NewRun.State.Selection.EndPos = 0;
}
return NewRun;
},
// В данной функции мы применяем приходящие настройки поверх старых, т.е. старые не удаляем
Apply_Pr : function(TextPr)
{
......@@ -3188,7 +3371,7 @@ ParaRun.prototype =
this.Set_RFonts2( TextPr.RFonts );
if ( undefined != TextPr.Lang )
this.Set_Lang( TextPr.Lang );
this.Set_Lang2( TextPr.Lang );
},
Set_Bold : function(Value)
......@@ -3538,10 +3721,25 @@ ParaRun.prototype =
if ( undefined != Value )
this.Pr.Lang.Set_FromObject( Value );
History.Add( this, { Type : historyitem_ParaRun_Lang, New : NewValue, Old : OldValue } );
History.Add( this, { Type : historyitem_ParaRun_Lang, New : this.Pr.Lang, Old : OldValue } );
this.Recalc_CompiledPr(false);
},
Set_Lang2 : function(Lang)
{
if ( undefined != Lang )
{
if ( undefined != Lang.Bidi )
this.Set_Lang_Bidi( Lang.Bidi );
if ( undefined != Lang.EastAsia )
this.Set_Lang_EastAsia( Lang.EastAsia );
if ( undefined != Lang.Val )
this.Set_Lang_Val( Lang.Val );
}
},
Set_Lang_Bidi : function(Value)
{
if ( Value !== this.Pr.Land.Bidi )
......@@ -3610,8 +3808,28 @@ ParaRun.prototype =
Load_Changes : function(Reader)
{
}
},
Write_ToBinary2 : function(Writer)
{
},
Read_FromBinary2 : function(Reader)
{
},
Write_ToBinary : function(Writer)
{
// TODO: Скорее всего надо будет убрать эти функции
},
Read_FromBinary : function(Reader)
{
// TODO: Скорее всего надо будет убрать эти функции
},
};
function CParaRunSelection()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment