Hyperlink.js 69.7 KB
Newer Older
Alexander.Trofimov's avatar
Alexander.Trofimov committed
1 2
"use strict";

3 4 5 6 7 8
/**
 * Created by Ilja.Kirillov on 17.02.14.
 */

function ParaHyperlink()
{
9 10
    ParaRun.superclass.constructor.call(this);

11 12 13 14 15 16 17 18
    this.Id = g_oIdCounter.Get_NewId();

    this.Type    = para_Hyperlink;
    this.Value   = "";
    this.Visited = false;
    this.ToolTip = "";

    this.State = new CParaRunState();
19
    this.Selection = this.State.Selection;
20

21
    this.Content = [];
22

23 24
    this.m_oContentChanges = new CContentChanges(); // список изменений(добавление/удаление элементов)

25 26 27
    this.NearPosArray  = [];
    this.SearchMarks   = [];
    this.SpellingMarks = [];
28

29 30 31 32
    // Добавляем данный класс в таблицу Id (обязательно в конце конструктора)
    g_oTableId.Add( this, this.Id );
}

33 34 35
Asc.extendClass(ParaHyperlink, CParagraphContentWithContentBase)

ParaHyperlink.prototype.Get_Id = function()
36
{
37 38
    return this.Id;
};
39

40 41 42 43
ParaHyperlink.prototype.Clear_ContentChanges = function()
{
    this.m_oContentChanges.Clear();
};
44

45 46 47 48
ParaHyperlink.prototype.Add_ContentChanges = function(Changes)
{
    this.m_oContentChanges.Add( Changes );
};
49

50 51 52 53
ParaHyperlink.prototype.Refresh_ContentChanges = function()
{
    this.m_oContentChanges.Refresh();
};
54

55 56 57
ParaHyperlink.prototype.Copy = function(Selected)
{
    var NewHyperlink = new ParaHyperlink();
58

59 60
    NewHyperlink.Set_Value( this.Value );
    NewHyperlink.Set_ToolTip( this.ToolTip );
61

62 63 64 65 66 67
    NewHyperlink.Visited = this.Visited;

    var StartPos = 0;
    var EndPos   = this.Content.length - 1;

    if ( true === Selected && true === this.State.Selection.Use )
68
    {
69 70
        StartPos = this.State.Selection.StartPos;
        EndPos   = this.State.Selection.EndPos;
71

72 73 74 75 76 77
        if ( StartPos > EndPos )
        {
            StartPos = this.State.Selection.EndPos;
            EndPos   = this.State.Selection.StartPos;
        }
    }
78

79
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
80
    {
81
        var Item = this.Content[CurPos];
82

83 84 85 86 87 88 89 90 91 92 93 94 95
        if ( StartPos === CurPos || EndPos === CurPos )
            NewHyperlink.Add_ToContent( CurPos - StartPos, Item.Copy(Selected) );
        else
            NewHyperlink.Add_ToContent( CurPos - StartPos, Item.Copy(false) );
    }

    return NewHyperlink;
};

ParaHyperlink.prototype.Recalc_RunsCompiledPr = function()
{
    var Count = this.Content.length;
    for (var Pos = 0; Pos < Count; Pos++)
96
    {
97 98 99 100 101 102
        var Element = this.Content[Pos];

        if (Element.Recalc_RunsCompiledPr)
            Element.Recalc_RunsCompiledPr();
    }
};
103

104 105 106 107
ParaHyperlink.prototype.Get_AllDrawingObjects = function(DrawingObjs)
{
    var Count = this.Content.length;
    for ( var Index = 0; Index < Count; Index++ )
108
    {
109 110 111 112 113 114 115 116 117 118
        var Item = this.Content[Index];

        if ( para_Run === Item.Type || para_Hyperlink === Item.Type )
            Item.Get_AllDrawingObjects(DrawingObjs);
    }
};

ParaHyperlink.prototype.Set_Paragraph = function(Paragraph)
{
    this.Paragraph = Paragraph;
119

120 121
    var ContentLen = this.Content.length;
    for (var CurPos = 0; CurPos < ContentLen; CurPos++)
122
    {
123 124 125
        this.Content[CurPos].Set_Paragraph( Paragraph );
    }
};
126

127 128 129 130
ParaHyperlink.prototype.Is_Empty = function()
{
    var ContentLen = this.Content.length;
    for ( var Index = 0; Index < ContentLen; Index++ )
131
    {
132 133 134
        if ( false === this.Content[Index].Is_Empty() )
            return false;
    }
135

136 137
    return true;
};
138

139 140 141 142 143 144 145 146
ParaHyperlink.prototype.Is_CheckingNearestPos = function()
{
    if (this.NearPosArray.length > 0)
        return true;

    return false;
};

147 148 149 150
ParaHyperlink.prototype.Is_StartFromNewLine = function()
{
    if ( this.Content.length < 0 )
        return false;
151

152 153
    return this.Content[0].Is_StartFromNewLine();
};
154

155 156 157 158
ParaHyperlink.prototype.Get_SelectedText = function(bAll, bClearText)
{
    var Str = "";
    var Count = this.Content.length;
159

160 161 162
    for ( var Pos = 0; Pos < Count; Pos++ )
    {
        var _Str = this.Content[Pos].Get_SelectedText( bAll, bClearText );
163

164 165
        if ( null === _Str )
            return null;
166

167 168
        Str += _Str;
    }
169

170 171
    return Str;
};
172

173 174 175 176 177 178 179 180 181 182 183 184 185
ParaHyperlink.prototype.Get_SelectionDirection = function()
{
    if (true !== this.Selection.Use)
        return 0;

    if (this.Selection.StartPos < this.Selection.EndPos)
        return 1;
    else if (this.Selection.StartPos > this.Selection.EndPos)
        return -1;

    return this.Content[this.Selection.StartPos].Get_SelectionDirection();
};

186 187 188 189 190 191 192 193 194 195 196 197 198
ParaHyperlink.prototype.Get_TextPr = function(_ContentPos, Depth)
{
    if ( undefined === _ContentPos )
        return this.Content[0].Get_TextPr();
    else
        return this.Content[_ContentPos.Get(Depth)].Get_TextPr( _ContentPos, Depth + 1 );
};

ParaHyperlink.prototype.Get_CompiledTextPr = function(Copy)
{
    var TextPr = null;

    if ( true === this.State.Selection )
199
    {
200 201 202 203
        var StartPos = this.State.Selection.StartPos;
        var EndPos   = this.State.Selection.EndPos;

        if ( StartPos > EndPos )
204
        {
205 206
            StartPos = this.State.Selection.EndPos;
            EndPos   = this.State.Selection.StartPos;
207
        }
208

209
        TextPr = this.Content[StartPos].Get_CompiledTextPr(Copy);
210

211
        while ( null === TextPr && StartPos < EndPos )
212
        {
213 214
            StartPos++;
            TextPr = this.Content[StartPos].Get_CompiledTextPr(Copy);
215 216
        }

217
        for ( var CurPos = StartPos + 1; CurPos <= EndPos; CurPos++ )
218
        {
219 220 221 222
            var CurTextPr = this.Content[CurPos].Get_CompiledPr(false);

            if ( null !== CurTextPr )
                TextPr = TextPr.Compare( CurTextPr );
223
        }
224 225 226 227
    }
    else
    {
        var CurPos = this.State.ContentPos;
228

229 230 231
        if ( CurPos >= 0 && CurPos < this.Content.length )
            TextPr = this.Content[CurPos].Get_CompiledTextPr(Copy);
    }
232

233 234
    return TextPr;
};
235

236 237 238 239 240 241
ParaHyperlink.prototype.Check_Content = function()
{
    // Данная функция запускается при чтении файла. Заглушка, на случай, когда в Hyperlink ничего не будет
    if ( this.Content.length <= 0 )
        this.Add_ToContent( 0, new ParaRun(), false );
};
242

243 244 245 246
ParaHyperlink.prototype.Add_ToContent = function(Pos, Item, UpdatePosition)
{
    History.Add( this, { Type : historyitem_Hyperlink_AddItem, Pos : Pos, EndPos : Pos, Items : [ Item ] } );
    this.Content.splice( Pos, 0, Item );
247

248
    if ( true === UpdatePosition )
249
    {
250 251 252
        // Обновляем текущую позицию
        if ( this.State.ContentPos >= Pos )
            this.State.ContentPos++;
253

254 255
        // Обновляем начало и конец селекта
        if ( true === this.State.Selection.Use )
256
        {
257 258 259 260 261 262
            if ( this.State.Selection.StartPos >= Pos )
                this.State.Selection.StartPos++;

            if ( this.State.Selection.EndPos >= Pos )
                this.State.Selection.EndPos++;
        }
263

264 265 266 267 268 269
        // Также передвинем всем метки переносов страниц и строк
        var LinesCount = this.protected_GetLinesCount();
        for ( var CurLine = 0; CurLine < LinesCount; CurLine++ )
        {
            var RangesCount = this.protected_GetRangesCount(CurLine);
            for ( var CurRange = 0; CurRange < RangesCount; CurRange++ )
270
            {
271 272
                var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
                var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
273

274 275
                if (StartPos > Pos)
                    StartPos++;
276

277 278 279 280
                if (EndPos > Pos)
                    EndPos++;

                this.protected_FillRange(CurLine, CurRange, StartPos, EndPos);
281 282
            }

283 284
            // Особый случай, когда мы добавляем элемент в самый последний ран
            if ( Pos === this.Content.length - 1 && LinesCount - 1 === CurLine )
285
            {
286
                this.protected_FillRangeEndPos(CurLine, RangesCount - 1, this.protected_GetRangeEndPos(CurLine, RangesCount - 1) + 1);
287 288
            }
        }
289
    }
290

291 292 293 294 295 296 297 298 299 300 301
    // Обновляем позиции в NearestPos
    var NearPosLen = this.NearPosArray.length;
    for ( var Index = 0; Index < NearPosLen; Index++ )
    {
        var HyperNearPos = this.NearPosArray[Index];
        var ContentPos = HyperNearPos.NearPos.ContentPos;
        var Depth      = HyperNearPos.Depth;

        if ( ContentPos.Data[Depth] >= Pos )
            ContentPos.Data[Depth]++;
    }
302

303 304 305
    // Обновляем позиции в поиске
    var SearchMarksCount = this.SearchMarks.length;
    for ( var Index = 0; Index < SearchMarksCount; Index++ )
306
    {
307 308 309 310 311 312 313 314
        var Mark       = this.SearchMarks[Index];
        var ContentPos = ( true === Mark.Start ? Mark.SearchResult.StartPos : Mark.SearchResult.EndPos );
        var Depth      = Mark.Depth;

        if ( ContentPos.Data[Depth] >= Pos )
            ContentPos.Data[Depth]++;
    }
};
315

