00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include "camtypes.h"
00104 #include "texttool.h"
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #include "blobs.h"
00118 #include "csrstack.h"
00119 #include "unicdman.h"
00120
00121 #include "keypress.h"
00122 #include "nodetext.h"
00123 #include "nodetxts.h"
00124 #include "nodetxtl.h"
00125 #include "objchge.h"
00126 #include "oilfiles.h"
00127 #include "opscale.h"
00128 #include "opsquash.h"
00129
00130
00131 #include "textinfo.h"
00132 #include "textops.h"
00133 #include "textfuns.h"
00134 #include "vkextra.h"
00135 #include "nodetxts.h"
00136 #include "nodemold.h"
00137 #include "cutop.h"
00138
00139 #include "layer.h"
00140 #include "nodepostpro.h"
00141 #include "nodepath.h"
00142 #include "usercord.h"
00143 #include "camview.h"
00144
00145 DECLARE_SOURCE( "$Revision: 1656 $" );
00146
00147 CC_IMPLEMENT_MEMDUMP(TextTool,Tool_v1)
00148 CC_IMPLEMENT_DYNAMIC(TextToolBlobPosItem, ListItem);
00149 CC_IMPLEMENT_DYNAMIC(TextToolBlobPosList, List);
00150
00151
00152
00153 #define new CAM_DEBUG_NEW
00154
00155
00156 TCHAR* TextTool::FamilyName = _T("Text Tools");
00157 TCHAR* TextTool::ToolName = _T("Text Tool");
00158 TCHAR* TextTool::Purpose = _T("Text manipulation");
00159 TCHAR* TextTool::Author = _T("TextToolTeam");
00160
00161
00162 BOOL TextTool::CurrentTool = FALSE;
00163 TextInfoBarOp* TextTool::pTextInfoBarOp = NULL;
00164
00165
00166 BOOL TextTool::UseDeadKeys = TRUE;
00167
00168 extern void Beep();
00169
00170
00171
00172
00173 static UINT32 GraveArray[] = { 0x0041, 0x00C0,
00174 0x0045, 0x00C8,
00175 0x0049, 0x00CC,
00176 0x004F, 0x00D2,
00177 0x0055, 0x00D9,
00178 0x0061, 0x00E0,
00179 0x0065, 0x00E8,
00180 0x0069, 0x00EC,
00181 0x006F, 0x00F2,
00182 0x0075, 0x00F9,
00183 0x0000 };
00184 static UINT32 AcuteArray[] = { 0x0041, 0x00C1,
00185 0x0045, 0x00C9,
00186 0x0049, 0x00CD,
00187 0x004F, 0x00D3,
00188 0x0055, 0x00DA,
00189 0x0059, 0x00DD,
00190 0x0061, 0x00E1,
00191 0x0065, 0x00E9,
00192 0x0069, 0x00ED,
00193 0x006F, 0x00F3,
00194 0x0075, 0x00FA,
00195 0x0079, 0x00FD,
00196 0x0000 };
00197 static UINT32 HatArray[] = { 0x0041, 0x00C2,
00198 0x0045, 0x00CA,
00199 0x0049, 0x00CE,
00200 0x004F, 0x00D4,
00201 0x0053, 0x008A,
00202 0x0055, 0x00DB,
00203 0x0061, 0x00E2,
00204 0x0065, 0x00EA,
00205 0x0069, 0x00EE,
00206 0x006F, 0x00F4,
00207 0x0073, 0x009A,
00208 0x0075, 0x00FB,
00209 0x0000 };
00210 static UINT32 TildeArray[] = { 0x0041, 0x00C3,
00211 0x004E, 0x00D1,
00212 0x004F, 0x00D5,
00213 0x0061, 0x00E3,
00214 0x006E, 0x00F1,
00215 0x006F, 0x00F5,
00216 0x0000 };
00217 static UINT32 ColonArray[] = { 0x0041, 0x00C4,
00218 0x0045, 0x00CB,
00219 0x0049, 0x00CF,
00220 0x004F, 0x00D6,
00221 0x0055, 0x00DC,
00222 0x0059, 0x009F,
00223 0x0061, 0x00E4,
00224 0x0065, 0x00EB,
00225 0x0069, 0x00EF,
00226 0x006F, 0x00F6,
00227 0x0075, 0x00FC,
00228 0x0079, 0x00FF,
00229 0x0000 };
00230 static UINT32 AtArray[] = { 0x0041, 0x00C5,
00231 0x0061, 0x00E5,
00232 0x0043, 0x00A9,
00233 0x0052, 0x00AE,
00234 0x0063, 0x00A9,
00235 0x0072, 0x00AE,
00236 0x0000 };
00237 static UINT32 CommaArray[] = { 0x0043, 0x00C7,
00238 0x0063, 0x00E7,
00239 0x0000 };
00240 static UINT32 SlashArray[] = { 0x004F, 0x00D8,
00241 0x0063, 0x00A2,
00242 0x006F, 0x00F8,
00243 0x0000 };
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 TextTool::TextTool()
00260 {
00261 pcCurrentCursor = NULL;
00262 IsBlankCursorUp = FALSE;
00263 UpdateAfterTyping = FALSE;
00264
00265 PreviousDeadKey = NULL;
00266 GraveVirtKey = NULL;
00267 AcuteVirtKey = NULL;
00268 HatVirtKey = NULL;
00269 TildeVirtKey = NULL;
00270 ColonVirtKey = NULL;
00271 AtVirtKey = NULL;
00272 CommaVirtKey = NULL;
00273 SlashVirtKey = NULL;
00274 pLastFocusStory = NULL;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 TextTool::~TextTool()
00288 {
00289 pTextInfoBarOp->pTextTool = NULL;
00290 TextInfoBarOp::DeInit();
00291
00292 RemoveDeadKeys();
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 BOOL TextTool::Init()
00310 {
00311
00312
00313 BOOL ok = TRUE;
00314
00315
00316 ok = ok && OpCreateTextObject::Init();
00317 ok = ok && OpTextSelection::Init();
00318 ok = ok && OpDeleteTextStory::Init();
00319 ok = ok && OpReverseStoryPath::Init();
00320 ok = ok && OpApplyJustificationToStory::Init();
00321 ok = ok && OpTextPaste::Init();
00322 ok = ok && OpTogglePrintTextAsShapes::Init();
00323 ok = ok && OpDragStoryNonPathLeftIndent::Init();
00324 ok = ok && OpDragStoryNonPathRightIndent::Init();
00325 ok = ok && OpDragStoryPathLeftIndent::Init();
00326 ok = ok && OpDragStoryPathRightIndent::Init();
00327 ok = ok && OpAffectFontChange::Init();
00328 ok = ok && TextInfoBarOp::Init();
00329
00330
00331
00332
00333 if (ok)
00334 {
00335 #if 0
00336 CCResTextFile file;
00337 TextInfoBarOpCreate BarCreate;
00338
00339 ok = file.open(_R(IDM_TEXT_BAR), _R(IDT_INFO_BAR_RES));
00340 if (ok) ok = DialogBarOp::ReadBarsFromFile(file,BarCreate);
00341 if (ok) file.close();
00342
00343 ENSURE(ok,"Unable to load Textbar.ini from resource\n");
00344
00345 if (ok)
00346 {
00347
00348 String_32 str = String_32(_R(IDS_TEXTTOOL_INFOBARNAME));
00349 DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str);
00350
00351 ok = (pDialogBarOp != NULL);
00352 if (ok) ok = pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(TextInfoBarOp));
00353 if (ok) pTextInfoBarOp = (TextInfoBarOp*)pDialogBarOp;
00354
00355 ENSURE(ok,"Error finding the Text tool info bar");
00356 }
00357 #endif
00358 pTextInfoBarOp = new TextInfoBarOp();
00359 ok = (pTextInfoBarOp != NULL);
00360 ENSURE(ok,"Error finding the Text tool info bar");
00361 }
00362
00363
00364 GetApplication()->DeclareSection(_T("TextTool"),1);
00365 GetApplication()->DeclarePref(_T("TextTool"),_T("UseDeadKeys"), &UseDeadKeys, 0, 1);
00366
00367
00368 if (ok)
00369 ok = RegisterDeadKeys();
00370
00371 return (ok);
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 void TextTool::Describe(void *InfoPtr)
00393 {
00394
00395 ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr;
00396
00397 Info->InfoVersion = 1;
00398
00399 Info->InterfaceVersion = GetToolInterfaceVersion();
00400
00401
00402 Info->Version = 1;
00403 Info->ID = GetID();
00404 Info->TextID = _R(IDS_TEXT_TOOL);
00405
00406 Info->Family = FamilyName;
00407 Info->Name = ToolName;
00408 Info->Purpose = Purpose;
00409 Info->Author = Author;
00410
00411 Info->BubbleID = _R(IDBBL_TEXT_TOOLBOX);
00412
00413 Info->CurrentAttributeGroup = CC_RUNTIME_CLASS(BaseTextClass);
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 void TextTool::SelectChange(BOOL isSelected)
00432 {
00433 BOOL ok = TRUE;
00434
00435 if (isSelected)
00436 ok = OnToolSelect();
00437 else
00438 ok = OnToolDeselect();
00439
00440 if (!ok)
00441 InformError();
00442 }
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 BOOL TextTool::CreateCursors()
00461 {
00462
00463 pcNormalTextCursor = new Cursor(this, _R(IDC_TEXTTOOLBLOBCURSOR));
00464 pcBlobTextCursor = new Cursor(this, _R(IDC_TEXTTOOLCURSOR));
00465 pcIndentCursor = new Cursor(this, _R(IDC_TEXTTOOLINDENTCURSOR));
00466 pcBlankCursor = new Cursor(this, _R(IDC_TEXTTOOLBLANKCURSOR));
00467
00468 if ( pcNormalTextCursor==NULL || !pcNormalTextCursor->IsValid() ||
00469 pcBlobTextCursor==NULL || !pcBlobTextCursor->IsValid() ||
00470 pcIndentCursor==NULL || !pcIndentCursor->IsValid() ||
00471 pcBlankCursor==NULL || !pcBlankCursor->IsValid() )
00472 {
00473 DestroyCursors();
00474 return FALSE;
00475 }
00476 else
00477 return TRUE;
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 void TextTool::DestroyCursors()
00497 {
00498 if (pcNormalTextCursor != NULL) delete pcNormalTextCursor;
00499 if (pcBlobTextCursor != NULL) delete pcBlobTextCursor;
00500 if (pcIndentCursor != NULL) delete pcIndentCursor;
00501 if (pcBlankCursor != NULL) delete pcBlankCursor;
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525 void TextTool::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods, Spread* pSpread )
00526 {
00527 if (ClickMods.Menu) return;
00528
00529 if (IsBlankCursorUp)
00530 return;
00531
00532 DocView* pDocView = DocView::GetSelected();
00533 if (pDocView == NULL)
00534 {
00535 ERROR3("No selected doc view!");
00536 }
00537 else
00538 {
00539 BOOL Success = TRUE;
00540
00541 switch (Click)
00542 {
00543 case CLICKTYPE_SINGLE:
00544 if (pDocView->IsSingleClickReallyTriple())
00545 Success = HandleTripleClick(pSpread, PointerPos, ClickMods);
00546 else
00547 Success = HandleSingleClick(pSpread, PointerPos, ClickMods);
00548 break;
00549 case CLICKTYPE_DOUBLE:
00550 if (pDocView->IsSingleClickReallyQuad())
00551 Success = HandleQuadClick(pSpread, PointerPos, ClickMods);
00552 else
00553 Success = HandleDoubleClick(pSpread, PointerPos, ClickMods);
00554 break;
00555 case CLICKTYPE_DRAG:
00556 Success = HandleDragClick(pSpread, PointerPos, ClickMods);
00557 break;
00558 default:
00559 break;
00560 }
00561
00562 if (!Success)
00563 InformError();
00564 }
00565 }
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 BOOL TextTool::HandleSingleClick(Spread* pSpread, DocCoord ClickPos, ClickModifiers ClickMods)
00585 {
00586 Node* pHitObject = NULL;
00587 TextStory* pTextStoryToSelect = NULL;
00588
00589
00590 BOOL BlobIsLeft = TRUE;
00591 TextStory* pFoundStory = NULL;
00592 if (!m_BlobPosList.FindBlobStory(pSpread, ClickPos, &BlobIsLeft, &pFoundStory))
00593 return FALSE;
00594
00595 if (pFoundStory != NULL)
00596 {
00597 if (!m_BlobPosList.RenderAndRemove(pFoundStory))
00598 return FALSE;
00599
00600
00601 OpDragStoryIndent* pOp = NULL;
00602 if (BlobIsLeft)
00603 {
00604 if (pFoundStory->GetTextPath() != NULL)
00605 pOp = new OpDragStoryPathLeftIndent;
00606 else
00607 pOp = new OpDragStoryNonPathLeftIndent;
00608 }
00609 else
00610 {
00611 if (pFoundStory->GetTextPath() != NULL)
00612 pOp = new OpDragStoryPathRightIndent;
00613 else
00614 pOp = new OpDragStoryNonPathRightIndent;
00615 }
00616 if (pOp==NULL)
00617 return FALSE;
00618 else
00619 return pOp->DoDrag(ClickPos, pSpread, ClickMods, pFoundStory);
00620 }
00621 else if ( IsPointNearUnselectedTextStory(pSpread, ClickPos, &pTextStoryToSelect, &pHitObject, FALSE) )
00622 {
00623
00624 OpTextSelection* pOp = new OpTextSelection;
00625 if (pOp == NULL)
00626 return FALSE;
00627 else
00628 return pOp->DoDrag(ClickPos, pSpread, ClickMods, pHitObject);
00629 }
00630 else
00631 {
00632
00633 OpCreateTextObject* pOpCreateTextObject = new OpCreateTextObject;
00634 if (pOpCreateTextObject == NULL)
00635 return FALSE;
00636 else
00637 {
00638 NodePath* pPath = NULL;
00639 IsPointNearNonStoryPath(pSpread, ClickPos, &pPath, FALSE);
00640 if (pPath != NULL)
00641 pOpCreateTextObject->DoImmediate(pSpread, ClickPos, pPath, ClickMods);
00642 else
00643 pOpCreateTextObject->DoDrag(pSpread, ClickPos, ClickMods);
00644 }
00645 }
00646 return TRUE;
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 BOOL TextTool::HandleDoubleClick(Spread* pSpread, DocCoord ClickPos, ClickModifiers ClickMods)
00667 {
00668 BOOL Success = TRUE;
00669
00670 if ((TextStory::GetFocusStory() != NULL) && !ClickMods.Constrain && !ClickMods.Adjust)
00671 {
00672 OpTextCaret* pOp = new OpTextCaret();
00673 if (pOp != NULL)
00674 pOp->DoSelectWordAtCaret();
00675 else
00676 Success = FALSE;
00677 }
00678 return Success;
00679 }
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 BOOL TextTool::HandleTripleClick(Spread* pSpread, DocCoord ClickPos, ClickModifiers ClickMods)
00696 {
00697 ERROR2IF(TextStory::GetFocusStory()==NULL, FALSE, "No focus story");
00698 ERROR2IF(TextStory::GetFocusStory()->GetCaret()==NULL, FALSE, "No caret in focus story");
00699
00700 TextLine* pLine = (TextLine*)TextStory::GetFocusStory()->GetCaret()->FindParent(CC_RUNTIME_CLASS(TextLine));
00701 ERROR2IF(pLine==NULL, FALSE, "Caret didn't have a parent TextLine");
00702
00703 OpTextSelection* pOp = new OpTextSelection();
00704 if (pOp != NULL)
00705 return pOp->DoSelectLineText();
00706 else
00707 return FALSE;
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 BOOL TextTool::HandleQuadClick(Spread* pSpread, DocCoord ClickPos, ClickModifiers ClickMods)
00725 {
00726 return TRUE;
00727 }
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 BOOL TextTool::HandleDragClick(Spread* pSpread, DocCoord ClickPos, ClickModifiers ClickMods)
00747 {
00748 return TRUE;
00749 }
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 BOOL TextTool::IsPointNearUnselectedTextStory(Spread* pSpread, DocCoord ClickPos, TextStory** pTS, Node** pHitObject, BOOL AllowInterrupts)
00777 {
00778 Node* pInterrupt;
00779 NodeRenderableInk* pObject = NULL;
00780
00781 if (AllowInterrupts)
00782 pObject = NodeRenderableInk::FindSimpleAtPoint(pSpread, ClickPos, NULL, &pInterrupt);
00783 else
00784 pObject = NodeRenderableInk::FindSimpleAtPoint(pSpread, ClickPos);
00785
00786
00787
00788
00789
00790
00791 NodeRenderableInk* pCompound = NodeRenderableInk::FindCompoundFromSimple(pObject);
00792 if (pCompound && pCompound->IsEffect() && ((NodeEffect*)pCompound)->IsLockedEffect())
00793 return FALSE;
00794
00795 *pTS = NULL;
00796 if (pHitObject!=NULL)
00797 *pHitObject = NULL;
00798
00799
00800 if (pObject != NULL)
00801 {
00802 if (pObject->IsAVisibleTextNode())
00803 {
00804 if (pHitObject!=NULL)
00805 *pHitObject = pObject;
00806 *pTS = (TextStory*)(pObject->FindParent()->FindParent());
00807 return TRUE;
00808 }
00809 }
00810
00811
00812
00813 Node* pNode = pSpread->FindFirstDepthFirst();
00814 while (pNode != NULL)
00815 {
00816 if (pNode->IsABaseTextClass() && IS_A(pNode, TextStory))
00817 {
00818
00819 TextStory* pStory = (TextStory*)pNode;
00820 DocRect StoryBounds = pStory->GetBoundingRect(TRUE);
00821 if (StoryBounds.ContainsCoord(ClickPos))
00822 {
00823
00824 Layer* pLayer = (Layer*)pStory->FindParent(CC_RUNTIME_CLASS(Layer));
00825 NodeMould* pMould = (NodeMould*)pStory->FindParent(CC_RUNTIME_CLASS(NodeMould));
00826 if (pLayer!=NULL && pMould==NULL && pStory->GetTextPath()==NULL && !pLayer->IsLocked())
00827 {
00828
00829 if (pHitObject!=NULL)
00830 {
00831 VisibleTextNode* pNearObject = NULL;
00832 BOOL ToLeft = FALSE;
00833 if (!pStory->GetCharacterAtPoint(TRUE, ClickPos, &pNearObject, &ToLeft))
00834 {
00835 InformError();
00836 return FALSE;
00837 }
00838 else
00839 {
00840 if (pNearObject != NULL)
00841 {
00842 *pHitObject = pNearObject;
00843 *pTS = pStory;
00844 return TRUE;
00845 }
00846 }
00847 }
00848 else
00849 {
00850
00851 DocRect UTStory = pStory->GetUTStoryBounds();
00852 DocCoord UTPoint = ClickPos;
00853 Matrix StoryMat = pStory->GetStoryMatrix();
00854 StoryMat=StoryMat.Inverse();
00855 StoryMat.transform(&UTPoint);
00856
00857 if (UTStory.ContainsCoord(UTPoint))
00858 {
00859 *pTS=pStory;
00860 return TRUE;
00861 }
00862 }
00863 }
00864 }
00865 }
00866 pNode = pNode->FindNextDepthFirst(pSpread);
00867 }
00868
00869 return FALSE;
00870 }
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893 BOOL TextTool::IsPointNearNonStoryPath( Spread* pSpread, DocCoord PointerPos, NodePath** pHitPath, BOOL AllowInterrupts)
00894 {
00895 Node* pInterrupt;
00896 NodeRenderableInk* pObject = NULL;
00897 *pHitPath = NULL;
00898
00899 if (AllowInterrupts)
00900 pObject = NodeRenderableInk::FindSimpleAtPoint(pSpread, PointerPos, NULL, &pInterrupt);
00901 else
00902 pObject = NodeRenderableInk::FindSimpleAtPoint(pSpread, PointerPos);
00903
00904
00905 if (pObject != NULL)
00906 {
00907 Node* pParent = pObject->FindParent();
00908 ObjChangeParam ChangeData(OBJCHANGE_STARTING, ObjChangeFlags(TRUE), pObject, NULL);
00909 if (IS_A(pObject, NodePath) && pObject->IsSelected() &&
00910 (pParent != NULL) && !IS_A(pParent, TextStory) &&
00911 pObject->AllowOp(&ChangeData, FALSE) )
00912 {
00913
00914 NodePath* pPath = (NodePath*)pObject;
00915 INT32 PathSlot = 0;
00916 if (pPath->InkPath.PointCloseToLine(PointerPos, &PathSlot))
00917 {
00918 *pHitPath = (NodePath*)pObject;
00919 return TRUE;
00920 }
00921 }
00922 }
00923
00924 return FALSE;
00925 }
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 void TextTool::OnMouseMove(DocCoord PointerPos, Spread* pSpread, ClickModifiers ClickMods)
00942 {
00943
00944 DisplayStatusBarHelp(PointerPos, pSpread, ClickMods);
00945 IsBlankCursorUp = FALSE;
00946
00947
00948 NodePath* pPath = NULL;
00949 TextStory* pTextStoryToSelect = NULL;
00950 Cursor* DisplayCur = pcNormalTextCursor;
00951
00952
00953 if ( IsPointNearUnselectedTextStory(pSpread, PointerPos, &pTextStoryToSelect, NULL, TRUE) ||
00954 IsPointNearNonStoryPath(pSpread, PointerPos, &pPath, TRUE) )
00955 {
00956 DisplayCur = pcBlobTextCursor;
00957 }
00958
00959
00960 TextStory* pFoundStory = NULL;
00961 if (!m_BlobPosList.FindBlobStory(pSpread, PointerPos, NULL, &pFoundStory))
00962 InformError();
00963 else if (pFoundStory != NULL)
00964 DisplayCur = pcIndentCursor;
00965
00966
00967 if ( (DisplayCur != pcCurrentCursor) && (DisplayCur != NULL) )
00968 {
00969 pcCurrentCursor = DisplayCur;
00970 CursorStack::GSetTop(pcCurrentCursor, CurrentCursorID);
00971 }
00972 }
00973
00974 void TextTool::GetRulerOrigin(Spread* pSpread, UserCoord *pOrigin)
00975 {
00976 if (TextInfoBarOp::IsRulerOriginClaimed())
00977 {
00978 pOrigin->x = TextInfoBarOp::GetRulerOrigin();
00979 }
00980 }
00981
00982 void TextTool::RenderRulerBlobs(RulerBase* pRuler, UserRect& UpdateRect, BOOL IsBackground)
00983 {
00984
00985 if (!TextInfoBarOp::IsRulerOriginClaimed()) return;
00986
00987
00988 if (IsBackground)
00989 {
00990 TextInfoBarOp::HighlightRulerSection(pRuler, UpdateRect);
00991 }
00992 else
00993 {
00994 TextInfoBarOp::RenderRulerBlobs(pRuler, UpdateRect);
00995 }
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015 BOOL TextTool::OnRulerClick(UserCoord PointerPos, ClickType Click, ClickModifiers Mods,
01016 Spread* pSpread, RulerBase* pRuler)
01017 {
01018 if (!TextInfoBarOp::IsRulerOriginClaimed()) return FALSE;
01019 return TextInfoBarOp::OnRulerClick(PointerPos, Click, Mods, pSpread, pRuler);
01020 }
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038 BOOL TextTool::GetRulerStatusLineText(String_256* pText, UserCoord PointerPos,
01039 Spread* pSpread, RulerBase* pRuler)
01040 {
01041 if (!TextInfoBarOp::IsRulerOriginClaimed()) return FALSE;
01042 return TextInfoBarOp::GetRulerStatusLineText(pText, PointerPos, pSpread, pRuler);
01043 }
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 BOOL TextTool::OnKeyPress(KeyPress* pKeyPress)
01059 {
01060 TRACEUSER( "wuerthne", _T("TextTool::OnKeyPress, IsChar=%d IsRelease=%d VirtKey=%d\n"),
01061 pKeyPress->IsChar(), pKeyPress->IsRelease(), pKeyPress->GetVirtKey() );
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079 if (pKeyPress->IsRelease())
01080 {
01081 TRACEUSER( "wuerthne", _T("Release\n") );
01082
01083 if (GetApplication()->FindSelection()->IsSelRangeGagged())
01084 {
01085 GetApplication()->FindSelection()->SetGag(FALSE);
01086 GetApplication()->FindSelection()->Update(TRUE);
01087 }
01088 return FALSE;
01089 }
01090
01091
01092 if (HandleSpecialStoryAndNonStoryKeys(pKeyPress))
01093 {
01094 TRACEUSER( "wuerthne", _T("SpecialStoryAndNonStoryKeys\n") );
01095
01096 return TRUE;
01097 }
01098
01099
01100 if (TextStory::GetFocusStory() == NULL)
01101 {
01102 SelRange* pSelection = GetApplication()->FindSelection();
01103 Node* pNode = pSelection->FindFirst();
01104 while (pNode != NULL)
01105 {
01106 if (IS_A(pNode,CaretNode))
01107 {
01108 TextStory::SetFocusStory((TextStory*)pNode->FindParent(CC_RUNTIME_CLASS(TextStory)));
01109 break;
01110 }
01111
01112 pNode = pSelection->FindNext(pNode);
01113 }
01114 }
01115
01116
01117 if (TextStory::GetFocusStory() == NULL)
01118 {
01119 TRACEUSER( "wuerthne", _T("GetFocusStory\n") );
01120
01121 return HandleSpecialNonStoryKeys(pKeyPress);
01122 }
01123
01124
01125 if ( !(TextStory::GetFocusStory()->GetCaret()->IsSelected()) &&
01126 (TextStory::GetFocusStory()->GetSelectionEnd() == NULL) )
01127 {
01128 TextStory::SetFocusStory(NULL);
01129 return HandleSpecialNonStoryKeys(pKeyPress);
01130 }
01131
01132
01133 SelRange* Selection = GetApplication()->FindSelection();
01134 Node* pNode = Selection->FindFirst();
01135 while (pNode != NULL)
01136 {
01137 if (pNode->IsAnObject())
01138 {
01139 if (!pNode->IsABaseTextClass())
01140 ((NodeRenderableInk*)pNode)->DeSelect(TRUE);
01141 else
01142 {
01143 if (!IS_A(pNode,TextStory))
01144 {
01145 TextStory* pParentStory = (TextStory*)pNode->FindParent(CC_RUNTIME_CLASS(TextStory));
01146 if (pParentStory != TextStory::GetFocusStory())
01147 ((NodeRenderableInk*)pNode)->DeSelect(TRUE);
01148 }
01149 }
01150 }
01151
01152 pNode = Selection->FindNext(pNode);
01153 }
01154
01155
01156 if (HandleSpecialStoryKeys(pKeyPress, TextStory::GetFocusStory(), TextStory::GetFocusStory()->GetCaret()))
01157 {
01158 TRACEUSER( "wuerthne", _T("HandleSpecialStoryKeys\n") );
01159
01160 return TRUE;
01161 }
01162
01163
01164 if( !pKeyPress->IsChar() )
01165 {
01166 TRACEUSER("wuerthne", _T("not char"));
01167
01168
01169 if( !pKeyPress->IsConstrain() && !pKeyPress->IsAlternative() && !pKeyPress->IsExtended() )
01170 return true;
01171
01172 return pKeyPress->GetUnicode() == _T(' ');
01173 }
01174
01175
01176
01177 if (pKeyPress->GetVirtKey() >= CAMKEY(F1) && pKeyPress->GetVirtKey() <= CAMKEY(F12))
01178 return FALSE;
01179
01180 if ( (!pKeyPress->IsAlternative()) ||
01181 (pKeyPress->IsAlternative() && pKeyPress->IsExtended()) ||
01182 (pKeyPress->IsAlternative() && pKeyPress->IsConstrain()) )
01183 {
01184 WCHAR UnicodeValue = pKeyPress->GetUnicode();
01185 TRACEUSER("wuerthne", _T("UnicodeValue from keypress event = %04x %d"), UnicodeValue, pKeyPress->IsExtended() );
01186
01187
01188 if (HandleDeadKeys(pKeyPress, &UnicodeValue) || pKeyPress->IsExtended())
01189 return TRUE;
01190 else
01191 {
01192 if ( (UnicodeValue>=32) && ((UnicodeValue < CAMELOT_UNICODE_BASE) || (UnicodeValue > CAMELOT_UNICODE_LAST)))
01193 {
01194 #ifndef EXCLUDE_FROM_XARALX
01195 if ((UnicodeValue < 256) )
01196 UnicodeValue = UnicodeManager::MultiByteToUnicode(UnicodeValue);
01197 #endif
01198
01199
01200
01201 if (!IsBlankCursorUp)
01202 {
01203 DocView* pDocView = DocView::GetSelected();
01204 if (pDocView != NULL)
01205 {
01206 OilCoord DummyPos;
01207 CCamView* pCCamView = pDocView->GetConnectionToOilView();
01208 if (pCCamView && pCCamView->GetCurrentMousePos(&DummyPos))
01209 {
01210
01211 pcCurrentCursor = pcBlankCursor;
01212 CursorStack::GSetTop(pcCurrentCursor, CurrentCursorID);
01213 IsBlankCursorUp = TRUE;
01214 }
01215 }
01216 }
01217
01218
01219 OpTextFormat* pOp = new OpTextFormat();
01220 if (pOp != NULL)
01221 {
01222 TRACEUSER("jlh92", _T("inserting Unicode char %04x"), UnicodeValue);
01223 pOp->DoInsertChar(UnicodeValue, OpTextFormat::INSERT);
01224 UpdateAfterTyping = TRUE;
01225 return TRUE;
01226 }
01227 }
01228 else
01229 TRACEUSER( "jlh92", _T("Rejected\n" ) );
01230 }
01231 }
01232 TRACEUSER("wuerthne", _T("TextTool::OnKeyPress returns FALSE"));
01233 return FALSE;
01234 }
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248 BOOL TextTool::HandleSpecialStoryAndNonStoryKeys(KeyPress* pKeyPress)
01249 {
01250 ERROR3IF(pKeyPress == NULL, "KeyPress pointer was NULL");
01251 if (pKeyPress == NULL)
01252 return FALSE;
01253
01254 if (pKeyPress->IsChar()) return FALSE;
01255
01256 BOOL UsedTheKeypress = FALSE;
01257 BOOL Errored = FALSE;
01258
01259 switch (pKeyPress->GetVirtKey())
01260 {
01261 case CAMKEY(B):
01262
01263 if (pKeyPress->IsConstrain() && !pKeyPress->IsAdjust() )
01264 {
01265 UsedTheKeypress = TRUE;
01266 Errored = !ApplyBold();
01267 }
01268 break;
01269 case CAMKEY(I):
01270
01271 if (pKeyPress->IsConstrain() && !pKeyPress->IsAdjust() )
01272 {
01273 UsedTheKeypress = TRUE;
01274 Errored = !ApplyItalic();
01275 }
01276 break;
01277 }
01278
01279 if (Errored)
01280 InformError();
01281 TRACEUSER("wuerthne", _T("HandleSpecialStoryAndNonStoryKeys returns %d"), UsedTheKeypress);
01282 return UsedTheKeypress;
01283 }
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297 BOOL TextTool::HandleSpecialNonStoryKeys(KeyPress* pKeyPress)
01298 {
01299 ERROR3IF(pKeyPress == NULL, "KeyPress pointer was NULL");
01300 if (pKeyPress == NULL)
01301 return FALSE;
01302
01303 BOOL UsedTheKeypress = FALSE;
01304
01305 switch (pKeyPress->GetVirtKey())
01306 {
01307 case CAMKEY(UP):
01308 case CAMKEY(DOWN):
01309 case CAMKEY(LEFT):
01310 case CAMKEY(RIGHT):
01311 UsedTheKeypress = TRUE;
01312 break;
01313 }
01314 TRACEUSER("wuerthne", _T("HandleSpecialNonStoryKeys returns %d"), UsedTheKeypress);
01315 return UsedTheKeypress;
01316 }
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333 BOOL TextTool::HandleSpecialStoryKeys(KeyPress* pKeyPress, TextStory* pStory, CaretNode* pCaret)
01334 {
01335 TRACEUSER("wuerthne", _T("HandleSpecialStoryKeys %d"), pKeyPress->GetVirtKey());
01336 ERROR3IF(pKeyPress == NULL, "KeyPress pointer was NULL");
01337 ERROR3IF(pStory == NULL, "Story pointer was NULL");
01338 ERROR3IF(pCaret == NULL, "Caret pointer was NULL");
01339 if ((pKeyPress == NULL) || (pStory == NULL) || (pCaret == NULL))
01340 return FALSE;
01341
01342 BOOL IsNonCharEvent = !pKeyPress->IsChar();
01343 BOOL UsedTheKeypress = FALSE;
01344 BOOL Errored = FALSE;
01345
01346 switch (pKeyPress->GetVirtKey())
01347 {
01348 case CAMKEY(HOME):
01349
01350 if (IsNonCharEvent)
01351 {
01352 OpTextCaret* pOp = new OpTextCaret();
01353 if (pOp != NULL)
01354 pOp->DoMoveCaretHome(pKeyPress->IsAdjust(), pKeyPress->IsConstrain());
01355 else
01356 Errored = TRUE;
01357 }
01358 UsedTheKeypress = TRUE;
01359 break;
01360 case CAMKEY(END):
01361
01362 if (IsNonCharEvent)
01363 {
01364 OpTextCaret* pOp = new OpTextCaret();
01365 if (pOp != NULL)
01366 pOp->DoMoveCaretEnd(pKeyPress->IsAdjust(), pKeyPress->IsConstrain());
01367 else
01368 Errored = TRUE;
01369 }
01370 UsedTheKeypress = TRUE;
01371 break;
01372 case CAMKEY(BACK):
01373
01374 if (IsNonCharEvent && (pStory->GetSelectionEnd() || pCaret->FindPrevVTNInStory() != NULL))
01375 {
01376 OpTextFormat* pOp = new OpTextFormat();
01377 if (pOp != NULL)
01378 pOp->DoDeleteChar(OpTextFormat::BACKSPACE);
01379 else
01380 Errored = TRUE;
01381 }
01382 UsedTheKeypress = TRUE;
01383 break;
01384 case CAMKEY(DELETE):
01385
01386 if (IsNonCharEvent && (pStory->GetSelectionEnd() || pCaret->FindNextVTNInStory() != pStory->FindLastVTN()))
01387 {
01388 OpTextFormat* pOp = new OpTextFormat();
01389 if (pOp != NULL)
01390 pOp->DoDeleteChar(OpTextFormat::DEL);
01391 else
01392 Errored = TRUE;
01393 }
01394 UsedTheKeypress = TRUE;
01395 break;
01396 case CAMKEY(LEFT):
01397
01398 if (IsNonCharEvent)
01399 {
01400 TRACEUSER("wuerthne", _T("caret left"));
01401 OpTextCaret* pOp = new OpTextCaret();
01402 if (pOp != NULL)
01403 pOp->DoMoveCaretLeft(pKeyPress->IsAdjust(), pKeyPress->IsConstrain());
01404 else
01405 Errored = TRUE;
01406 }
01407 UsedTheKeypress = TRUE;
01408 break;
01409 case CAMKEY(RIGHT):
01410
01411 if (IsNonCharEvent)
01412 {
01413 OpTextCaret* pOp = new OpTextCaret();
01414 if (pOp != NULL)
01415 pOp->DoMoveCaretRight(pKeyPress->IsAdjust(), pKeyPress->IsConstrain());
01416 else
01417 Errored = TRUE;
01418 }
01419 UsedTheKeypress = TRUE;
01420 break;
01421 case CAMKEY(UP):
01422
01423 if (IsNonCharEvent)
01424 {
01425 OpTextCaret* pOp = new OpTextCaret();
01426 if (pOp != NULL)
01427 pOp->DoMoveCaretUp(pKeyPress->IsAdjust());
01428 else
01429 Errored = TRUE;
01430 }
01431 UsedTheKeypress = TRUE;
01432 break;
01433 case CAMKEY(DOWN):
01434
01435 if (IsNonCharEvent)
01436 {
01437 OpTextCaret* pOp = new OpTextCaret();
01438 if (pOp != NULL)
01439 pOp->DoMoveCaretDown(pKeyPress->IsAdjust());
01440 else
01441 Errored = TRUE;
01442 }
01443 UsedTheKeypress = TRUE;
01444 break;
01445 case CAMKEY(C):
01446
01447 if (pKeyPress->IsConstrain() && pKeyPress->IsAdjust() )
01448 {
01449 if (IsNonCharEvent && TextStory::GetFocusStory()->GetCaret()->FindNextTextCharInStory() != NULL)
01450 {
01451 OpTextFormat* pOp = new OpTextFormat();
01452 if (pOp != NULL)
01453 {
01454 pOp->DoSwapCase();
01455 }
01456 else
01457 Errored = TRUE;
01458 }
01459 UsedTheKeypress = TRUE;
01460 }
01461 break;
01462 case CAMKEY(A):
01463
01464 if (pKeyPress->IsConstrain() && !pKeyPress->IsAdjust())
01465 {
01466 if (IsNonCharEvent)
01467 {
01468 OpTextSelection* pOp = new OpTextSelection();
01469 if (pOp != NULL)
01470 Errored = !pOp->DoSelectAllText(TextStory::GetFocusStory());
01471 else
01472 Errored = TRUE;
01473 }
01474 UsedTheKeypress = TRUE;
01475 }
01476 break;
01477
01478 case CAMKEY(V):
01479
01480 if (pKeyPress->IsConstrain() && !pKeyPress->IsAdjust())
01481 {
01482 if (IsNonCharEvent)
01483 {
01484
01485 OpTextPaste* pOp = new OpTextPaste();
01486 if (pOp != NULL)
01487 pOp->Do(NULL);
01488 }
01489 UsedTheKeypress = TRUE;
01490 }
01491 break;
01492
01493 case CAMKEY(L):
01494
01495 if (pKeyPress->IsConstrain() && !pKeyPress->IsAdjust())
01496 {
01497 TextLine* pLine = (TextLine*)TextStory::GetFocusStory()->GetCaret()->FindParent(CC_RUNTIME_CLASS(TextLine));
01498 if (pLine != NULL)
01499 {
01500 if (IsNonCharEvent)
01501 {
01502 OpTextSelection* pOp = new OpTextSelection();
01503 if (pOp != NULL)
01504 Errored = !pOp->DoSelectLineText();
01505 else
01506 Errored = TRUE;
01507 }
01508 UsedTheKeypress = TRUE;
01509 }
01510 }
01511 break;
01512 case CAMKEY(EQUALS):
01513
01514 if (pKeyPress->IsConstrain() && !pKeyPress->IsAdjust() )
01515 {
01516 UsedTheKeypress = TRUE;
01517 Errored = IsNonCharEvent ? !IncreaseTrackKern() : FALSE;
01518 }
01519 break;
01520 case CAMKEY(MINUS):
01521
01522 if (pKeyPress->IsConstrain() && !pKeyPress->IsAdjust() )
01523 {
01524 UsedTheKeypress = TRUE;
01525 Errored = IsNonCharEvent ? !DecreaseTrackKern() : FALSE;
01526 }
01527 break;
01528 case CAMKEY(RETURN):
01529
01530 if (!pKeyPress->IsAlternative() && !pKeyPress->IsConstrain())
01531 {
01532 if (IsNonCharEvent)
01533 {
01534 OpTextFormat* pOp = new OpTextFormat();
01535 if (pOp != NULL)
01536 Errored = !pOp->DoReturn(OpTextFormat::INSERT);
01537 else
01538 Errored = TRUE;
01539 }
01540 UsedTheKeypress = TRUE;
01541 }
01542 break;
01543 case CAMKEY(TAB):
01544 if (!pKeyPress->IsAlternative() && !pKeyPress->IsConstrain())
01545 {
01546 if (IsNonCharEvent)
01547 {
01548
01549 OpTextFormat* pOp = new OpTextFormat();
01550 if (pOp != NULL)
01551 Errored = !pOp->DoTab();
01552 else
01553 Errored = TRUE;
01554 }
01555 UsedTheKeypress = TRUE;
01556 }
01557 break;
01558 case CAMKEY(ESCAPE):
01559
01560 if (!pKeyPress->IsAlternative() && !pKeyPress->IsConstrain())
01561 {
01562 if (IsNonCharEvent)
01563 {
01564 pCaret->DeSelect(TRUE);
01565 pStory->Select(TRUE);
01566 GetApplication()->FindSelection()->Update(TRUE);
01567 }
01568 UsedTheKeypress = TRUE;
01569
01570
01571 Errored = IsNonCharEvent ? !OpDeleteTextStory::RemoveEmptyFocusStory() : FALSE;
01572 }
01573 break;
01574 }
01575
01576 if (Errored)
01577 InformError();
01578
01579 return UsedTheKeypress;
01580 }
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600 void TextTool::DisplayStatusBarHelp(DocCoord DocPos, Spread* pSpread, ClickModifiers ClickMods)
01601 {
01602 String_256 StatusMsg("");
01603
01604
01605 GetCurrentStatusText(&StatusMsg, pSpread, DocPos, ClickMods);
01606 GetApplication()->UpdateStatusBarText(&StatusMsg);
01607 }
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628 BOOL TextTool::GetStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods)
01629 {
01630
01631 GetCurrentStatusText(ptext, pSpread, DocPos, ClickMods);
01632 return TRUE;
01633 }
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654 void TextTool::GetCurrentStatusText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods)
01655 {
01656
01657 INT32 IDToUse = _R(IDS_TEXTTOOL_OVERDOCUMENT);
01658
01659
01660 if (TextStory::GetFocusStory()!=NULL && TextStory::GetFocusStory()->GetCaret()!=NULL
01661 && TextStory::GetFocusStory()->GetCaret()->IsSelected())
01662 {
01663 IDToUse = _R(IDS_TEXTTOOL_OVERDOCUMENTC);
01664 }
01665
01666
01667 TextStory* pTextStoryToSelect = NULL;
01668 if (IsPointNearUnselectedTextStory(pSpread, DocPos, &pTextStoryToSelect, NULL, TRUE))
01669 {
01670 if (pTextStoryToSelect != NULL)
01671 IDToUse = _R(IDS_TEXTTOOL_OVERTEXTSTORY);
01672 }
01673 else
01674 {
01675 NodePath* pPath = NULL;
01676 if (IsPointNearNonStoryPath(pSpread, DocPos, &pPath, TRUE))
01677 IDToUse = _R(IDS_TEXTTOOL_OVERNODEPATH);
01678 }
01679
01680
01681 BOOL LeftBlob = TRUE;
01682 TextStory* pFoundStory = NULL;
01683 if (!m_BlobPosList.FindBlobStory(pSpread, DocPos, &LeftBlob, &pFoundStory))
01684 InformError();
01685 else if (pFoundStory != NULL)
01686 {
01687 if (pFoundStory->GetTextPath() != NULL)
01688 IDToUse = _R(IDS_TEXTTOOL_DRAGPATHINDENT);
01689 else
01690 IDToUse = _R(IDS_TEXTTOOL_DRAGSTORYWIDTH);
01691 }
01692
01693 ptext->Load(IDToUse);
01694 }
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709 BOOL TextTool::ApplyBold()
01710 {
01711 AttrTxtBold* ApplyBoldAttrib = new AttrTxtBold();
01712 BOOL Success = ApplyBoldAttrib != NULL;
01713
01714 if (Success)
01715 {
01716
01717 AttrTxtBold* CurrentBoldAttrib = NULL;
01718 SelRange::CommonAttribResult AttrRes = GetApplication()->FindSelection()->
01719 FindCommonAttribute(CC_RUNTIME_CLASS(AttrTxtBold), (NodeAttribute **)&CurrentBoldAttrib);
01720 if (AttrRes == SelRange::ATTR_COMMON)
01721 ApplyBoldAttrib->Value.BoldOn = !(CurrentBoldAttrib->Value.BoldOn);
01722 else
01723 ApplyBoldAttrib->Value.BoldOn = TRUE;
01724
01725
01726 AttributeManager::AttributeSelected(ApplyBoldAttrib, NULL);
01727 }
01728
01729 return Success;
01730 }
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745 BOOL TextTool::ApplyItalic()
01746 {
01747 AttrTxtItalic* ApplyItalicAttrib = new AttrTxtItalic();
01748 BOOL Success = ApplyItalicAttrib != NULL;
01749
01750 if (Success)
01751 {
01752
01753 AttrTxtItalic* CurrentItalicAttrib = NULL;
01754 SelRange::CommonAttribResult AttrRes = GetApplication()->FindSelection()->
01755 FindCommonAttribute(CC_RUNTIME_CLASS(AttrTxtItalic), (NodeAttribute **)&CurrentItalicAttrib);
01756 if (AttrRes == SelRange::ATTR_COMMON)
01757 ApplyItalicAttrib->Value.ItalicOn = !(CurrentItalicAttrib->Value.ItalicOn);
01758 else
01759 ApplyItalicAttrib->Value.ItalicOn = TRUE;
01760
01761
01762 AttributeManager::AttributeSelected(ApplyItalicAttrib, NULL);
01763 }
01764
01765 return Success;
01766 }
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783 BOOL TextTool::IncreaseTrackKern()
01784 {
01785
01786 TextStory* pStory = TextStory::GetFocusStory();
01787 ERROR3IF(pStory == NULL, "IncreaseTrackKern called without a focus story!");
01788 BOOL Success = TRUE;
01789
01790 if (pStory != NULL)
01791 {
01792 if (pStory->GetSelectionEnd() == NULL)
01793 Success = CommonApplyKern(50);
01794 else
01795 Success = CommonApplyTracking(10);
01796 }
01797
01798 return Success;
01799 }
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816 BOOL TextTool::DecreaseTrackKern()
01817 {
01818
01819 TextStory* pStory = TextStory::GetFocusStory();
01820 ERROR3IF(pStory == NULL, "DecreaseTrackKern called without a focus story!");
01821 BOOL Success = TRUE;
01822
01823 if (pStory != NULL)
01824 {
01825 if (pStory->GetSelectionEnd() == NULL)
01826 Success = CommonApplyKern(-50);
01827 else
01828 Success = CommonApplyTracking(-10);
01829 }
01830
01831 return Success;
01832 }
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847 BOOL TextTool::CommonApplyTracking(MILLIPOINT ChangeAmmount)
01848 {
01849
01850 AttrTxtTracking* ApplyTrackingAttrib = new AttrTxtTracking();
01851 BOOL Success = (ApplyTrackingAttrib != NULL);
01852
01853 if (Success)
01854 {
01855
01856 AttrTxtTracking* CurrentTrackingAttrib = NULL;
01857 SelRange::CommonAttribResult AttrRes = GetApplication()->FindSelection()->
01858 FindCommonAttribute(CC_RUNTIME_CLASS(AttrTxtTracking), (NodeAttribute **)&CurrentTrackingAttrib);
01859 if (AttrRes == SelRange::ATTR_COMMON)
01860 ApplyTrackingAttrib->Value.Tracking = CurrentTrackingAttrib->Value.Tracking + ChangeAmmount;
01861 else
01862 ApplyTrackingAttrib->Value.Tracking = ChangeAmmount;
01863
01864
01865 AttributeManager::AttributeSelected(ApplyTrackingAttrib, NULL);
01866 }
01867
01868 return Success;
01869 }
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884 BOOL TextTool::CommonApplyKern(MILLIPOINT ChangeAmmount)
01885 {
01886 MILLIPOINT NewKernVal = ChangeAmmount;
01887
01888
01889 TextStory* pStory = TextStory::GetFocusStory();
01890 CaretNode* pCaret = NULL;
01891 if (pStory != NULL)
01892 pCaret = pStory->GetCaret();
01893 if (pCaret != NULL)
01894 {
01895 VisibleTextNode* LastNode = pCaret->FindPrevAbstractTextCharInStory();
01896 if ((LastNode != NULL) && IS_A(LastNode, KernCode))
01897 NewKernVal += (((KernCode*)LastNode)->GetValue()).x;
01898 }
01899
01900
01901 OpDescriptor* OpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpTextKern));
01902 if (OpDesc != NULL)
01903 {
01904 OpParam param(NewKernVal,0);
01905 OpDesc->Invoke(¶m);
01906 }
01907
01908 return TRUE;
01909 }
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924 BOOL TextTool::OnIdle()
01925 {
01926 if (UpdateAfterTyping)
01927 {
01928 if (!pTextInfoBarOp->UpdateFieldsAfterTyping())
01929 InformError();
01930 UpdateAfterTyping = FALSE;
01931 }
01932
01933 return FALSE;
01934 }
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950 BOOL TextTool::DelayingUpdate()
01951 {
01952
01953 Tool* pTool = Tool::GetCurrent();
01954 if (!pTool || pTool->GetID() != TOOLID_TEXT) return FALSE;
01955
01956
01957 return ((TextTool*) pTool)->UpdateAfterTyping;
01958 }
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973 BOOL TextTool::RegisterDeadKeys()
01974 {
01975 BOOL ok = TRUE;
01976
01977 if (UseDeadKeys)
01978 {
01979 if (ok)
01980 ok = RegisterAdditionalVirtKey(&GraveVirtKey, (TCHAR)('`'));
01981 if (ok)
01982 ok = RegisterAdditionalVirtKey(&AcuteVirtKey, (TCHAR)0x27);
01983 if (ok)
01984 ok = RegisterAdditionalVirtKey(&TildeVirtKey, (TCHAR)('~'));
01985 if (ok)
01986 ok = RegisterAdditionalVirtKey(&HatVirtKey, (TCHAR)('^'));
01987 if (ok)
01988 ok = RegisterAdditionalVirtKey(&ColonVirtKey, (TCHAR)(':'));
01989 if (ok)
01990 ok = RegisterAdditionalVirtKey(&AtVirtKey, (TCHAR)('@'));
01991 if (ok)
01992 ok = RegisterAdditionalVirtKey(&CommaVirtKey, (TCHAR)(','));
01993 if (ok)
01994 ok = RegisterAdditionalVirtKey(&SlashVirtKey, (TCHAR)('/'));
01995 }
01996
01997 return ok;
01998 }
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013 BOOL TextTool::RemoveDeadKeys()
02014 {
02015 if (GraveVirtKey != NULL)
02016 {
02017 KeyPress::RemoveVirtualKeyCode(GraveVirtKey->GetVirtKey(), GraveVirtKey->GetUnicode());
02018 delete GraveVirtKey;
02019 }
02020 if (AcuteVirtKey != NULL)
02021 {
02022 KeyPress::RemoveVirtualKeyCode(AcuteVirtKey->GetVirtKey(), AcuteVirtKey->GetUnicode());
02023 delete AcuteVirtKey;
02024 }
02025 if (TildeVirtKey != NULL)
02026 {
02027 KeyPress::RemoveVirtualKeyCode(TildeVirtKey->GetVirtKey(), TildeVirtKey->GetUnicode());
02028 delete TildeVirtKey;
02029 }
02030 if (HatVirtKey != NULL)
02031 {
02032 KeyPress::RemoveVirtualKeyCode(HatVirtKey->GetVirtKey(), HatVirtKey->GetUnicode());
02033 delete HatVirtKey;
02034 }
02035 if (ColonVirtKey != NULL)
02036 {
02037 KeyPress::RemoveVirtualKeyCode(ColonVirtKey->GetVirtKey(), ColonVirtKey->GetUnicode());
02038 delete ColonVirtKey;
02039 }
02040 if (AtVirtKey != NULL)
02041 {
02042 KeyPress::RemoveVirtualKeyCode(AtVirtKey->GetVirtKey(), AtVirtKey->GetUnicode());
02043 delete AtVirtKey;
02044 }
02045 if (CommaVirtKey != NULL)
02046 {
02047 KeyPress::RemoveVirtualKeyCode(CommaVirtKey->GetVirtKey(), CommaVirtKey->GetUnicode());
02048 delete CommaVirtKey;
02049 }
02050 if (SlashVirtKey != NULL)
02051 {
02052 KeyPress::RemoveVirtualKeyCode(SlashVirtKey->GetVirtKey(), SlashVirtKey->GetUnicode());
02053 delete SlashVirtKey;
02054 }
02055
02056 return TRUE;
02057 }
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074 BOOL TextTool::RegisterAdditionalVirtKey(KeyPress** pKey, TCHAR ch)
02075 {
02076 BOOL ok = TRUE;
02077
02078 *pKey = KeyPress::ConstructVK(ch);
02079 ok = (*pKey != NULL);
02080 if (ok)
02081 ok = KeyPress::AddVirtualKeyCode((*pKey)->GetVirtKey(), (*pKey)->GetUnicode());
02082
02083 return ok;
02084 }
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098 BOOL TextTool::HandleDeadKeys(KeyPress* pKeyPress, WCHAR* pNewUnicode)
02099 {
02100 BOOL UsedKey = FALSE;
02101 *pNewUnicode = pKeyPress->GetUnicode();
02102
02103
02104 if (!UseDeadKeys)
02105 return FALSE;
02106
02107
02108 if ( TestForDeadKey(pKeyPress, GraveVirtKey) ||
02109 TestForDeadKey(pKeyPress, AcuteVirtKey) ||
02110 TestForDeadKey(pKeyPress, HatVirtKey) ||
02111 TestForDeadKey(pKeyPress, TildeVirtKey) ||
02112 TestForDeadKey(pKeyPress, ColonVirtKey) ||
02113 TestForDeadKey(pKeyPress, AtVirtKey) ||
02114 TestForDeadKey(pKeyPress, SlashVirtKey) ||
02115 TestForDeadKey(pKeyPress, CommaVirtKey) )
02116 {
02117 UsedKey = TRUE;
02118 }
02119
02120
02121 if (!UsedKey && (PreviousDeadKey != NULL) && IsUsableUnicode(pKeyPress->GetUnicode()) )
02122 {
02123
02124 UINT32* pMapArrays = NULL;
02125 if (PreviousDeadKey == GraveVirtKey)
02126 pMapArrays = GraveArray;
02127 else if (PreviousDeadKey == AcuteVirtKey)
02128 pMapArrays = AcuteArray;
02129 else if (PreviousDeadKey == HatVirtKey)
02130 pMapArrays = HatArray;
02131 else if (PreviousDeadKey == TildeVirtKey)
02132 pMapArrays = TildeArray;
02133 else if (PreviousDeadKey == ColonVirtKey)
02134 pMapArrays = ColonArray;
02135 else if (PreviousDeadKey == AtVirtKey)
02136 pMapArrays = AtArray;
02137 else if (PreviousDeadKey == SlashVirtKey)
02138 pMapArrays = SlashArray;
02139 else if (PreviousDeadKey == CommaVirtKey)
02140 pMapArrays = CommaArray;
02141 else
02142 {
02143 ERROR3("Unknown dead key");
02144 pMapArrays = NULL;
02145 }
02146
02147
02148 if (pMapArrays != NULL)
02149 {
02150 BOOL Found = FALSE;
02151 while (!Found && (*pMapArrays != 0))
02152 {
02153 if (*pMapArrays == (UINT32)(*pNewUnicode))
02154 {
02155 *pNewUnicode = *(pMapArrays+1);
02156 Found = TRUE;
02157 }
02158 pMapArrays += 2;
02159 }
02160 }
02161
02162 PreviousDeadKey = 0;
02163 UsedKey = FALSE;
02164 }
02165
02166 return UsedKey;
02167 }
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182 BOOL TextTool::TestForDeadKey(KeyPress* pKeyPress, KeyPress* pDeadKeyPress)
02183 {
02184 if ( pDeadKeyPress != NULL &&
02185 pDeadKeyPress->GetVirtKey() != CAMKEY(CC_NONE) &&
02186 !pDeadKeyPress->IsConstrain() &&
02187 pKeyPress->IsConstrain() &&
02188 pDeadKeyPress->IsAdjust() == pKeyPress->IsAdjust() &&
02189 pDeadKeyPress->IsAlternative() == pKeyPress->IsAlternative() &&
02190 pDeadKeyPress->GetVirtKey() == pKeyPress->GetVirtKey()
02191 )
02192 {
02193 PreviousDeadKey = pDeadKeyPress;
02194 return TRUE;
02195 }
02196 else
02197 return FALSE;
02198 }
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212 BOOL TextTool::IsUsableUnicode(WCHAR CodeValue)
02213 {
02214 return ( ((CodeValue>=32) && (CodeValue<=126)) || ((CodeValue>=128) && (CodeValue<=255)) );
02215 }
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230 void TextTool::LocaleChanged()
02231 {
02232 RemoveDeadKeys();
02233 if (!RegisterDeadKeys())
02234 InformError();
02235 }
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249 BOOL TextTool::OnToolSelect()
02250 {
02251 BOOL ok = TRUE;
02252
02253
02254 ok = CreateCursors();
02255 if (ok)
02256 {
02257 CurrentCursorID = CursorStack::GPush(pcNormalTextCursor, FALSE);
02258 pcCurrentCursor = pcNormalTextCursor;
02259 IsBlankCursorUp = FALSE;
02260 }
02261 else
02262 pcCurrentCursor = NULL;
02263
02264
02265 CurrentTool = TRUE;
02266 UpdateAfterTyping = FALSE;
02267 PreviousDeadKey = 0;
02268
02269
02270 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
02271 if (BlobMgr != NULL)
02272 {
02273
02274 BlobStyle MyBlobs;
02275 MyBlobs.Object = TRUE;
02276
02277
02278 BlobMgr->ToolInterest(MyBlobs);
02279 }
02280
02281
02282 if (ok)
02283 ok = m_BlobPosList.BuildFromSelection();
02284 if (ok && m_BlobPosList.GetBlobSpread()!=NULL)
02285 BlobMgr->RenderToolBlobsOn(this, m_BlobPosList.GetBlobSpread(), NULL);
02286
02287
02288 if (ok)
02289 ok = pTextInfoBarOp->Create();
02290 pTextInfoBarOp->pTextTool = this;
02291
02292
02293 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_PASTE);
02294 pOpDesc->AliasOperation(CC_RUNTIME_CLASS(OpTextPaste),NULL,0);
02295
02296
02297 LocaleChanged();
02298
02299
02300 SelRange* pSelRange = GetApplication()->FindSelection();
02301 Node* pSel = pSelRange->FindFirst();
02302
02303 TextStory* pSelStory = NULL;
02304 while (pSel != NULL)
02305 {
02306
02307 TextStory* pParentStory = NULL;
02308 if (pSel->IsABaseTextClass())
02309 {
02310 if (IS_A(pSel,TextStory))
02311 pParentStory = (TextStory*)pSel;
02312 else
02313 pParentStory = (TextStory*)pSel->FindParent(CC_RUNTIME_CLASS(TextStory));
02314 }
02315
02316 if (pSelStory==NULL)
02317 {
02318
02319 if (pSel->IsAVisibleTextNode())
02320 pSelStory = pParentStory;
02321 }
02322 else
02323 {
02324
02325 if (pSelStory!=pParentStory)
02326 {
02327 pSelStory = NULL;
02328 break;
02329 }
02330 }
02331
02332 pSel = pSelRange->FindNext(pSel);
02333 }
02334 if (pSelStory != NULL)
02335 TextStory::SetFocusStory(pSelStory);
02336
02337
02338
02339 if ((pLastFocusStory!= NULL) && (pSelStory==NULL) && (GetApplication()->FindSelection()->Count()==1))
02340 {
02341 Node* pSelected = GetApplication()->FindSelection()->FindFirst();
02342 if (IS_A(pSelected,TextStory) && (pSelected == pLastFocusStory))
02343 {
02344 TextStory* pTS = (TextStory*)pSelected;
02345 CaretNode* pCaret = pTS->GetCaret();
02346 if (pCaret != NULL)
02347 {
02348 pTS->DeSelect(TRUE);
02349 pCaret->Select(TRUE);
02350 TextStory::SetFocusStory(pTS);
02351 GetApplication()->FindSelection()->Update(TRUE);
02352 }
02353 }
02354 }
02355
02356 return ok;
02357 }
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371 BOOL TextTool::OnToolDeselect()
02372 {
02373 BOOL ok = TRUE;
02374
02375
02376 pTextInfoBarOp->Delete();
02377
02378
02379 if (pcCurrentCursor != NULL)
02380 {
02381 CursorStack::GPop(CurrentCursorID);
02382 pcCurrentCursor = NULL;
02383 CurrentCursorID = 0;
02384 }
02385 DestroyCursors();
02386
02387
02388 GetApplication()->FindSelection()->SetGag(FALSE);
02389 TextStory* pTS = TextStory::GetFocusStory();
02390 if (pTS != NULL)
02391 {
02392
02393
02394 CaretNode* pCaret = pTS->GetCaret();
02395 VisibleTextNode* pSel = pTS->GetSelectionEnd();
02396 if (pCaret->IsSelected() && pSel==NULL)
02397 {
02398 pCaret->DeSelect(TRUE);
02399 pTS->Select(TRUE);
02400 GetApplication()->FindSelection()->Update(TRUE);
02401 }
02402
02403 ok = OpDeleteTextStory::RemoveEmptyFocusStory();
02404 }
02405
02406
02407 if (m_BlobPosList.GetBlobSpread()!=NULL)
02408 m_BlobPosList.RenderAndRemoveAll();
02409
02410
02411 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
02412 if (BlobMgr != NULL)
02413 {
02414 BlobStyle bsRemoves;
02415 bsRemoves.ToolObject = TRUE;
02416 BlobMgr->RemoveInterest(bsRemoves);
02417 }
02418
02419
02420 pLastFocusStory = TextStory::GetFocusStory();
02421 TextStory::SetFocusStory(NULL);
02422
02423
02424 TextInfoBarOp::ReleaseRuler();
02425 CurrentTool = FALSE;
02426
02427 return ok;
02428 }
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443 void TextTool::RenderToolBlobs(Spread* pSpread, DocRect* pClipRect)
02444 {
02445 m_BlobPosList.RenderAllBlobs(pSpread, pClipRect);
02446
02447
02448
02449
02450
02451 }
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465 BOOL TextTool::SelectionHasChanged()
02466 {
02467 BOOL ok = TRUE;
02468
02469
02470 if (ok)
02471 ok = m_BlobPosList.RenderAllBlobs();
02472
02473
02474 if (ok)
02475 ok = m_BlobPosList.BuildFromSelection();
02476
02477
02478 if (ok)
02479 ok = m_BlobPosList.RenderAllBlobs();
02480
02481 return ok;
02482 }
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521 TextToolBlobPosItem::TextToolBlobPosItem(DocCoord Left, DocCoord Right, BOOL Connected, TextStory* pStory)
02522 {
02523 ERROR3IF(pStory==NULL, "NULL story pointer");
02524
02525 m_LeftBlobPos = Left;
02526 m_RightBlobPos = Right;
02527 m_pTextStory = pStory;
02528 m_BlobsConnected = Connected;
02529 }
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543 TextToolBlobPosItem::~TextToolBlobPosItem()
02544 {
02545
02546 }
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563 TextToolBlobPosList::TextToolBlobPosList()
02564 {
02565 m_pSelSpread = NULL;
02566 }
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580 TextToolBlobPosList::~TextToolBlobPosList()
02581 {
02582 DeleteAll();
02583 }
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597 BOOL TextToolBlobPosList::BuildFromSelection()
02598 {
02599
02600 DeleteAll();
02601 m_pSelSpread = NULL;
02602
02603
02604 SelRange* pSel = GetApplication()->FindSelection();
02605 Node* pCurrent = pSel->FindFirst();
02606 TextStory* pLastSelStory = NULL;
02607 while (pCurrent!=NULL)
02608 {
02609
02610 if (pCurrent->IsABaseTextClass())
02611 {
02612 TextStory* pCurrentStory = ((BaseTextClass*)pCurrent)->FindParentStory();
02613
02614 if (pCurrentStory!=NULL && pCurrentStory!=pLastSelStory && pCurrentStory->IsWordWrapping())
02615 {
02616 DocCoord LeftBlob;
02617 DocCoord RightBlob;
02618
02619 if (pCurrentStory->GetTextPath() != NULL)
02620 {
02621 LeftBlob = pCurrentStory->GetLeftIndentPos();
02622 RightBlob = pCurrentStory->GetRightIndentPos();
02623 }
02624 else
02625 {
02626 const Matrix* pStoryMat = pCurrentStory->GetpStoryMatrix();
02627 LeftBlob = DocCoord(0,0);
02628 RightBlob = DocCoord(pCurrentStory->GetStoryWidth(),0);
02629 pStoryMat->transform(&LeftBlob);
02630 pStoryMat->transform(&RightBlob);
02631 }
02632
02633 Spread* pSpread = pCurrentStory->FindParentSpread();
02634
02635
02636 ERROR3IF(pSpread==NULL, "Story didn't have a parent spread!");
02637 if (pSpread!=NULL)
02638 {
02639
02640 TextToolBlobPosItem* pNewItem = new TextToolBlobPosItem(LeftBlob, RightBlob, (pCurrentStory->GetTextPath()==NULL), pCurrentStory);
02641 if (pNewItem==NULL)
02642 return FALSE;
02643
02644
02645 AddTail(pNewItem);
02646
02647
02648 ERROR3IF(m_pSelSpread!=NULL && m_pSelSpread!=pSpread, "Selection crosses spreads! Text tool blobs wont work!");
02649 m_pSelSpread = pSpread;
02650 }
02651
02652 pLastSelStory = pCurrentStory;
02653 }
02654 }
02655
02656 pCurrent = pSel->FindNext(pCurrent);
02657 }
02658
02659 return TRUE;
02660 }
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675 BOOL TextToolBlobPosList::RenderAllBlobs(Spread* pSpread, DocRect* pClipRect)
02676 {
02677 TextToolBlobPosItem* pItem = (TextToolBlobPosItem*) GetHead();
02678
02679
02680 if (pSpread==NULL)
02681 pSpread = m_pSelSpread;
02682 if (m_pSelSpread!=pSpread)
02683 return TRUE;
02684
02685 while (pItem!=NULL)
02686 {
02687 RenderBlobPair(pSpread, pClipRect, pItem);
02688
02689 pItem = (TextToolBlobPosItem*) GetNext(pItem);
02690 }
02691
02692 return TRUE;
02693 }
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709 void TextToolBlobPosList::RenderBlobPair(Spread* pSpread, DocRect* pClipRect, TextToolBlobPosItem* pPair)
02710 {
02711 ERROR3IF(pPair==NULL, "NULL pointer");
02712
02713 if (pPair!=NULL)
02714 {
02715
02716
02717 RenderRegion* pRegion = DocView::RenderOnTop(pClipRect, pSpread, ClippedEOR);
02718 while (pRegion != NULL)
02719 {
02720
02721 pRegion->SetLineColour(COLOUR_NONE);
02722 pRegion->SetFillColour(COLOUR_BEZIERBLOB);
02723 pRegion->DrawBlob(pPair->GetLeftBlobPos(), BT_UNSELECTED);
02724 pRegion->DrawBlob(pPair->GetRightBlobPos(), BT_UNSELECTED);
02725
02726
02727 if (pPair->IsConnected())
02728 {
02729 pRegion->SetLineColour(COLOUR_BEZIERBLOB);
02730 pRegion->DrawLine(pPair->GetLeftBlobPos(), pPair->GetRightBlobPos());
02731 }
02732
02733
02734 pRegion = DocView::GetNextOnTop(pClipRect);
02735 }
02736 }
02737 }
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753 void TextToolBlobPosList::RenderBlob(Spread* pSpread, DocRect* pClipRect, DocCoord BlobPos)
02754 {
02755 RenderRegion* pRegion = DocView::RenderOnTop(pClipRect, pSpread, ClippedEOR);
02756 while (pRegion != NULL)
02757 {
02758
02759 pRegion->SetLineColour(COLOUR_NONE);
02760 pRegion->SetFillColour(COLOUR_BEZIERBLOB);
02761 pRegion->DrawBlob(BlobPos, BT_UNSELECTED);
02762
02763
02764 pRegion = DocView::GetNextOnTop(pClipRect);
02765 }
02766 }
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782 BOOL TextToolBlobPosList::FindBlobStory(Spread* pSpread, DocCoord PointerPos, BOOL* pLeft, TextStory** pStory)
02783 {
02784
02785 ERROR2IF(pSpread!=m_pSelSpread && m_pSelSpread!=NULL, FALSE, "Different spreads");
02786 ERROR2IF(pStory==NULL, FALSE, "NULL output parameter");
02787
02788
02789 TextToolBlobPosItem* pItem = (TextToolBlobPosItem*) GetTail();
02790 while (pItem!=NULL)
02791 {
02792
02793 DocRect BlobBounds;
02794 DocCoord BlobPos = pItem->GetLeftBlobPos();
02795 GetApplication()->GetBlobManager()->GetBlobRect(BlobPos, &BlobBounds);
02796 if (BlobBounds.ContainsCoord(PointerPos))
02797 {
02798 if (pLeft!=NULL)
02799 *pLeft = TRUE;
02800 *pStory = pItem->GetBlobStory();
02801
02802 return TRUE;
02803 }
02804
02805
02806 BlobPos = pItem->GetRightBlobPos();
02807 GetApplication()->GetBlobManager()->GetBlobRect(BlobPos, &BlobBounds);
02808 if (BlobBounds.ContainsCoord(PointerPos))
02809 {
02810 if (pLeft!=NULL)
02811 *pLeft = FALSE;
02812 *pStory = pItem->GetBlobStory();
02813
02814 return TRUE;
02815 }
02816
02817 pItem = (TextToolBlobPosItem*) GetPrev(pItem);
02818 }
02819
02820 return TRUE;
02821 }
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836 BOOL TextToolBlobPosList::RenderAndRemove(TextStory* pStory)
02837 {
02838 ERROR2IF(pStory==NULL, FALSE, "NULL story pointer");
02839
02840
02841 TextToolBlobPosItem* pItem = (TextToolBlobPosItem*) GetHead();
02842 while (pItem!=NULL)
02843 {
02844 if (pItem->GetBlobStory() == pStory)
02845 {
02846
02847 RenderBlobPair(m_pSelSpread, NULL, pItem);
02848
02849
02850 RemoveItem(pItem);
02851 delete pItem;
02852
02853 return TRUE;
02854 }
02855 else
02856 pItem = (TextToolBlobPosItem*) GetNext(pItem);
02857 }
02858
02859 ERROR3("Story not found");
02860
02861 return TRUE;
02862 }
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876 void TextToolBlobPosList::RenderAndRemoveAll()
02877 {
02878
02879 TextToolBlobPosItem* pItem = (TextToolBlobPosItem*) RemoveHead();
02880 while (pItem!=NULL)
02881 {
02882
02883 RenderBlobPair(m_pSelSpread, NULL, pItem);
02884
02885
02886 delete pItem;
02887
02888 pItem = (TextToolBlobPosItem*) RemoveHead();
02889 }
02890 }
02891
02892
02893