316 317 318 319 320 321 322 323 324
ParaHyperlink.prototype.Remove_FromContent = function(Pos, Count, UpdatePosition)
{
    // Получим массив удаляемых элементов
    var DeletedItems = this.Content.slice( Pos, Pos + Count );
    History.Add( this, { Type : historyitem_Hyperlink_RemoveItem, Pos : Pos, EndPos : Pos + Count - 1, Items : DeletedItems } );

    this.Content.splice( Pos, Count );

    if ( true === UpdatePosition )
325
    {
326 327 328 329 330
        // Обновим текущую позицию
        if ( this.State.ContentPos > Pos + Count )
            this.State.ContentPos -= Count;
        else if ( this.State.ContentPos > Pos )
            this.State.ContentPos = Pos;
331

332 333
        // Обновим начало и конец селекта
        if ( true === this.State.Selection.Use )
334
        {
335
            if ( this.State.Selection.StartPos <= this.State.Selection.EndPos )
336
            {
337 338 339 340 341 342 343 344 345
                if ( this.State.Selection.StartPos > Pos + Count )
                    this.State.Selection.StartPos -= Count;
                else if ( this.State.Selection.StartPos > Pos )
                    this.State.Selection.StartPos = Pos;

                if ( this.State.Selection.EndPos >= Pos + Count )
                    this.State.Selection.EndPos -= Count;
                else if ( this.State.Selection.EndPos >= Pos )
                    this.State.Selection.EndPos = Math.max( 0, Pos - 1 );
346
            }
347
            else
348
            {
349 350 351 352 353 354 355 356 357
                if ( this.State.Selection.StartPos >= Pos + Count )
                    this.State.Selection.StartPos -= Count;
                else if ( this.State.Selection.StartPos >= Pos )
                    this.State.Selection.StartPos = Math.max( 0, Pos - 1 );

                if ( this.State.Selection.EndPos > Pos + Count )
                    this.State.Selection.EndPos -= Count;
                else if ( this.State.Selection.EndPos > Pos )
                    this.State.Selection.EndPos = Pos;
358 359
            }
        }
360

361 362 363
        // Также передвинем всем метки переносов страниц и строк
        var LinesCount = this.protected_GetLinesCount();
        for ( var CurLine = 0; CurLine < LinesCount; CurLine++ )
364
        {
365 366 367 368 369
            var RangesCount = this.protected_GetRangesCount(CurLine);
            for ( var CurRange = 0; CurRange < RangesCount; CurRange++ )
            {
                var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
                var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
370

371 372 373 374
                if (StartPos > Pos + Count)
                    StartPos -= Count;
                else if (StartPos > Pos)
                    StartPos = Math.max(0 , Pos);
375

376 377 378 379
                if (EndPos >= Pos + Count)
                    EndPos -= Count;
                else if (EndPos >= Pos)
                    EndPos = Math.max(0 , Pos);
380

381 382
                this.protected_FillRange(CurLine, CurRange, StartPos, EndPos);
            }
383
        }
384
    }
385

386 387 388
    // Обновляем позиции в NearestPos
    var NearPosLen = this.NearPosArray.length;
    for ( var Index = 0; Index < NearPosLen; Index++ )
389
    {
390 391 392
        var HyperNearPos = this.NearPosArray[Index];
        var ContentPos = HyperNearPos.NearPos.ContentPos;
        var Depth      = HyperNearPos.Depth;
393

394 395 396 397 398
        if ( ContentPos.Data[Depth] > Pos + Count )
            ContentPos.Data[Depth] -= Count;
        else if ( ContentPos.Data[Depth] > Pos )
            ContentPos.Data[Depth] = Math.max( 0 , Pos );
    }
399

400 401 402 403 404 405 406 407 408 409 410 411 412 413
    // Обновляем позиции в поиске
    var SearchMarksCount = this.SearchMarks.length;
    for ( var Index = 0; Index < SearchMarksCount; Index++ )
    {
        var Mark       = this.SearchMarks[Index];
        var ContentPos = ( true === Mark.Start ? Mark.SearchResult.StartPos : Mark.SearchResult.EndPos );
        var Depth      = Mark.Depth;

        if ( ContentPos.Data[Depth] > Pos + Count )
            ContentPos.Data[Depth] -= Count;
        else if ( ContentPos.Data[Depth] > Pos )
            ContentPos.Data[Depth] = Math.max( 0 , Pos );
    }
};
414

415 416 417 418 419 420 421
ParaHyperlink.prototype.Add = function(Item)
{
    switch (Item.Type)
    {
        case para_Run :
        {
            var CurItem = this.Content[this.State.ContentPos];
422

423
            switch ( CurItem.Type )
424
            {
425
                case para_Run :
426
                {
427
                    var NewRun = CurItem.Split2(CurItem.State.ContentPos);
428

429 430 431 432 433
                    this.Internal_Content_Add( CurPos + 1, Item );
                    this.Internal_Content_Add( CurPos + 2, NewRun );
                    this.State.ContentPos = CurPos + 1;
                    break;
                }
434

435 436 437 438
                default:
                {
                    this.Content[this.State.ContentPos].Add( Item );
                    break;
439 440
                }
            }
441

442
            break;
443
        }
444

445
        default :
446
        {
447 448
            this.Content[this.State.ContentPos].Add( Item );
            break;
449
        }
450 451 452 453 454 455
    }
};

ParaHyperlink.prototype.Remove = function(Direction, bOnAddText)
{
    var Selection = this.State.Selection;
456

457
    if ( true === Selection.Use )
458
    {
459 460
        var StartPos = Selection.StartPos;
        var EndPos   = Selection.EndPos;
461

462 463 464 465 466
        if ( StartPos > EndPos )
        {
            StartPos = Selection.EndPos;
            EndPos   = Selection.StartPos;
        }
467

468 469 470 471 472
        if ( StartPos === EndPos )
        {
            this.Content[StartPos].Remove(Direction, bOnAddText);

            if ( StartPos !== this.Content.length - 1 && true === this.Content[StartPos].Is_Empty() )
473
            {
474
                this.Remove_FromContent( StartPos, 1, true );
475 476
            }
        }
477
        else
478
        {
479
            this.Content[EndPos].Remove(Direction, bOnAddText);
480

481
            if ( EndPos !== this.Content.length - 1 && true === this.Content[EndPos].Is_Empty() )
482
            {
483
                this.Remove_FromContent( EndPos, 1, true );
484 485
            }

486
            for ( var CurPos = EndPos - 1; CurPos > StartPos; CurPos-- )
487
            {
488
                this.Remove_FromContent( CurPos, 1, true );
489 490
            }

491
            this.Content[StartPos].Remove(Direction, bOnAddText);
492

493 494 495
            if ( true === this.Content[StartPos].Is_Empty() )
                this.Remove_FromContent( StartPos, 1, true );
        }
496

497 498 499 500 501 502
        this.Selection_Remove();
        this.State.ContentPos = StartPos;
    }
    else
    {
        var ContentPos = this.State.ContentPos;
503

504 505 506
        if ( true === this.Cursor_Is_Start() || true === this.Cursor_Is_End() )
        {
            this.Select_All();
507 508 509
        }
        else
        {
510
            while ( false === this.Content[ContentPos].Remove( Direction, bOnAddText ) )
511
            {
512 513 514 515
                if ( Direction < 0 )
                    ContentPos--;
                else
                    ContentPos++;
516

517 518
                if ( ContentPos < 0 || ContentPos >= this.Content.length )
                    break;
519

520 521 522 523
                if ( Direction < 0 )
                    this.Content[ContentPos].Cursor_MoveToEndPos(false);
                else
                    this.Content[ContentPos].Cursor_MoveToStartPos();
524

525
            }
526

527 528 529 530 531 532
            if ( ContentPos < 0 || ContentPos >= this.Content.length )
                return false;
            else
            {
                if ( ContentPos !== this.Content.length - 1 && true === this.Content[ContentPos].Is_Empty() )
                    this.Remove_FromContent( ContentPos, 1, true );
533

534
                this.State.ContentPos = ContentPos;
535 536
            }
        }
537
    }
538

539 540
    return true;
};
541

542 543 544
ParaHyperlink.prototype.Get_CurrentParaPos = function()
{
    var CurPos = this.State.ContentPos;
545

546 547
    if ( CurPos >= 0 && CurPos < this.Content.length )
        return this.Content[CurPos].Get_CurrentParaPos();
548

549 550
    return new CParaPos( this.StartRange, this.StartLine, 0, 0 );
};
551

552 553 554
ParaHyperlink.prototype.Apply_TextPr = function(TextPr, IncFontSize, ApplyToAll)
{
    if ( true === ApplyToAll )
555
    {
556 557
        var ContentLen = this.Content.length;
        for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
558
        {
559
            this.Content[CurPos].Apply_TextPr( TextPr, IncFontSize, true );
560
        }
561 562 563 564 565 566
    }
    else
    {
        var Selection = this.State.Selection;

        if ( true === Selection.Use )
567
        {
568 569
            var StartPos = Selection.StartPos;
            var EndPos   = Selection.EndPos;
570

571
            if ( StartPos === EndPos )
572
            {
573
                var NewElements = this.Content[EndPos].Apply_TextPr( TextPr, IncFontSize, false );
574

575
                if ( para_Run === this.Content[EndPos].Type )
576
                {
577
                    var CenterRunPos = this.Internal_ReplaceRun( EndPos, NewElements );
578

579 580
                    if ( StartPos === this.State.ContentPos )
                        this.State.ContentPos = CenterRunPos;
581

582 583 584
                    // Подправим метки селекта
                    Selection.StartPos = CenterRunPos;
                    Selection.EndPos   = CenterRunPos;
585
                }
586
            }
587
            else
588
            {
589 590 591 592 593 594 595 596 597
                var Direction = 1;
                if ( StartPos > EndPos )
                {
                    var Temp = StartPos;
                    StartPos = EndPos;
                    EndPos = Temp;

                    Direction = -1;
                }
598

599
                for ( var CurPos = StartPos + 1; CurPos < EndPos; CurPos++ )
600
                {
601
                    this.Content[CurPos].Apply_TextPr( TextPr, IncFontSize, false );
602
                }
603 604


605 606 607
                var NewElements = this.Content[EndPos].Apply_TextPr( TextPr, IncFontSize, false );
                if ( para_Run === this.Content[EndPos].Type )
                    this.Internal_ReplaceRun( EndPos, NewElements );
608

609 610 611
                var NewElements = this.Content[StartPos].Apply_TextPr( TextPr, IncFontSize, false );
                if ( para_Run === this.Content[StartPos].Type )
                    this.Internal_ReplaceRun( StartPos, NewElements );
612

613 614 615 616 617 618 619 620 621 622 623 624
                // Подправим селект. Заметим, что метки выделения изменяются внутри функции Add_ToContent
                // за счет того, что EndPos - StartPos > 1.
                if ( Selection.StartPos < Selection.EndPos && true === this.Content[Selection.StartPos].Selection_IsEmpty() )
                    Selection.StartPos++;
                else if ( Selection.EndPos < Selection.StartPos && true === this.Content[Selection.EndPos].Selection_IsEmpty() )
                    Selection.EndPos++;

                if ( Selection.StartPos < Selection.EndPos && true === this.Content[Selection.EndPos].Selection_IsEmpty() )
                    Selection.EndPos--;
                else if ( Selection.EndPos < Selection.StartPos && true === this.Content[Selection.StartPos].Selection_IsEmpty() )
                    Selection.StartPos--;
            }
625 626 627
        }
        else
        {
628 629 630
            var Pos = this.State.ContentPos;
            var Element = this.Content[Pos];
            var NewElements = Element.Apply_TextPr( TextPr, IncFontSize, false );
631

632 633 634 635 636 637 638 639
            if ( para_Run === Element.Type )
            {
                var CenterRunPos = this.Internal_ReplaceRun( Pos, NewElements );
                this.State.ContentPos = CenterRunPos;
            }
        }
    }
};
640

641 642 643 644 645 646 647 648 649 650 651 652
ParaHyperlink.prototype.Internal_ReplaceRun = function(Pos, NewRuns)
{
    // По логике, можно удалить Run, стоящий в позиции Pos и добавить все раны, которые не null в массиве NewRuns.
    // Но, согласно работе ParaRun.Apply_TextPr, в массиве всегда идет ровно 3 рана (возможно null). Второй ран
    // всегда не null. Первый не null ран и есть ран, идущий в позиции Pos.

    var LRun = NewRuns[0];
    var CRun = NewRuns[1];
    var RRun = NewRuns[2];

    // CRun - всегда не null
    var CenterRunPos = Pos;
653

654
    if ( null !== LRun )
655
    {
656 657 658 659 660 661 662
        this.Add_ToContent( Pos + 1, CRun, true );
        CenterRunPos = Pos + 1;
    }
    else
    {
        // Если LRun - null, значит CRun - это и есть тот ран который стоит уже в позиции Pos
    }
663

664 665
    if ( null !== RRun )
        this.Add_ToContent( CenterRunPos + 1, RRun, true );
666

667 668 669 670 671 672 673 674 675 676 677
    return CenterRunPos;
};

ParaHyperlink.prototype.Clear_TextPr = function()
{
    var HyperlinkStyle = null;
    if ( undefined !== this.Paragraph && null !== this.Paragraph )
    {
        var Styles = this.Paragraph.Parent.Get_Styles();
        HyperlinkStyle = Styles.Get_Default_Hyperlink();
    }
678

679 680
    var Count = this.Content.length;
    for ( var Index = 0; Index < Count; Index++ )
681
    {
682 683 684 685 686 687 688
        var Item = this.Content[Index];
        Item.Clear_TextPr();

        if ( para_Run === Item.Type && null !== HyperlinkStyle )
            Item.Set_RStyle( HyperlinkStyle );
    }
};
689

690 691 692 693 694
ParaHyperlink.prototype.Check_NearestPos = function(ParaNearPos, Depth)
{
    var HyperNearPos = new CParagraphElementNearPos();
    HyperNearPos.NearPos = ParaNearPos.NearPos;
    HyperNearPos.Depth   = Depth;
695

696 697
    this.NearPosArray.push( HyperNearPos );
    ParaNearPos.Classes.push( this );
698

699 700 701 702 703 704 705 706 707 708
    var CurPos = ParaNearPos.NearPos.ContentPos.Get(Depth);
    this.Content[CurPos].Check_NearestPos( ParaNearPos, Depth + 1 );
};

ParaHyperlink.prototype.Get_DrawingObjectRun = function(Id)
{
    var Run = null;

    var ContentLen = this.Content.length;
    for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
709
    {
710 711 712 713 714
        var Element = this.Content[CurPos];
        Run = Element.Get_DrawingObjectRun( Id );
        if ( null !== Run )
            return Run;
    }
715

716 717 718 719 720 721 722 723 724 725 726
    return Run;
};

ParaHyperlink.prototype.Get_DrawingObjectContentPos = function(Id, ContentPos, Depth)
{
    var ContentLen = this.Content.length;
    for ( var Index = 0; Index < ContentLen; Index++ )
    {
        var Element = this.Content[Index];

        if ( true === Element.Get_DrawingObjectContentPos(Id, ContentPos, Depth + 1) )
727
        {
728 729
            ContentPos.Update2( Index, Depth );
            return true;
730
        }
731
    }
732

733 734
    return false;
};
735

736 737 738 739
ParaHyperlink.prototype.Get_Layout = function(DrawingLayout, UseContentPos, ContentPos, Depth)
{
    var CurLine  = DrawingLayout.Line - this.StartLine;
    var CurRange = ( 0 === CurLine ? DrawingLayout.Range - this.StartRange : DrawingLayout.Range );
740

741 742
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
743

744
    var CurContentPos = ( true === UseContentPos ? ContentPos.Get(Depth) : -1 );
745

746
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
747
    {
748
        this.Content[CurPos].Get_Layout(DrawingLayout, ( CurPos === CurContentPos ? true : false ), ContentPos, Depth + 1 );
749

750
        if (true === DrawingLayout.Layout)
751 752 753
            return;
    }
};
754

755 756 757 758
ParaHyperlink.prototype.Get_NextRunElements = function(RunElements, UseContentPos, Depth)
{
    var CurPos     = ( true === UseContentPos ? RunElements.ContentPos.Get(Depth) : 0 );
    var ContentLen = this.Content.length;
759

760
    this.Content[CurPos].Get_NextRunElements( RunElements, UseContentPos,  Depth + 1 );
761

762 763
    if ( RunElements.Count <= 0 )
        return;
764

765
    CurPos++;
766

767 768 769
    while ( CurPos < ContentLen )
    {
        this.Content[CurPos].Get_NextRunElements( RunElements, false,  Depth + 1 );
770 771

        if ( RunElements.Count <= 0 )
772
            break;
773 774

        CurPos++;
775 776
    }
};
777

778 779 780
ParaHyperlink.prototype.Get_PrevRunElements = function(RunElements, UseContentPos, Depth)
{
    var CurPos = ( true === UseContentPos ? RunElements.ContentPos.Get(Depth) : this.Content.length - 1 );
781

782
    this.Content[CurPos].Get_PrevRunElements( RunElements, UseContentPos,  Depth + 1 );
783

784 785
    if ( RunElements.Count <= 0 )
        return;
786

787
    CurPos--;
788

789 790 791
    while ( CurPos >= 0 )
    {
        this.Content[CurPos].Get_PrevRunElements( RunElements, false,  Depth + 1 );
792 793

        if ( RunElements.Count <= 0 )
794
            break;
795 796

        CurPos--;
797 798
    }
};
799

800 801 802 803 804 805
ParaHyperlink.prototype.Collect_DocumentStatistics = function(ParaStats)
{
    var Count = this.Content.length;
    for (var Index = 0; Index < Count; Index++)
        this.Content[Index].Collect_DocumentStatistics( ParaStats );
};
806

807 808 809 810 811 812
ParaHyperlink.prototype.Create_FontMap = function(Map)
{
    var Count = this.Content.length;
    for (var Index = 0; Index < Count; Index++)
        this.Content[Index].Create_FontMap( Map );
};
813

814 815 816 817 818 819
ParaHyperlink.prototype.Get_AllFontNames = function(AllFonts)
{
    var Count = this.Content.length;
    for (var Index = 0; Index < Count; Index++)
        this.Content[Index].Get_AllFontNames( AllFonts );
};
820

821 822 823
ParaHyperlink.prototype.Clear_TextFormatting = function( DefHyper )
{
    var Count = this.Content.length;
824

825
    for ( var Pos = 0; Pos < Count; Pos++ )
826
    {
827 828
        var Item = this.Content[Pos];
        Item.Clear_TextFormatting( DefHyper );
829

830 831 832 833
        if ( para_Run === Item.Type )
            Item.Set_RStyle( DefHyper );
    }
};
834

835 836 837 838
ParaHyperlink.prototype.Can_AddDropCap = function()
{
    var Count = this.Content.length;
    for ( var Pos = 0; Pos < Count; Pos++ )
839
    {
840
        var TempRes = this.Content[Pos].Can_AddDropCap();
841

842 843 844
        if ( null !== TempRes )
            return TempRes;
    }
845

846 847
    return null;
};
848

849 850 851
ParaHyperlink.prototype.Get_TextForDropCap = function(DropCapText, UseContentPos, ContentPos, Depth)
{
    var EndPos = ( true === UseContentPos ? ContentPos.Get(Depth) : this.Content.length - 1 );
852

853
    for ( var Pos = 0; Pos <= EndPos; Pos++ )
854
    {
855
        this.Content[Pos].Get_TextForDropCap( DropCapText, (true === UseContentPos && Pos === EndPos ? true : false), ContentPos, Depth + 1 );
856

857 858 859 860
        if ( true === DropCapText.Mixed && ( true === DropCapText.Check || DropCapText.Runs.length > 0 ) )
            return;
    }
};
861

862 863 864 865
ParaHyperlink.prototype.Get_StartTabsCount = function(TabsCounter)
{
    var ContentLen = this.Content.length;
    for ( var Pos = 0; Pos < ContentLen; Pos++ )
866
    {
867 868 869 870
        var Element = this.Content[Pos];
        if ( false === Element.Get_StartTabsCount( TabsCounter ) )
            return false;
    }
871

872 873
    return true;
};
874

875 876 877 878 879 880 881 882 883
ParaHyperlink.prototype.Remove_StartTabs = function(TabsCounter)
{
    var ContentLen = this.Content.length;
    for ( var Pos = 0; Pos < ContentLen; Pos++ )
    {
        var Element = this.Content[Pos];
        if ( false === Element.Remove_StartTabs( TabsCounter ) )
            return false;
    }
884

885 886
    return true;
};
887

888 889 890 891 892
ParaHyperlink.prototype.Split = function (ContentPos, Depth)
{
    var NewHyperlink = new ParaHyperlink();
    NewHyperlink.Set_Value( this.Value );
    NewHyperlink.Set_ToolTip( this.ToolTip );
893

894
    var CurPos = ContentPos.Get(Depth);
895

896
    var TextPr = this.Get_TextPr(ContentPos, Depth);
897

898 899 900
    // Разделяем текущий элемент (возвращается правая, отделившаяся часть, если она null, тогда заменяем
    // ее на пустой ран с заданными настройками).
    var NewElement = this.Content[CurPos].Split( ContentPos, Depth + 1 );
901

902
    if ( null === NewElement )
903
    {
904 905 906
        NewElement = new ParaRun();
        NewElement.Set_Pr( TextPr.Copy() );
    }
907

908 909 910 911 912
    // Теперь делим на три части:
    // 1. До элемента с номером CurPos включительно (оставляем эту часть в исходном параграфе)
    // 2. После элемента с номером CurPos (добавляем эту часть в новый параграф)
    // 3. Новый элемент, полученный после разделения элемента с номером CurPos, который мы
    //    добавляем в начало нового параграфа.
913

914 915
    var NewContent = this.Content.slice( CurPos + 1 );
    this.Remove_FromContent( CurPos + 1, this.Content.length - CurPos - 1, false );
916

917 918 919 920
    // Добавляем в новую гиперссылку Right элемент и NewContent
    var Count = NewContent.length;
    for ( var Pos = 0; Pos < Count; Pos++ )
        NewHyperlink.Add_ToContent( Pos, NewContent[Pos], false );
921

922
    NewHyperlink.Add_ToContent( 0, NewElement, false );
923

924 925
    return NewHyperlink;
};
926

927 928 929 930
ParaHyperlink.prototype.Split2 = function(CurPos)
{
    // Создаем новый ран
    var NewRun = new ParaRun(this.Paragraph);
931

932 933
    // Копируем настройки
    NewRun.Set_Pr( this.Pr.Copy() );
934

935 936
    // TODO: Как только избавимся от para_End переделать тут
    // Проверим, если наш ран содержит para_End, тогда мы должны para_End переметить в правый ран
937

938 939 940 941 942 943 944 945
    var CheckEndPos = -1;
    var CheckEndPos2 = Math.min( CurPos, this.Content.length );
    for ( var Pos = 0; Pos < CheckEndPos2; Pos++ )
    {
        if ( para_End === this.Content[Pos].Type )
        {
            CheckEndPos = Pos;
            break;
946
        }
947
    }
948

949 950
    if ( -1 !== CheckEndPos )
        CurPos = CheckEndPos;
951

952 953 954
    // Разделяем содержимое по ранам
    NewRun.Concat_ToContent( this.Content.slice(CurPos) );
    this.Remove_FromContent( CurPos, this.Content.length - CurPos, true );
955

956 957 958
    // Если были точки орфографии, тогда переместим их в новый ран
    var SpellingMarksCount = this.SpellingMarks.length;
    for ( var Index = 0; Index < SpellingMarksCount; Index++ )
959
    {
960 961
        var Mark    = this.SpellingMarks[Index];
        var MarkPos = ( true === Mark.Start ? Mark.Element.StartPos.Get(Mark.Depth) : Mark.Element.EndPos.Get(Mark.Depth) );
962

963
        if ( MarkPos >= CurPos )
964
        {
965 966
            var MarkElement = Mark.Element;
            if ( true === Mark.Start )
967
            {
968 969
                MarkElement.ClassesS[Mark.Depth]       = NewRun;
                MarkElement.StartPos.Data[Mark.Depth] -= CurPos;
970 971 972
            }
            else
            {
973 974
                MarkElement.ClassesE[Mark.Depth]     = NewRun;
                MarkElement.EndPos.Data[Mark.Depth] -= CurPos;
975 976
            }

977
            NewRun.SpellingMarks.push( Mark );
978

979 980 981
            this.SpellingMarks.splice( Index, 1 );
            SpellingMarksCount--;
            Index--;
982
        }
983
    }
984

985 986 987 988 989 990 991 992 993 994
    return NewRun;
};
//-----------------------------------------------------------------------------------
// Функции пересчета
//-----------------------------------------------------------------------------------
ParaHyperlink.prototype.Recalculate_Range = function(PRS, ParaPr, Depth)
{
    if ( this.Paragraph !== PRS.Paragraph )
    {
        this.Paragraph = PRS.Paragraph;
995
        this.protected_UpdateSpellChecking();
996
    }
997

998 999
    var CurLine  = PRS.Line - this.StartLine;
    var CurRange = ( 0 === CurLine ? PRS.Range - this.StartRange : PRS.Range );
1000

1001 1002 1003
    // Добавляем информацию о новом отрезке
    var RangeStartPos = this.protected_AddRange(CurLine, CurRange);
    var RangeEndPos   = 0;
1004

1005 1006 1007 1008 1009
    var ContentLen = this.Content.length;
    var Pos = RangeStartPos;
    for ( ; Pos < ContentLen; Pos++ )
    {
        var Item = this.Content[Pos];
1010

1011
        if ( ( 0 === Pos && 0 === CurLine && 0 === CurRange ) || Pos !== RangeStartPos )
1012
        {
1013
            Item.Recalculate_Reset( PRS.Range, PRS.Line );
1014 1015
        }

1016 1017
        PRS.Update_CurPos( Pos, Depth );
        Item.Recalculate_Range( PRS, ParaPr, Depth + 1 );
1018

1019 1020 1021 1022
        if ( true === PRS.NewRange )
        {
            RangeEndPos = Pos;
            break;
1023
        }
1024
    }
1025

1026
    if ( Pos >= ContentLen )
1027
    {
1028 1029
        RangeEndPos = Pos - 1;
    }
1030

1031 1032
    this.protected_FillRange(CurLine, CurRange, RangeStartPos, RangeEndPos);
};
1033

1034 1035 1036 1037 1038
ParaHyperlink.prototype.Recalculate_Set_RangeEndPos = function(PRS, PRP, Depth)
{
    var CurLine  = PRS.Line - this.StartLine;
    var CurRange = ( 0 === CurLine ? PRS.Range - this.StartRange : PRS.Range );
    var CurPos   = PRP.Get(Depth);
1039

1040
    this.protected_FillRangeEndPos(CurLine, CurRange, CurPos);
1041

1042 1043
    this.Content[CurPos].Recalculate_Set_RangeEndPos( PRS, PRP, Depth + 1 );
};
1044

1045 1046 1047 1048 1049 1050 1051
ParaHyperlink.prototype.Recalculate_Range_Width = function(PRSC, _CurLine, _CurRange)
{
    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );

    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1052

1053
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1054
    {
1055 1056 1057
        this.Content[CurPos].Recalculate_Range_Width( PRSC, _CurLine, _CurRange );
    }
};
1058

1059 1060 1061 1062
ParaHyperlink.prototype.Recalculate_Range_Spaces = function(PRSA, _CurLine, _CurRange, _CurPage)
{
    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1063

1064 1065
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1066

1067
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1068
    {
1069 1070 1071
        this.Content[CurPos].Recalculate_Range_Spaces( PRSA, _CurLine, _CurRange, _CurPage );
    }
};
1072

1073 1074 1075 1076
ParaHyperlink.prototype.Recalculate_PageEndInfo = function(PRSI, _CurLine, _CurRange)
{
    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1077

1078 1079
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1080

1081
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1082
    {
1083 1084 1085
        this.Content[CurPos].Recalculate_PageEndInfo( PRSI, _CurLine, _CurRange );
    }
};
1086

1087 1088 1089 1090 1091 1092 1093
ParaHyperlink.prototype.Save_RecalculateObject = function(Copy)
{
    var RecalcObj = new CRunRecalculateObject(this.StartLine, this.StartRange);
    RecalcObj.Save_Lines( this, Copy );
    RecalcObj.Save_Content( this, Copy );
    return RecalcObj;
};
1094

1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106
ParaHyperlink.prototype.Load_RecalculateObject = function(RecalcObj)
{
    RecalcObj.Load_Lines( this );
    RecalcObj.Load_Content( this );
};

ParaHyperlink.prototype.Prepare_RecalculateObject = function()
{
    this.protected_ClearLines();

    var Count = this.Content.length;
    for ( var Index = 0; Index < Count; Index++ )
1107
    {
1108 1109 1110
        this.Content[Index].Prepare_RecalculateObject();
    }
};
1111

1112 1113 1114 1115 1116 1117 1118
ParaHyperlink.prototype.Is_EmptyRange = function(_CurLine, _CurRange)
{
    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );

    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1119

1120
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1121
    {
1122 1123 1124
        if ( false === this.Content[CurPos].Is_EmptyRange(_CurLine, _CurRange) )
            return false;
    }
1125

1126 1127
    return true;
};
1128

1129 1130 1131 1132
ParaHyperlink.prototype.Check_Range_OnlyMath = function(Checker, _CurRange, _CurLine)
{
    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1133

1134 1135
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1136

1137
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1138
    {
1139
        this.Content[CurPos].Check_Range_OnlyMath(Checker, _CurRange, _CurLine);
1140

1141 1142 1143 1144
        if (false === Checker.Result)
            break;
    }
};
1145

1146 1147 1148 1149
ParaHyperlink.prototype.Check_MathPara = function(Checker)
{
    var Count = this.Content.length;
    if ( Checker.Direction > 0 )
1150
    {
1151
        for ( var CurPos = 0; CurPos < Count; CurPos++ )
1152
        {
1153
            if ( this.Content[CurPos].Check_MathPara )
1154
            {
1155
                this.Content[CurPos].Check_MathPara( MathParaChecker );
1156

1157 1158 1159
                if ( false !== MathParaChecker.Found )
                    break;
            }
1160
        }
1161 1162 1163 1164
    }
    else
    {
        for ( var CurPos = Count - 1; CurPos >= 0; CurPos-- )
1165
        {
1166
            if ( this.Content[CurPos].Check_MathPara )
1167
            {
1168
                this.Content[CurPos].Check_MathPara( MathParaChecker );
1169

1170 1171
                if ( false !== MathParaChecker.Found )
                    break;
1172 1173
            }
        }
1174 1175
    }
};
1176

1177 1178 1179 1180
ParaHyperlink.prototype.Check_PageBreak = function()
{
    var Count = this.Content.length;
    for (var Pos = 0; Pos < Count; Pos++)
1181
    {
1182 1183 1184
        if (true === this.Content[Pos].Check_PageBreak())
            return true;
    }
1185

1186 1187
    return false;
};
1188

1189 1190 1191 1192
ParaHyperlink.prototype.Check_BreakPageEnd = function(PBChecker)
{
    var ContentLen = this.Content.length;
    for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
1193
    {
1194
        var Element = this.Content[CurPos];
1195

1196 1197 1198
        if ( true !== Element.Check_BreakPageEnd(PBChecker) )
            return false;
    }
1199

1200 1201
    return true;
};
1202

1203 1204 1205
ParaHyperlink.prototype.Get_ParaPosByContentPos = function(ContentPos, Depth)
{
    var Pos = ContentPos.Get(Depth);
1206

1207 1208
    return this.Content[Pos].Get_ParaPosByContentPos( ContentPos, Depth + 1 );
};
1209

1210 1211 1212 1213 1214
ParaHyperlink.prototype.Recalculate_CurPos = function(_X, Y, CurrentRun, _CurRange, _CurLine, _CurPage, UpdateCurPos, UpdateTarget, ReturnTarget)
{
    var CurLine  = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
    var X = _X;
1215

1216 1217
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1218

1219
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1220
    {
1221 1222
        var Item = this.Content[CurPos];
        var Res = Item.Recalculate_CurPos( X, Y, (true === CurrentRun && CurPos === this.State.ContentPos ? true : false), _CurRange, _CurLine, _CurPage, UpdateCurPos, UpdateTarget, ReturnTarget );
1223

1224 1225 1226 1227 1228
        if ( true === CurrentRun && CurPos === this.State.ContentPos )
            return Res;
        else
            X = Res.X;
    }
1229

1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242
    return { X : X };
};

ParaHyperlink.prototype.Refresh_RecalcData = function(Data)
{
    if (undefined !== this.Paragraph && null !== this.Paragraph)
        this.Paragraph.Refresh_RecalcData2(0);
};

ParaHyperlink.prototype.Recalculate_MinMaxContentWidth = function(MinMax)
{
    var Count = this.Content.length;
    for ( var Pos = 0; Pos < Count; Pos++ )
1243
    {
1244 1245 1246
        this.Content[Pos].Recalculate_MinMaxContentWidth(MinMax);
    }
};
1247

1248 1249 1250 1251
ParaHyperlink.prototype.Get_Range_VisibleWidth = function(RangeW, _CurLine, _CurRange)
{
    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1252

1253 1254
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1255

1256
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1257
    {
1258 1259 1260 1261 1262 1263 1264 1265
        this.Content[CurPos].Get_Range_VisibleWidth(RangeW, _CurLine, _CurRange);
    }
};

ParaHyperlink.prototype.Shift_Range = function(Dx, Dy, _CurLine, _CurRange)
{
    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1266

1267 1268
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1269

1270 1271 1272 1273 1274
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
    {
        this.Content[CurPos].Shift_Range(Dx, Dy, _CurLine, _CurRange);
    }
};
1275 1276 1277
//-----------------------------------------------------------------------------------
// Функции отрисовки
//-----------------------------------------------------------------------------------
1278 1279 1280 1281
ParaHyperlink.prototype.Draw_HighLights = function(PDSH)
{
    var CurLine  = PDSH.Line - this.StartLine;
    var CurRange = ( 0 === CurLine ? PDSH.Range - this.StartRange : PDSH.Range );
1282

1283 1284
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1285

1286 1287 1288 1289 1290
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
    {
        this.Content[CurPos].Draw_HighLights( PDSH );
    }
};
1291

1292 1293 1294
ParaHyperlink.prototype.Draw_Elements = function(PDSE)
{
    PDSE.VisitedHyperlink = this.Visited;
1295

1296 1297
    var CurLine  = PDSE.Line - this.StartLine;
    var CurRange = ( 0 === CurLine ? PDSE.Range - this.StartRange : PDSE.Range );
1298

1299 1300
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1301

1302 1303 1304 1305
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
    {
        this.Content[CurPos].Draw_Elements( PDSE );
    }
1306

1307 1308
    PDSE.VisitedHyperlink = false;
};
1309

1310 1311 1312
ParaHyperlink.prototype.Draw_Lines = function(PDSL)
{
    PDSL.VisitedHyperlink = this.Visited;
1313

1314 1315
    var CurLine  = PDSL.Line - this.StartLine;
    var CurRange = ( 0 === CurLine ? PDSL.Range - this.StartRange : PDSL.Range );
1316

1317 1318
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1319

1320 1321 1322 1323
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
    {
        this.Content[CurPos].Draw_Lines( PDSL );
    }
1324

1325 1326
    PDSL.VisitedHyperlink = false;
};
1327 1328 1329
//-----------------------------------------------------------------------------------
// Функции для работы с курсором
//-----------------------------------------------------------------------------------
1330 1331 1332 1333
ParaHyperlink.prototype.Is_CursorPlaceable = function()
{
    return true;
};
1334

1335 1336 1337 1338 1339 1340
ParaHyperlink.prototype.Cursor_Is_Start = function()
{
    var ContentLen = this.Content.length;
    var CurPos = 0;

    while ( CurPos < this.State.ContentPos && CurPos < this.Content.length - 1 )
1341
    {
1342 1343 1344 1345 1346
        if ( true === this.Content[CurPos].Is_Empty() )
            CurPos++;
        else
            return false;
    }
1347

1348 1349
    return this.Content[CurPos].Cursor_Is_Start();
};
1350

1351 1352 1353 1354
ParaHyperlink.prototype.Cursor_Is_NeededCorrectPos = function()
{
    return false;
};
1355

1356 1357 1358
ParaHyperlink.prototype.Cursor_Is_End = function()
{
    var CurPos = this.Content.length - 1;
1359

1360
    while ( CurPos > this.State.ContentPos && CurPos > 0 )
1361
    {
1362 1363 1364 1365 1366
        if ( true === this.Content[CurPos].Is_Empty() )
            CurPos--;
        else
            return false;
    }
1367

1368 1369 1370 1371 1372 1373
    return this.Content[CurPos].Cursor_Is_End();
};

ParaHyperlink.prototype.Cursor_MoveToStartPos = function()
{
    this.State.ContentPos = 0;
1374

1375 1376 1377 1378 1379 1380 1381 1382 1383
    if ( this.Content.length > 0 )
    {
        this.Content[0].Cursor_MoveToStartPos();
    }
};

ParaHyperlink.prototype.Cursor_MoveToEndPos = function(SelectFromEnd)
{
    var ContentLen = this.Content.length;
1384

1385
    if ( ContentLen > 0 )
1386
    {
1387 1388 1389 1390
        this.State.ContentPos = ContentLen - 1;
        this.Content[ContentLen - 1].Cursor_MoveToEndPos( SelectFromEnd );
    }
};
1391

1392 1393 1394 1395 1396 1397 1398 1399 1400
ParaHyperlink.prototype.Get_ParaContentPosByXY = function(SearchPos, Depth, _CurLine, _CurRange, StepEnd)
{
    var Result = false;

    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );

    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1401

1402
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1403
    {
1404 1405 1406 1407
        var Item = this.Content[CurPos];

        if ( false === SearchPos.InText )
            SearchPos.InTextPos.Update2( CurPos, Depth );
1408

1409
        if ( true === Item.Get_ParaContentPosByXY( SearchPos, Depth + 1, _CurLine, _CurRange, StepEnd ) )
1410
        {
1411 1412
            SearchPos.Pos.Update2( CurPos, Depth );
            Result = true;
1413
        }
1414
    }
1415

1416 1417
    return Result;
};
1418

1419 1420 1421 1422
ParaHyperlink.prototype.Get_ParaContentPos = function(bSelection, bStart, ContentPos)
{
    var Pos = ( true === bSelection ? ( true === bStart ? this.State.Selection.StartPos : this.State.Selection.EndPos ) : this.State.ContentPos );
    ContentPos.Add( Pos );
1423

1424 1425
    this.Content[Pos].Get_ParaContentPos( bSelection, bStart, ContentPos );
};
1426

1427 1428 1429
ParaHyperlink.prototype.Set_ParaContentPos = function(ContentPos, Depth)
{
    var Pos = ContentPos.Get(Depth);
1430

1431 1432
    if ( Pos >= this.Content.length )
        Pos = this.Content.length - 1;
1433

1434 1435
    if ( Pos < 0 )
        Pos = 0;
1436

1437
    this.State.ContentPos = Pos;
1438

1439 1440
    this.Content[Pos].Set_ParaContentPos( ContentPos, Depth + 1 );
};
1441

1442 1443 1444 1445
ParaHyperlink.prototype.Get_PosByElement = function(Class, ContentPos, Depth, UseRange, Range, Line)
{
    if ( this === Class )
        return true;
1446

1447
    var ContentPos = new CParagraphContentPos();
1448

1449 1450
    var StartPos = 0;
    var EndPos   = this.Content.length - 1;
1451

1452 1453 1454 1455
    if ( true === UseRange )
    {
        var CurLine  = Line - this.StartLine;
        var CurRange = ( 0 === CurLine ? Range - this.StartRange : Range );
1456

1457 1458 1459 1460 1461 1462
        if (CurLine >= 0 && CurLine < this.protected_GetLinesCount() && CurRange >= 0 && CurRange < this.protected_GetRangesCount(CurLine))
        {
            StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
            EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
        }
    }
1463

1464
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1465
    {
1466
        var Element = this.Content[CurPos];
1467

1468
        ContentPos.Update( CurPos, Depth );
1469

1470 1471 1472
        if ( true === Element.Get_PosByElement(Class, ContentPos, Depth + 1, true, CurRange, CurLine) )
            return true;
    }
1473

1474 1475
    return false;
};
1476

1477 1478 1479 1480 1481 1482 1483 1484 1485
ParaHyperlink.prototype.Get_ElementByPos = function(ContentPos, Depth)
{
    if (Depth + 1 >= ContentPos.Depth)
        return this;

    var CurPos = ContentPos.Get(Depth);
    return this.Content[CurPos].Get_ElementByPos(ContentPos, Depth + 1);
};

1486 1487 1488 1489 1490 1491
ParaHyperlink.prototype.Get_PosByDrawing = function(Id, ContentPos, Depth)
{
    var Count = this.Content.length;
    for ( var CurPos = 0; CurPos < Count; CurPos++ )
    {
        var Element = this.Content[CurPos];
1492

1493
        ContentPos.Update( CurPos, Depth );
1494

1495 1496 1497
        if ( true === Element.Get_PosByDrawing(Id, ContentPos, Depth + 1) )
            return true;
    }
1498

1499 1500
    return false;
};
1501

1502 1503 1504 1505 1506
ParaHyperlink.prototype.Get_RunElementByPos = function(ContentPos, Depth)
{
    if ( undefined !== ContentPos )
    {
        var Pos = ContentPos.Get(Depth);
1507

1508 1509 1510
        return this.Content[Pos].Get_RunElementByPos( ContentPos, Depth + 1 );
    }
    else
1511 1512
    {
        var Count = this.Content.length;
1513 1514
        if ( Count <= 0 )
            return null;
1515

1516 1517
        var Pos = 0;
        var Element = this.Content[Pos];
1518

1519 1520
        while ( null === Element && Pos < Count - 1 )
            Element = this.Content[++Pos];
1521

1522 1523 1524 1525 1526 1527 1528 1529
        return Element;
    }
};

ParaHyperlink.prototype.Get_LastRunInRange = function(_CurLine, _CurRange)
{
    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1530

1531
    if (CurLine < this.protected_GetLinesCount() && CurRange < this.protected_GetRangesCount(CurLine))
1532
    {
1533 1534 1535 1536
        var LastItem = this.Content[this.protected_GetRangeEndPos(CurLine, CurRange)];
        if ( undefined !== LastItem )
            return LastItem.Get_LastRunInRange(_CurLine, _CurRange);
    }
1537

1538 1539
    return null;
};
1540

1541 1542 1543 1544 1545 1546
ParaHyperlink.prototype.Get_LeftPos = function(SearchPos, ContentPos, Depth, UseContentPos)
{
    var CurPos = ( true === UseContentPos ? ContentPos.Get(Depth) : this.Content.length - 1 );

    this.Content[CurPos].Get_LeftPos(SearchPos, ContentPos, Depth + 1, UseContentPos);
    SearchPos.Pos.Update( CurPos, Depth );
1547

1548 1549 1550 1551 1552 1553 1554 1555
    if ( true === SearchPos.Found )
        return true;

    CurPos--;

    while ( CurPos >= 0 )
    {
        this.Content[CurPos].Get_LeftPos(SearchPos, ContentPos, Depth + 1, false);
1556 1557 1558 1559 1560 1561
        SearchPos.Pos.Update( CurPos, Depth );

        if ( true === SearchPos.Found )
            return true;

        CurPos--;
1562
    }
1563

1564 1565
    return false;
};
1566

1567 1568 1569
ParaHyperlink.prototype.Get_RightPos = function(SearchPos, ContentPos, Depth, UseContentPos, StepEnd)
{
    var CurPos = ( true === UseContentPos ? ContentPos.Get(Depth) : 0 );
1570

1571 1572
    this.Content[CurPos].Get_RightPos(SearchPos, ContentPos, Depth + 1, UseContentPos, StepEnd);
    SearchPos.Pos.Update( CurPos, Depth );
1573

1574 1575
    if ( true === SearchPos.Found )
        return true;
1576

1577
    CurPos++;
1578

1579 1580 1581 1582
    var Count = this.Content.length;
    while ( CurPos < this.Content.length )
    {
        this.Content[CurPos].Get_RightPos(SearchPos, ContentPos, Depth + 1, false, StepEnd);
1583 1584 1585 1586 1587 1588
        SearchPos.Pos.Update( CurPos, Depth );

        if ( true === SearchPos.Found )
            return true;

        CurPos++;
1589
    }
1590

1591 1592
    return false;
};
1593

1594 1595 1596
ParaHyperlink.prototype.Get_WordStartPos = function(SearchPos, ContentPos, Depth, UseContentPos)
{
    var CurPos = ( true === UseContentPos ? ContentPos.Get(Depth) : this.Content.length - 1 );
1597

1598
    this.Content[CurPos].Get_WordStartPos(SearchPos, ContentPos, Depth + 1, UseContentPos);
1599

1600 1601
    if ( true === SearchPos.UpdatePos )
        SearchPos.Pos.Update( CurPos, Depth );
1602

1603 1604
    if ( true === SearchPos.Found )
        return;
1605

1606 1607 1608 1609 1610
    CurPos--;

    var Count = this.Content.length;
    while ( CurPos >= 0 )
    {
1611 1612
        var OldUpdatePos = SearchPos.UpdatePos;

1613
        this.Content[CurPos].Get_WordStartPos(SearchPos, ContentPos, Depth + 1, false);
1614

1615
        if (true === SearchPos.UpdatePos)
1616
            SearchPos.Pos.Update( CurPos, Depth );
1617 1618
        else
            SearchPos.UpdatePos = OldUpdatePos;
1619 1620 1621 1622 1623

        if ( true === SearchPos.Found )
            return;

        CurPos--;
1624 1625
    }
};
1626

1627 1628 1629
ParaHyperlink.prototype.Get_WordEndPos = function(SearchPos, ContentPos, Depth, UseContentPos, StepEnd)
{
    var CurPos = ( true === UseContentPos ? ContentPos.Get(Depth) : 0 );
1630

1631
    this.Content[CurPos].Get_WordEndPos(SearchPos, ContentPos, Depth + 1, UseContentPos, StepEnd);
1632

1633 1634
    if ( true === SearchPos.UpdatePos )
        SearchPos.Pos.Update( CurPos, Depth );
1635

1636 1637
    if ( true === SearchPos.Found )
        return;
1638

1639
    CurPos++;
1640

1641 1642 1643
    var Count = this.Content.length;
    while ( CurPos < Count )
    {
1644 1645
        var OldUpdatePos = SearchPos.UpdatePos;

1646
        this.Content[CurPos].Get_WordEndPos(SearchPos, ContentPos, Depth + 1, false, StepEnd);
1647

1648
        if (true === SearchPos.UpdatePos)
1649
            SearchPos.Pos.Update( CurPos, Depth );
1650 1651
        else
            SearchPos.UpdatePos = OldUpdatePos;
1652 1653 1654 1655 1656

        if ( true === SearchPos.Found )
            return;

        CurPos++;
1657 1658
    }
};
1659

1660 1661 1662 1663
ParaHyperlink.prototype.Get_EndRangePos = function(_CurLine, _CurRange, SearchPos, Depth)
{
    var CurLine  = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1664

1665
    var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
1666

1667 1668
    if ( EndPos >= this.Content.length || EndPos < 0 )
        return false;
1669

1670
    var Result = this.Content[EndPos].Get_EndRangePos( _CurLine, _CurRange, SearchPos, Depth + 1 );
1671

1672 1673
    if ( true === Result )
        SearchPos.Pos.Update( EndPos, Depth );
1674

1675
    return Result;
1676

1677
};
1678

1679 1680 1681 1682
ParaHyperlink.prototype.Get_StartRangePos = function(_CurLine, _CurRange, SearchPos, Depth)
{
    var CurLine  = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1683

1684
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
1685

1686 1687
    if ( StartPos >= this.Content.length || StartPos < 0 )
        return false;
1688

1689
    var Result = this.Content[StartPos].Get_StartRangePos( _CurLine, _CurRange, SearchPos, Depth + 1 );
1690

1691 1692
    if ( true === Result )
        SearchPos.Pos.Update( StartPos, Depth );
1693

1694 1695
    return Result;
};
1696

1697 1698 1699 1700
ParaHyperlink.prototype.Get_StartRangePos2 = function(_CurLine, _CurRange, ContentPos, Depth)
{
    var CurLine  = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1701

1702
    var Pos = this.protected_GetRangeStartPos(CurLine, CurRange);
1703

1704
    ContentPos.Update( Pos, Depth );
1705

1706 1707
    this.Content[Pos].Get_StartRangePos2( _CurLine, _CurRange, ContentPos, Depth + 1 );
};
1708

1709 1710 1711
ParaHyperlink.prototype.Get_StartPos = function(ContentPos, Depth)
{
    if ( this.Content.length > 0 )
1712
    {
1713
        ContentPos.Update( 0, Depth );
1714

1715 1716 1717
        this.Content[0].Get_StartPos( ContentPos, Depth + 1 );
    }
};
1718

1719 1720 1721 1722
ParaHyperlink.prototype.Get_EndPos = function(BehindEnd, ContentPos, Depth)
{
    var ContentLen = this.Content.length;
    if ( ContentLen > 0 )
1723
    {
1724
        ContentPos.Update( ContentLen - 1, Depth );
1725

1726 1727 1728
        this.Content[ContentLen - 1].Get_EndPos( BehindEnd, ContentPos, Depth + 1 );
    }
};
1729 1730 1731
//-----------------------------------------------------------------------------------
// Функции для работы с селектом
//-----------------------------------------------------------------------------------
1732 1733
ParaHyperlink.prototype.Set_SelectionContentPos = function(StartContentPos, EndContentPos, Depth, StartFlag, EndFlag)
{
1734
    var Selection = this.Selection;
1735

1736 1737
    var OldStartPos = Selection.StartPos;
    var OldEndPos   = Selection.EndPos;
1738

1739
    if ( OldStartPos > OldEndPos )
1740
    {
1741 1742 1743
        OldStartPos = Selection.EndPos;
        OldEndPos   = Selection.StartPos;
    }
1744

1745 1746
    var StartPos = 0;
    switch (StartFlag)
1747
    {
1748 1749 1750 1751
        case  1: StartPos = 0; break;
        case -1: StartPos = this.Content.length - 1; break;
        case  0: StartPos = StartContentPos.Get(Depth); break;
    }
1752

1753 1754
    var EndPos = 0;
    switch (EndFlag)
1755
    {
1756 1757 1758 1759
        case  1: EndPos = 0; break;
        case -1: EndPos = this.Content.length - 1; break;
        case  0: EndPos = EndContentPos.Get(Depth); break;
    }
1760

1761 1762 1763 1764 1765
    // Удалим отметки о старом селекте
    if ( OldStartPos < StartPos && OldStartPos < EndPos )
    {
        var TempLimit = Math.min( StartPos, EndPos );
        for ( var CurPos = OldStartPos; CurPos < TempLimit; CurPos++ )
1766
        {
1767 1768 1769
            this.Content[CurPos].Selection_Remove();
        }
    }
1770

1771 1772 1773 1774 1775 1776
    if ( OldEndPos > StartPos && OldEndPos > EndPos )
    {
        var TempLimit = Math.max( StartPos, EndPos );
        for ( var CurPos = TempLimit + 1; CurPos <= OldEndPos; CurPos++ )
        {
            this.Content[CurPos].Selection_Remove();
1777
        }
1778
    }
1779

1780
    // Выставим метки нового селекта
1781

1782 1783 1784
    Selection.Use      = true;
    Selection.StartPos = StartPos;
    Selection.EndPos   = EndPos;
1785

1786 1787 1788 1789
    if ( StartPos != EndPos )
    {
        this.Content[StartPos].Set_SelectionContentPos( StartContentPos, null, Depth + 1, StartFlag, StartPos > EndPos ? 1 : -1 );
        this.Content[EndPos].Set_SelectionContentPos( null, EndContentPos, Depth + 1, StartPos > EndPos ? -1 : 1, EndFlag );
1790

1791 1792 1793
        var _StartPos = StartPos;
        var _EndPos   = EndPos;
        var Direction = 1;
1794

1795
        if ( _StartPos > _EndPos )
1796
        {
1797 1798 1799
            _StartPos = EndPos;
            _EndPos   = StartPos;
            Direction = -1;
1800 1801
        }

1802
        for ( var CurPos = _StartPos + 1; CurPos < _EndPos; CurPos++ )
1803 1804 1805
        {
            this.Content[CurPos].Select_All( Direction );
        }
1806 1807
    }
    else
1808
    {
1809 1810 1811
        this.Content[StartPos].Set_SelectionContentPos( StartContentPos, EndContentPos, Depth + 1, StartFlag, EndFlag );
    }
};
1812

1813 1814 1815 1816
ParaHyperlink.prototype.Selection_IsUse = function()
{
    return this.State.Selection.Use;
};
1817

1818 1819 1820 1821 1822 1823
ParaHyperlink.prototype.Selection_Stop = function()
{
};

ParaHyperlink.prototype.Selection_Remove = function()
{
1824
    var Selection = this.Selection;
1825

1826
    if ( true === Selection.Use )
1827
    {
1828 1829
        var StartPos = Selection.StartPos;
        var EndPos   = Selection.EndPos;
1830 1831 1832

        if ( StartPos > EndPos )
        {
1833 1834
            StartPos = Selection.EndPos;
            EndPos   = Selection.StartPos;
1835 1836
        }

1837 1838 1839
        StartPos = Math.max( 0, StartPos );
        EndPos   = Math.min( this.Content.length - 1, EndPos );

1840 1841
        for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
        {
1842
            this.Content[CurPos].Selection_Remove();
1843
        }
1844
    }
1845

1846 1847 1848 1849
    Selection.Use      = false;
    Selection.StartPos = 0;
    Selection.EndPos   = 0;
};
1850

1851 1852 1853
ParaHyperlink.prototype.Select_All = function(Direction)
{
    var ContentLen = this.Content.length;
1854

1855
    var Selection = this.Selection;
1856 1857

    Selection.Use = true;
1858

1859
    if ( -1 === Direction )
1860
    {
1861
        Selection.StartPos = ContentLen - 1;
1862 1863 1864 1865 1866
        Selection.EndPos   = 0;
    }
    else
    {
        Selection.StartPos = 0;
1867
        Selection.EndPos   = ContentLen - 1;
1868
    }
1869

1870
    for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
1871 1872 1873 1874
    {
        this.Content[CurPos].Select_All( Direction );
    }
};
1875

1876 1877 1878 1879
ParaHyperlink.prototype.Selection_DrawRange = function(_CurLine, _CurRange, SelectionDraw)
{
    var CurLine = _CurLine - this.StartLine;
    var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
1880

1881 1882
    var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
    var EndPos   = this.protected_GetRangeEndPos(CurLine, CurRange);
1883

1884 1885 1886 1887 1888
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
    {
        this.Content[CurPos].Selection_DrawRange( _CurLine, _CurRange, SelectionDraw );
    }
};
1889

1890 1891 1892 1893
ParaHyperlink.prototype.Selection_IsEmpty = function(CheckEnd)
{
    var StartPos = this.State.Selection.StartPos;
    var EndPos   = this.State.Selection.EndPos;
1894

1895 1896 1897 1898 1899
    if ( StartPos > EndPos )
    {
        StartPos = this.State.Selection.EndPos;
        EndPos   = this.State.Selection.StartPos;
    }
1900

1901
    for ( var CurPos = StartPos; CurPos <= EndPos; CurPos++ )
1902
    {
1903 1904 1905
        if ( false === this.Content[CurPos].Selection_IsEmpty(CheckEnd) )
            return false;
    }
1906

1907 1908
    return true;
};
1909

1910 1911 1912
ParaHyperlink.prototype.Selection_CheckParaEnd = function()
{
    // В гиперссылку не должен попадать ParaEnd
1913

1914 1915
    return false;
};
1916

1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928
ParaHyperlink.prototype.Selection_CheckParaContentPos = function(ContentPos, Depth, bStart, bEnd)
{
    var CurPos = ContentPos.Get(Depth);

    if (this.Selection.StartPos <= CurPos && CurPos <= this.Selection.EndPos)
        return this.Content[CurPos].Selection_CheckParaContentPos(ContentPos, Depth + 1, bStart && this.Selection.StartPos === CurPos, bEnd && CurPos === this.Selection.EndPos);
    else if (this.Selection.EndPos <= CurPos && CurPos <= this.Selection.StartPos)
        return this.Content[CurPos].Selection_CheckParaContentPos(ContentPos, Depth + 1, bStart && this.Selection.EndPos === CurPos, bEnd && CurPos === this.Selection.StartPos);

    return false;
};

1929 1930 1931
ParaHyperlink.prototype.Is_SelectedAll = function(Props)
{
    var Selection = this.State.Selection;
1932

1933 1934 1935 1936 1937 1938 1939
    if ( false === Selection.Use && true !== this.Is_Empty( Props ) )
        return false;

    var StartPos = Selection.StartPos;
    var EndPos   = Selection.EndPos;

    if ( EndPos < StartPos )
1940
    {
1941 1942 1943
        StartPos = Selection.EndPos;
        EndPos   = Selection.StartPos;
    }
1944

1945
    for ( var Pos = 0; Pos <= StartPos; Pos++ )
1946
    {
1947 1948 1949
        if ( false === this.Content[Pos].Is_SelectedAll( Props ) )
            return false;
    }
1950

1951 1952
    var Count = this.Content.length;
    for ( var Pos = EndPos; Pos < Count; Pos++ )
1953
    {
1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964
        if ( false === this.Content[Pos].Is_SelectedAll( Props ) )
            return false;
    }

    return true;
};

ParaHyperlink.prototype.Selection_CorrectLeftPos = function(Direction)
{
    if ( false === this.Selection.Use || true === this.Is_Empty( { SkipAnchor : true } ) )
        return true;
1965

1966 1967 1968 1969 1970
    var Selection = this.State.Selection;
    var StartPos = Math.min( Selection.StartPos, Selection.EndPos );
    var EndPos   = Math.max( Selection.StartPos, Selection.EndPos );

    for ( var Pos = 0; Pos < StartPos; Pos++ )
1971
    {
1972 1973 1974
        if ( true !== this.Content[Pos].Is_Empty( { SkipAnchor : true } ) )
            return false;
    }
1975

1976
    for ( var Pos = StartPos; Pos <= EndPos; Pos++ )
1977
    {
1978
        if ( true === this.Content[Pos].Selection_CorrectLeftPos(Direction) )
1979
        {
1980 1981
            if ( 1 === Direction )
                this.Selection.StartPos = Pos + 1;
1982
            else
1983 1984 1985
                this.Selection.EndPos   = Pos + 1;

            this.Content[Pos].Selection_Remove();
1986 1987
        }
        else
1988 1989
            return false;
    }
1990

1991 1992 1993 1994 1995 1996 1997 1998 1999
    return true;
};
//-----------------------------------------------------------------------------------
// Работаем со значениями
//-----------------------------------------------------------------------------------
ParaHyperlink.prototype.Get_Text = function(Text)
{
    var ContentLen = this.Content.length;
    for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
2000
    {
2001 2002 2003 2004 2005 2006 2007 2008
        this.Content[CurPos].Get_Text( Text );
    }
};

ParaHyperlink.prototype.Set_Visited = function(Value)
{
    this.Visited = Value;
};
2009

2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023
ParaHyperlink.prototype.Get_Visited = function()
{
    return this.Visited;
};

ParaHyperlink.prototype.Set_ToolTip = function(ToolTip)
{
    History.Add( this, { Type : historyitem_Hyperlink_ToolTip, New : ToolTip, Old : this.ToolTip } );
    this.ToolTip = ToolTip;
};

ParaHyperlink.prototype.Get_ToolTip = function()
{
    if ( null === this.ToolTip )
2024
    {
2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043
        if ( "string" === typeof(this.Value) )
            return this.Value;
        else
            return "";
    }
    else
        return this.ToolTip;
};

ParaHyperlink.prototype.Get_Value = function()
{
    return this.Value;
};

ParaHyperlink.prototype.Set_Value = function(Value)
{
    History.Add( this, { Type : historyitem_Hyperlink_Value, New : Value, Old : this.Value } );
    this.Value = Value;
};
2044 2045 2046 2047

//-----------------------------------------------------------------------------------
// Undo/Redo функции
//-----------------------------------------------------------------------------------
2048 2049 2050 2051
ParaHyperlink.prototype.Undo = function(Data)
{
    var Type = Data.Type;
    switch(Type)
2052
    {
2053
        case historyitem_Hyperlink_AddItem :
2054
        {
2055
            this.Content.splice( Data.Pos, Data.EndPos - Data.Pos + 1 );
2056

2057
            this.protected_UpdateSpellChecking();
2058 2059
            break;
        }
2060

2061 2062 2063
        case historyitem_Hyperlink_RemoveItem :
        {
            var Pos = Data.Pos;
2064

2065 2066
            var Array_start = this.Content.slice( 0, Pos );
            var Array_end   = this.Content.slice( Pos );
2067

2068
            this.Content = Array_start.concat( Data.Items, Array_end );
2069

2070
            this.protected_UpdateSpellChecking();
2071 2072
            break;
        }
2073

2074 2075 2076 2077 2078
        case historyitem_Hyperlink_Value :
        {
            this.Value = Data.Old;
            break;
        }
2079

2080 2081 2082 2083
        case historyitem_Hyperlink_ToolTip :
        {
            this.ToolTip = Data.Old;
            break;
2084
        }
2085 2086
    }
};
2087

2088 2089 2090 2091
ParaHyperlink.prototype.Redo = function(Data)
{
    var Type = Data.Type;
    switch(Type)
2092
    {
2093
        case historyitem_Hyperlink_AddItem :
2094
        {
2095
            var Pos = Data.Pos;
2096

2097 2098
            var Array_start = this.Content.slice( 0, Pos );
            var Array_end   = this.Content.slice( Pos );
2099

2100
            this.Content = Array_start.concat( Data.Items, Array_end );
2101

2102
            this.protected_UpdateSpellChecking();
2103 2104
            break;
        }
2105

2106 2107 2108
        case historyitem_Hyperlink_RemoveItem :
        {
            this.Content.splice( Data.Pos, Data.EndPos - Data.Pos + 1 );
2109

2110
            this.protected_UpdateSpellChecking();
2111 2112
            break;
        }
2113

2114 2115 2116 2117 2118
        case historyitem_Hyperlink_Value :
        {
            this.Value = Data.New;
            break;
        }
2119

2120 2121 2122 2123
        case historyitem_Hyperlink_ToolTip :
        {
            this.ToolTip = Data.New;
            break;
2124
        }
2125 2126
    }
};
2127 2128 2129
//----------------------------------------------------------------------------------------------------------------------
// Функции совместного редактирования
//----------------------------------------------------------------------------------------------------------------------
2130 2131 2132 2133 2134
ParaHyperlink.prototype.Save_Changes = function(Data, Writer)
{
    // Сохраняем изменения из тех, которые используются для Undo/Redo в бинарный файл.
    // Long : тип класса
    // Long : тип изменений
2135

2136
    Writer.WriteLong( historyitem_type_Hyperlink );
2137

2138
    var Type = Data.Type;
2139

2140 2141
    // Пишем тип
    Writer.WriteLong( Type );
2142

2143 2144 2145
    switch(Type)
    {
        case historyitem_Hyperlink_AddItem :
2146
        {
2147 2148 2149 2150 2151 2152
            // Long     : Количество элементов
            // Array of :
            //  {
            //    Long     : Позиция
            //    Variable : Id элемента
            //  }
2153

2154 2155
            var bArray = Data.UseArray;
            var Count  = Data.Items.length;
2156

2157
            Writer.WriteLong( Count );
2158

2159 2160 2161 2162 2163 2164
            for ( var Index = 0; Index < Count; Index++ )
            {
                if ( true === bArray )
                    Writer.WriteLong( Data.PosArray[Index] );
                else
                    Writer.WriteLong( Data.Pos + Index );
2165

2166
                Writer.WriteString2( Data.Items[Index].Get_Id() );
2167 2168
            }

2169 2170 2171 2172 2173 2174 2175
            break;
        }

        case historyitem_Hyperlink_RemoveItem :
        {
            // Long          : Количество удаляемых элементов
            // Array of Long : позиции удаляемых элементов
2176

2177 2178
            var bArray = Data.UseArray;
            var Count  = Data.Items.length;
2179

2180 2181 2182
            var StartPos = Writer.GetCurPosition();
            Writer.Skip(4);
            var RealCount = Count;
2183

2184 2185 2186
            for ( var Index = 0; Index < Count; Index++ )
            {
                if ( true === bArray )
2187
                {
2188 2189
                    if ( false === Data.PosArray[Index] )
                        RealCount--;
2190
                    else
2191
                        Writer.WriteLong( Data.PosArray[Index] );
2192
                }
2193 2194 2195
                else
                    Writer.WriteLong( Data.Pos );
            }
2196

2197 2198 2199 2200
            var EndPos = Writer.GetCurPosition();
            Writer.Seek( StartPos );
            Writer.WriteLong( RealCount );
            Writer.Seek( EndPos );
2201

2202 2203
            break;
        }
2204

2205 2206 2207 2208 2209 2210
        case historyitem_Hyperlink_Value :
        {
            // String : Value
            Writer.WriteString2( Data.New );
            break;
        }
2211

2212 2213 2214 2215
        case historyitem_Hyperlink_ToolTip :
        {
            // String : ToolTip
            Writer.WriteString2( Data.New );
2216

2217
            break;
2218
        }
2219 2220
    }
};
2221

2222 2223 2224 2225 2226
ParaHyperlink.prototype.Load_Changes = function(Reader)
{
    // Сохраняем изменения из тех, которые используются для Undo/Redo в бинарный файл.
    // Long : тип класса
    // Long : тип изменений
2227

2228 2229 2230
    var ClassType = Reader.GetLong();
    if ( historyitem_type_Hyperlink != ClassType )
        return;
2231

2232
    var Type = Reader.GetLong();
2233

2234 2235 2236
    switch ( Type )
    {
        case historyitem_Hyperlink_AddItem :
2237
        {
2238 2239 2240 2241 2242 2243
            // Long     : Количество элементов
            // Array of :
            //  {
            //    Long     : Позиция
            //    Variable : Id Элемента
            //  }
2244

2245
            var Count = Reader.GetLong();
2246

2247 2248 2249 2250
            for ( var Index = 0; Index < Count; Index++ )
            {
                var Pos     = this.m_oContentChanges.Check( contentchanges_Add, Reader.GetLong() );
                var Element = g_oTableId.Get_ById( Reader.GetString2() );
2251

2252 2253 2254
                if ( null != Element )
                {
                    this.Content.splice( Pos, 0, Element );
2255 2256 2257
                }
            }

2258
            this.protected_UpdateSpellChecking();
2259 2260
            break;
        }
2261

2262 2263 2264 2265
        case historyitem_Hyperlink_RemoveItem:
        {
            // Long          : Количество удаляемых элементов
            // Array of Long : позиции удаляемых элементов
2266

2267
            var Count = Reader.GetLong();
2268

2269 2270 2271
            for ( var Index = 0; Index < Count; Index++ )
            {
                var ChangesPos = this.m_oContentChanges.Check( contentchanges_Remove, Reader.GetLong() );
2272

2273 2274 2275
                // действие совпало, не делаем его
                if ( false === ChangesPos )
                    continue;
2276

2277
                this.Content.splice( ChangesPos, 1 );
2278 2279
            }

2280
            this.protected_UpdateSpellChecking();
2281
            break;
2282
        }
2283

2284 2285 2286 2287 2288 2289
        case historyitem_Hyperlink_Value:
        {
            // String : Value
            this.Value = Reader.GetString2();
            break;
        }
2290

2291
        case historyitem_Hyperlink_ToolTip :
2292
        {
2293 2294 2295 2296
            // String : ToolTip
            this.ToolTip = Reader.GetString2();

            break;
2297
        }
2298 2299 2300 2301 2302 2303
    }
};

ParaHyperlink.prototype.Write_ToBinary2 = function(Writer)
{
    Writer.WriteLong( historyitem_type_Hyperlink );
2304

2305 2306 2307 2308 2309
    // String : Id
    // String : Value
    // String : ToolTip
    // Long   : Количество элементов
    // Array of Strings : массив с Id элементов
2310

2311 2312 2313 2314 2315 2316
    Writer.WriteString2( this.Id );
    if(!(editor && editor.isDocumentEditor))
    {
        this.Write_ToBinary2SpreadSheets(Writer);
        return;
    }
2317

2318 2319
    Writer.WriteString2( this.Value );
    Writer.WriteString2( this.ToolTip );
2320

2321 2322 2323 2324
    var Count = this.Content.length;
    Writer.WriteLong( Count );

    for ( var Index = 0; Index < Count; Index++ )
2325
    {
2326 2327 2328
        Writer.WriteString2( this.Content[Index].Get_Id() );
    }
};
2329

2330 2331 2332 2333 2334 2335 2336
ParaHyperlink.prototype.Read_FromBinary2 = function(Reader)
{
    // String : Id
    // String : Value
    // String : ToolTip
    // Long   : Количество элементов
    // Array of Strings : массив с Id элементов
2337

2338 2339 2340
    this.Id      = Reader.GetString2();
    this.Value   = Reader.GetString2();
    this.ToolTip = Reader.GetString2();
2341

2342 2343
    var Count = Reader.GetLong();
    this.Content = [];
2344

2345
    for ( var Index = 0; Index < Count; Index++ )
2346
    {
2347 2348 2349
        var Element = g_oTableId.Get_ById( Reader.GetString2() );
        if ( null !== Element )
            this.Content.push( Element );
2350 2351
    }
};
2352

2353 2354 2355 2356 2357 2358 2359
ParaHyperlink.prototype.Write_ToBinary2SpreadSheets = function(Writer)
{
    Writer.WriteString2("");
    Writer.WriteString2("");
    Writer.WriteLong(0);
};

2360 2361 2362 2363 2364 2365 2366 2367 2368 2369
function CParaHyperLinkStartState(HyperLink)
{
    this.Value = HyperLink.Value;
    this.ToolTip = HyperLink.ToolTip;
    this.Content = [];
    for(var i = 0; i < HyperLink.Content.length; ++i)
    {
        this.Content.push(HyperLink.Content);
    }
}