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
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 #include "camtypes.h"
00116 #include "textops.h"
00117
00118 #include "dlgmgr.h"
00119
00120
00121
00122
00123
00124
00125 #include "blobs.h"
00126 #include "clipint.h"
00127
00128
00129 #include "invalid.h"
00130 #include "layer.h"
00131 #include "nodetext.h"
00132 #include "nodetxtl.h"
00133 #include "nodetxts.h"
00134 #include "objchge.h"
00135
00136
00137 #include "progress.h"
00138 #include "textacts.h"
00139 #include "textfuns.h"
00140 #include "textinfo.h"
00141 #include "texttool.h"
00142
00143
00144
00145
00146 #include "ndtxtpth.h"
00147 #include "cutop.h"
00148
00149 #include "fontman.h"
00150
00151 #include "bubbleid.h"
00152
00153 #include "slicehelper.h"
00154
00155 #include "opliveeffects.h"
00156 #include "ophist.h"
00157 #include "nodedoc.h"
00158 #include "nodepath.h"
00159
00160 extern void Beep();
00161
00162 DECLARE_SOURCE( "$Revision: 1446 $" );
00163
00164
00165
00166 #if !defined(EXCLUDE_FROM_RALPH)
00167
00168 CC_IMPLEMENT_DYNCREATE(OpTextUndoable, SelOperation)
00169
00170
00171 CC_IMPLEMENT_DYNCREATE(OpDeleteTextStory, SelOperation)
00172 CC_IMPLEMENT_DYNCREATE(OpCreateTextObject, OpTextUndoable)
00173 CC_IMPLEMENT_DYNCREATE(OpTextFormat, OpTextUndoable)
00174 CC_IMPLEMENT_DYNCREATE(OpFitTextToCurve, OpTextUndoable)
00175 CC_IMPLEMENT_DYNCREATE(OpTextKern, OpTextUndoable)
00176 CC_IMPLEMENT_DYNCREATE(OpTextAutoKern, OpTextUndoable)
00177 CC_IMPLEMENT_DYNCREATE(OpReverseStoryPath, OpTextUndoable)
00178
00179
00180 CC_IMPLEMENT_DYNAMIC(OpDragStoryIndent, OpTextUndoable)
00181 CC_IMPLEMENT_DYNAMIC(OpDragStoryPathIndent, OpDragStoryIndent)
00182 CC_IMPLEMENT_DYNAMIC(OpDragStoryNonPathIndent, OpDragStoryIndent)
00183 CC_IMPLEMENT_DYNCREATE(OpDragStoryPathLeftIndent, OpDragStoryPathIndent)
00184 CC_IMPLEMENT_DYNCREATE(OpDragStoryPathRightIndent, OpDragStoryPathIndent)
00185 CC_IMPLEMENT_DYNCREATE(OpDragStoryNonPathLeftIndent, OpDragStoryNonPathIndent)
00186 CC_IMPLEMENT_DYNCREATE(OpDragStoryNonPathRightIndent, OpDragStoryNonPathIndent)
00187
00188 CC_IMPLEMENT_DYNCREATE(OpTextPaste, OpPaste)
00189 CC_IMPLEMENT_DYNCREATE(OpTogglePrintTextAsShapes, Operation)
00190 CC_IMPLEMENT_DYNCREATE(OpTextCaret, Operation)
00191 CC_IMPLEMENT_DYNCREATE(OpTextSelection, Operation)
00192 #endif
00193 CC_IMPLEMENT_DYNCREATE(OpApplyGlobalAffect, Operation)
00194 #if !defined(EXCLUDE_FROM_RALPH)
00195 CC_IMPLEMENT_DYNCREATE(OpApplyJustificationToStory, Operation)
00196 CC_IMPLEMENT_DYNCREATE(OpApplyLeftJustifyToStory, OpApplyJustificationToStory)
00197 CC_IMPLEMENT_DYNCREATE(OpApplyCentreJustifyToStory, OpApplyJustificationToStory)
00198 CC_IMPLEMENT_DYNCREATE(OpApplyRightJustifyToStory, OpApplyJustificationToStory)
00199 CC_IMPLEMENT_DYNCREATE(OpApplyFullJustifyToStory, OpApplyJustificationToStory)
00200 #endif
00201 CC_IMPLEMENT_DYNCREATE(OpAffectFontChange, OpApplyGlobalAffect)
00202
00203 CC_IMPLEMENT_DYNCREATE(PrePostTextAction, Action)
00204 CC_IMPLEMENT_DYNCREATE(ToggleAutoKerningAction, Action)
00205 #if !defined(EXCLUDE_FROM_RALPH)
00206 CC_IMPLEMENT_DYNCREATE(PositionCaretAction, Action)
00207 CC_IMPLEMENT_DYNCREATE(StorePathIndentAction, Action)
00208 #endif
00209
00210
00211 #define new CAM_DEBUG_NEW
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 #define SELECT_CARET_AND_CHARS
00223
00224 #if !defined(EXCLUDE_FROM_RALPH)
00225
00226 VerticalInsetStore OpTextCaret::VertInset;
00227
00228
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 OpTextUndoable::OpTextUndoable()
00241 {
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 BOOL OpTextUndoable::DoStartTextOp(TextStory* pTxtStory, BOOL StartBlobs, BOOL EndBlobs)
00260 {
00261
00262
00263
00264 return DoStartSelOp(StartBlobs, EndBlobs);
00265 }
00266
00267
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 OpCreateTextObject::OpCreateTextObject()
00280 {
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 void OpCreateTextObject::DoImmediate( Spread* pSpread, DocCoord Anchor, NodePath* pPath,
00302 ClickModifiers ClickMods, DocCoord StoryWidth)
00303 {
00304
00305 DocView::SnapCurrent(pSpread, &Anchor);
00306
00307
00308 TextStory* pTextStory = NULL;
00309 ALLOC_WITH_FAIL(pTextStory, (TextStory::CreateTextObject(Anchor)), this);
00310 BOOL ok = (pTextStory != NULL);
00311
00312
00313 if (ok && pPath==NULL && StoryWidth!=DocCoord(MinDocCoord,MinDocCoord))
00314 {
00315
00316 pTextStory->SetWordWrapping(TRUE);
00317 pTextStory->SetStoryWidth((MILLIPOINT)Anchor.Distance(StoryWidth));
00318
00319
00320 double StoryRot = atan2((double)StoryWidth.y-Anchor.y, (double)StoryWidth.x-Anchor.x)*(180/PI);
00321
00322
00323 Trans2DMatrix StoryRotMat(Matrix(Anchor, StoryRot));
00324 pTextStory->Transform(StoryRotMat);
00325 }
00326
00327
00328 if (ok)
00329 ok = DoStartSelOp(FALSE, TRUE, TRUE, FALSE);
00330
00331
00332 if (ok)
00333 ok = OpDeleteTextStory::RemoveEmptyFocusStory(this);
00334
00335
00336 if (ok)
00337 ok = pOurDoc->GetAttributeMgr().ApplyCurrentAttribsToNode((NodeRenderableInk*)pTextStory);
00338
00339
00340 if (ok)
00341 {
00342 if (pPath == NULL)
00343 ok = DoInsertNewNode(pTextStory, pSpread, FALSE, TRUE, FALSE);
00344 else
00345 ok = DoInsertNewNode(pTextStory, pPath, NEXT, FALSE, TRUE, FALSE);
00346 }
00347
00348
00349 if (ok && pPath!=NULL)
00350 {
00351
00352 MILLIPOINT KernDist = 0;
00353 if (!ClickMods.Constrain)
00354 {
00355 double dist = 0.0;
00356 ok = pPath->InkPath.DistanceTo(Anchor, &dist);
00357 if (ok)
00358 KernDist = (MILLIPOINT)dist;
00359 }
00360
00361
00362 BOOL PathIsClosed = pPath->InkPath.IsSubPathClosed(pPath->InkPath.GetNumCoords()-1);
00363 if (ClickMods.Adjust || PathIsClosed)
00364 {
00365 pTextStory->SetWordWrapping(FALSE);
00366 pTextStory->SetLeftIndent(0);
00367
00368
00369
00370 CaretNode* pCaret = pTextStory->GetCaret();
00371 if (ok && (pCaret != NULL) && (KernDist > 0))
00372 {
00373 FormatRegion FRegion;
00374 ok = FRegion.Init(pCaret);
00375
00376 CharMetrics CharMet;
00377 if (ok)
00378 ok = FRegion.GetCharMetrics(&CharMet, FONTEMCHAR);
00379
00380
00381 if (ok)
00382 {
00383 KernDist = (INT32)((KernDist / (double)CharMet.FontEmWidth)*1000);
00384 KernCode* pKern = new KernCode();
00385 if (pKern == NULL)
00386 ok = FALSE;
00387 else
00388 {
00389 DocCoord kd(KernDist,0);
00390 pKern->SetValue(kd);
00391 ok = DoInsertNewNode(pKern,pTextStory->FindFirstChild(CC_RUNTIME_CLASS(TextLine)),
00392 FIRSTCHILD,FALSE,FALSE,FALSE);
00393
00394 if (ok)
00395 {
00396 KernCode* pKern = new KernCode();
00397 if (pKern == NULL)
00398 ok = FALSE;
00399 else
00400 {
00401 DocCoord kd(0,0);
00402 pKern->SetValue(kd);
00403 ok = DoInsertNewNode(pKern,pTextStory->FindFirstChild(CC_RUNTIME_CLASS(TextLine)),
00404 FIRSTCHILD,FALSE,FALSE,FALSE);
00405 }
00406 }
00407 }
00408 }
00409 }
00410 }
00411 else
00412 {
00413 pTextStory->SetWordWrapping(TRUE);
00414 pTextStory->SetLeftIndent(KernDist);
00415 }
00416
00417
00418
00419 if (ok) ok = DoLocaliseCommonAttributes(pTextStory);
00420
00421
00422 if (ok) ok = DoMoveNode(pPath, pTextStory, FIRSTCHILD);
00423 if (ok) pPath->DeSelect(FALSE);
00424
00425
00426 if (ok) ok = DoFactorOutCommonChildAttributes(pTextStory);
00427 }
00428
00429
00430 if (ok)
00431 pOurDoc->SetModified(TRUE);
00432
00433
00434 if (ok)
00435 ok = PrePostTextAction::DoFormatStory(this, pTextStory);
00436
00437
00438 if (ok)
00439 {
00440
00441 Layer* pLayer = (Layer*)pTextStory->FindParent(CC_RUNTIME_CLASS(Layer));
00442 if ((pLayer != NULL) && pLayer->IsVisible() && !pLayer->IsLocked())
00443 {
00444 pTextStory->GetCaret()->Select(TRUE);
00445 TextStory::SetFocusStory(pTextStory);
00446 DialogManager::DefaultKeyboardFocus();
00447 }
00448 }
00449
00450
00451 if (!ok)
00452 {
00453 InformError();
00454 FailAndExecute();
00455 }
00456
00457 End();
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 void OpCreateTextObject::DoDrag( Spread* pSpread, DocCoord Anchor, ClickModifiers ClickMods)
00473 {
00474
00475 DocView::SnapCurrent(pSpread, &Anchor);
00476
00477
00478 m_AnchorPoint = Anchor;
00479 m_CurrentOtherEnd = Anchor;
00480 m_pStartSpread = pSpread;
00481
00482
00483 DocRect EditPathBBox = m_pStartSpread->GetBoundingRect();
00484 RenderDragBlobs(EditPathBBox, m_pStartSpread, FALSE);
00485
00486
00487 StartDrag( DRAGTYPE_AUTOSCROLL, NULL, &m_AnchorPoint, FALSE );
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 void OpCreateTextObject::DragPointerMove( DocCoord PointerPos, ClickModifiers ClickMods, Spread* pSpread, BOOL bSolidDrag)
00504 {
00505
00506 DocRect EditPathBBox = m_pStartSpread->GetBoundingRect();
00507 RenderDragBlobs(EditPathBBox, m_pStartSpread, bSolidDrag);
00508
00509
00510 if (pSpread != m_pStartSpread)
00511 PointerPos = MakeRelativeToSpread(m_pStartSpread, pSpread, PointerPos);
00512
00513
00514
00515
00516
00517 if (!ClickMods.Adjust && !ClickMods.Constrain)
00518 PointerPos.y = m_AnchorPoint.y;
00519 if (ClickMods.Constrain)
00520 DocView::ConstrainToAngle(m_AnchorPoint, &PointerPos);
00521 DocView::SnapCurrent(pSpread, &PointerPos);
00522
00523 m_CurrentOtherEnd = PointerPos;
00524
00525
00526 RenderDragBlobs(EditPathBBox, m_pStartSpread, bSolidDrag);
00527
00528
00529 String_256 HelpString(_R(IDS_TEXTTOOL_DRAGCREATEPARA));
00530 GetApplication()->UpdateStatusBarText(&HelpString);
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 void OpCreateTextObject::DragFinished( DocCoord PointerPos, ClickModifiers ClickMods, Spread* pSpread, BOOL Success, BOOL bSolidDrag)
00548 {
00549 EndDrag();
00550
00551
00552 DocRect EditPathBBox = m_pStartSpread->GetBoundingRect();
00553 RenderDragBlobs(EditPathBBox, m_pStartSpread, bSolidDrag);
00554
00555 if (Success)
00556 {
00557
00558 DocRect PointerBlobRect;
00559 GetApplication()->GetBlobManager()->GetBlobRect(m_AnchorPoint, &PointerBlobRect);
00560
00561
00562 if (PointerBlobRect.ContainsCoord(m_CurrentOtherEnd))
00563 DoImmediate(m_pStartSpread, m_AnchorPoint, NULL, ClickMods);
00564 else
00565 DoImmediate(m_pStartSpread, m_AnchorPoint, NULL, ClickMods, m_CurrentOtherEnd);
00566 }
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 void OpCreateTextObject::RenderDragBlobs(DocRect EditPathBBox, Spread* pSpread, BOOL bSolidDrag)
00581 {
00582
00583
00584 if (pSpread != m_pStartSpread)
00585 {
00586 EditPathBBox.lo = MakeRelativeToSpread(m_pStartSpread, pSpread, EditPathBBox.lo);
00587 EditPathBBox.hi = MakeRelativeToSpread(m_pStartSpread, pSpread, EditPathBBox.hi);
00588 }
00589
00590
00591 RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR);
00592 while (pRegion)
00593 {
00594
00595 pRegion->SetFillColour(COLOUR_NONE);
00596 pRegion->SetLineColour(COLOUR_XORNEW);
00597 pRegion->DrawLine(m_AnchorPoint, m_CurrentOtherEnd);
00598
00599
00600 pRegion->SetLineColour(COLOUR_BEZIERBLOB);
00601 pRegion->SetFillColour(COLOUR_BEZIERBLOB);
00602 pRegion->DrawBlob(m_AnchorPoint, BT_UNSELECTED);
00603
00604
00605 pRegion = DocView::GetNextOnTop(NULL);
00606 }
00607 }
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 void OpCreateTextObject::GetOpName(String_256* OpName)
00621 {
00622 *OpName = String_256(_R(IDS_CREATETEXTOBJECT));
00623 }
00624
00625
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 OpTextFormat::OpTextFormat()
00638 {
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 BOOL OpTextFormat::DoDeleteSelection(TextStory* pTextStory, BOOL ReAttachAttributes, BOOL* AllowOpRefused)
00656 {
00657 if (AllowOpRefused != NULL)
00658 *AllowOpRefused = FALSE;
00659
00660 BOOL ok = TRUE;
00661 TextStory* pStory = TextStory::GetFocusStory();
00662 if (pStory != NULL)
00663 {
00664 BOOL DontDelete = FALSE;
00665 BOOL FoundDeletable = FALSE;
00666
00667
00668 VisibleTextNode* pChar = pStory->FindFirstVTN();
00669 ok = (pChar != NULL);
00670 ObjChangeParam ObjEdit(OBJCHANGE_STARTING,ObjChangeFlags(TRUE),NULL,this);
00671 while (ok && !DontDelete && (pChar != NULL))
00672 {
00673 if (pChar->IsSelected() && !pChar->IsACaret())
00674 {
00675 FoundDeletable = TRUE;
00676 DontDelete = !(pChar->AllowOp(&ObjEdit));
00677 }
00678 pChar = pChar->FindNextVTNInStory();
00679 }
00680
00681 if (DontDelete && (AllowOpRefused != NULL))
00682 *AllowOpRefused = TRUE;
00683
00684 if (FoundDeletable && !DontDelete)
00685 {
00686
00687 if (ok && !DontDelete)
00688 ok = pStory->DeleteSelectedText(this);
00689
00690 CaretNode* pCaret = pStory->GetCaret();
00691 if (ok && !DontDelete && (pCaret!=NULL))
00692 pCaret->SetSelected(TRUE);
00693
00694
00695 if (ok && ReAttachAttributes)
00696 ok = pStory->AttachCaretAttributes();
00697
00698
00699 if (GetWorkingDoc() != NULL)
00700 GetWorkingDoc()->SetModified(TRUE);
00701 }
00702 }
00703
00704 return ok;
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 void OpTextFormat::DoInsertChar(WCHAR ch, OpTextFormat::InsertStatus InsStatus)
00719 {
00720 if (!DoInsertCharHelper(ch))
00721 FailAndExecute();
00722 End();
00723 }
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 BOOL OpTextFormat::DoInsertCharHelper(WCHAR ch)
00737 {
00738
00739 TextStory* pStory = TextStory::GetFocusStory();
00740 ERROR2IF(pStory==NULL,FALSE,"OpTextFormat::DoInsertCharHelper() - no focus story");
00741 CaretNode* pCaret = pStory->GetCaret();
00742 ERROR2IF(pCaret==NULL,FALSE,"OpTextFormat::DoInsertCharHelper() - Story has no caret");
00743
00744 String_256 MasterText = pStory->GetStoryAsString();
00745
00746
00747 BOOL ok = DoStartTextOp(pStory);
00748
00749
00750 ObjChangeParam ObjInsert(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
00751 if (ok) ok = pCaret->AllowOp(&ObjInsert);
00752
00753
00754 if (ok) ok = DoDeleteSelection(pStory,TRUE);
00755
00756
00757 TextChar* pNewChar = NULL;
00758 if (ok) { ALLOC_WITH_FAIL(pNewChar, (new TextChar()) , this); }
00759 if (ok) ok = (pNewChar!=NULL);
00760 if (ok) pNewChar->SetUnicodeValue(ch);
00761 if (ok) ok = pNewChar->DoInsertNewNode(this,pCaret,PREV);
00762 if (ok) ok = pCaret->DoApplyAttrsTo(this,pNewChar);
00763
00764
00765 if (ok && GetWorkingDoc()!=NULL)
00766 GetWorkingDoc()->SetModified(TRUE);
00767
00768
00769 SliceHelper::OnTextStoryChanged(pStory, this, &ObjInsert, MasterText);
00770
00771
00772 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
00773 if (ok) ok = UpdateChangedNodes(&ObjChange);
00774
00775 if (ok) pCaret->ScrollToShow();
00776
00777 return ok;
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 void OpTextFormat::DoDeleteChar(OpTextFormat::DeleteType DelTyp)
00793 {
00794 TextStory* pStory = TextStory::GetFocusStory();
00795 if (pStory==NULL)
00796 End();
00797
00798 String_256 MasterText = pStory->GetStoryAsString();
00799
00800 BOOL ok = DoStartTextOp(pStory);
00801
00802 BOOL DeletingAtCaret = FALSE;
00803 BOOL AttachAttrsToCaret = TRUE;
00804
00805
00806 CaretNode* pCaret = pStory->GetCaret();
00807 ERROR3IF(pCaret==NULL,"OpTextFormat::DoDeleteChar() - Focus story had no caret");
00808 VisibleTextNode* pForcedSel = NULL;
00809
00810 if (ok && pCaret!=NULL && pStory->GetSelectionEnd()==NULL)
00811 {
00812 DeletingAtCaret = TRUE;
00813 if (DelTyp==OpTextFormat::DEL)
00814 {
00815 pForcedSel = pCaret->FindNextVTNInStory();
00816 ERROR3IF(pForcedSel==NULL,"No VisibleTextNode following the caret");
00817 if (pForcedSel!=NULL && pForcedSel==pStory->FindLastVTN())
00818 pForcedSel = NULL;
00819 }
00820 else
00821 {
00822 pForcedSel = pCaret->FindPrevVTNInStory();
00823 if (pForcedSel!=NULL && !pForcedSel->IsAnEOLNode())
00824 {
00825 pStory->AttachCaretAttributes();
00826 AttachAttrsToCaret = FALSE;
00827 }
00828
00829 }
00830
00831
00832 if (pForcedSel!=NULL)
00833 {
00834 pForcedSel->SetSelected(TRUE);
00835 pCaret->SetSelected(FALSE);
00836 }
00837 }
00838
00839
00840 if (!DeletingAtCaret || pForcedSel!=NULL)
00841 {
00842
00843 BOOL AllowOpRefused = TRUE;
00844 ok = DoDeleteSelection(pStory, AttachAttrsToCaret, &AllowOpRefused);
00845
00846
00847 if (ok && AllowOpRefused && pForcedSel!=NULL)
00848 {
00849 pForcedSel->SetSelected(FALSE);
00850 pCaret->SetSelected(TRUE);
00851 }
00852
00853
00854 if (GetWorkingDoc()!=NULL)
00855 GetWorkingDoc()->SetModified(TRUE);
00856
00857 ObjChangeFlags cFlags;
00858 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00859
00860 if (ok)
00861 {
00862
00863 SliceHelper::OnTextStoryChanged(pStory, this, &ObjChange, MasterText);
00864 }
00865
00866 ObjChange.Define(OBJCHANGE_FINISHED,ObjChangeFlags(TRUE),NULL,this);
00867
00868
00869 if (ok) ok = UpdateChangedNodes(&ObjChange);
00870
00871 if (ok) pCaret->ScrollToShow();
00872 }
00873
00874 if (!ok)
00875 {
00876 InformError();
00877 FailAndExecute();
00878 }
00879
00880 End();
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 BOOL OpTextFormat::DoReturn(OpTextFormat::InsertStatus InsStatus)
00896 {
00897 ERROR2IF(InsStatus!=OpTextFormat::INSERT,FALSE,"OpTextFormat::DoReturn() - only supports insert mode");
00898 UndoableOperation* pUndoOp = this;
00899
00900
00901 TextStory* pStory = TextStory::GetFocusStory();
00902 ERROR2IF(pStory==NULL, FALSE, "OpTextFormat::DoReturn() - No focus story");
00903 CaretNode* pCaret = pStory->GetCaret();
00904 ERROR2IF(pCaret==NULL, FALSE, "OpTextFormat::DoReturn() - Focus story had no caret");
00905 TextLine* pCaretLine = pCaret->FindParentLine();
00906 ERROR2IF(pCaretLine==NULL,FALSE,"OpTextFormat::DoReturn() - caret has no parent");
00907
00908 String_256 MasterText = pStory->GetStoryAsString();
00909
00910
00911 BOOL ok = DoStartTextOp(pStory);
00912
00913
00914 ObjChangeParam ObjParam(OBJCHANGE_STARTING, ObjChangeFlags(), NULL, pUndoOp);
00915 if (pCaret->AllowOp(&ObjParam)==FALSE)
00916 return TRUE;
00917
00918
00919 if (ok) ok = DoDeleteSelection(pStory, TRUE);
00920
00921
00922
00923 pCaret = pStory->GetCaret();
00924 ERROR2IF(pCaret==NULL, FALSE, "OpTextFormat::DoReturn() - Focus story had no caret");
00925 pCaretLine = pCaret->FindParentLine();
00926 ERROR2IF(pCaretLine==NULL,FALSE,"OpTextFormat::DoReturn() - caret has no parent");
00927
00928 VisibleTextNode* pLastCaretLineVTN = pCaretLine->FindLastVTN();
00929 ERROR2IF(pLastCaretLineVTN==NULL,FALSE,"OpTextFormat::DoReturn() - caret line has no VTN");
00930
00931
00932 EOLNode* pNewEOL = NULL;
00933 if (ok) pNewEOL = new EOLNode;
00934 if (ok) ok = (pNewEOL!=NULL);
00935 if (ok) ok = pNewEOL->DoInsertNewNode(pUndoOp,pCaret,PREV);
00936 if (ok) ok = pCaret->DoApplyAttrsTo(pUndoOp,pNewEOL);
00937
00938
00939 TextLine* pNewLine = NULL;
00940 if (ok) pNewLine = new TextLine;
00941 if (ok) ok = (pNewLine!=NULL);
00942 if (ok) ok = pNewLine->DoInsertNewNode(pUndoOp,pCaretLine,NEXT);
00943
00944
00945 if (ok) ok = pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,NULL);
00946 if (ok) ok = pCaret->DoMoveNodes(pUndoOp,pLastCaretLineVTN,pNewLine,FIRSTCHILD);
00947 if (ok) ok = pCaretLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
00948 if (ok) ok = pNewLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
00949
00950
00951 SliceHelper::OnTextStoryChanged(pStory, this, &ObjParam, MasterText);
00952
00953
00954 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,pUndoOp);
00955 if (ok) ok = UpdateChangedNodes(&ObjChange);
00956
00957 if (ok) pCaret->ScrollToShow();
00958
00959 if (!ok) FailAndExecute();
00960 End();
00961
00962 return ok;
00963 }
00964
00965 BOOL OpTextFormat::DoTab()
00966 {
00967 UndoableOperation* pUndoOp = this;
00968
00969
00970 TextStory* pStory = TextStory::GetFocusStory();
00971 ERROR2IF(pStory==NULL, FALSE, "OpTextFormat::DoTab() - No focus story");
00972 CaretNode* pCaret = pStory->GetCaret();
00973 ERROR2IF(pCaret==NULL, FALSE, "OpTextFormat::DoTab() - Focus story had no caret");
00974 TextLine* pCaretLine = pCaret->FindParentLine();
00975 ERROR2IF(pCaretLine==NULL,FALSE,"OpTextFormat::DoTab() - caret has no parent");
00976
00977
00978 BOOL ok = DoStartTextOp(pStory);
00979
00980
00981 ObjChangeParam ObjParam(OBJCHANGE_STARTING, ObjChangeFlags(), NULL, pUndoOp);
00982 if (pCaret->AllowOp(&ObjParam)==FALSE)
00983 return TRUE;
00984
00985
00986 if (ok) ok = DoDeleteSelection(pStory, TRUE);
00987
00988
00989
00990 pCaret = pStory->GetCaret();
00991 ERROR2IF(pCaret==NULL, FALSE, "OpTextFormat::DoTab() - Focus story had no caret");
00992 pCaretLine = pCaret->FindParentLine();
00993 ERROR2IF(pCaretLine==NULL,FALSE,"OpTextFormat::DoTab() - caret has no parent");
00994
00995 VisibleTextNode* pLastCaretLineVTN = pCaretLine->FindLastVTN();
00996 ERROR2IF(pLastCaretLineVTN==NULL,FALSE,"OpTextFormat::DoTab() - caret line has no VTN");
00997
00998
00999 HorizontalTab* pTab = NULL;
01000 if (ok) pTab = new HorizontalTab;
01001 if (ok) ok = (pTab != NULL);
01002 if (ok) ok = pTab->DoInsertNewNode(pUndoOp,pCaret,PREV);
01003 if (ok) ok = pCaret->DoApplyAttrsTo(pUndoOp,pTab);
01004
01005
01006
01007
01008
01009 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,pUndoOp);
01010 if (ok) ok = UpdateChangedNodes(&ObjChange);
01011
01012 if (ok) pCaret->ScrollToShow();
01013
01014 if (!ok) FailAndExecute();
01015 End();
01016
01017 return ok;
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 void OpTextFormat::DoSwapCase()
01030 {
01031
01032 TextStory* pStory = TextStory::GetFocusStory();
01033 ERROR3IF(pStory == NULL, "You attempted to swap a character without a focus story");
01034 CaretNode* pCaret = NULL;
01035 if (pStory != NULL)
01036 pCaret = pStory->GetCaret();
01037 ERROR3IF(pCaret == NULL, "The TextStory didn't have a caret!");
01038 if (pCaret == NULL)
01039 return;
01040
01041
01042 if (pStory->GetSelectionEnd() != NULL)
01043 {
01044 Beep();
01045 return;
01046 }
01047
01048
01049 VisibleTextNode* pSwapChar = NULL;
01050 pSwapChar = pCaret->FindNextVTNInStory();
01051
01052 BOOL ok = TRUE;
01053
01054 if (pSwapChar != NULL)
01055 {
01056 ok = DoStartTextOp(pStory);
01057
01058
01059 if (ok)
01060 {
01061 ObjChangeParam ObjInsert(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
01062 if (pSwapChar->AllowOp(&ObjInsert)==FALSE)
01063 pSwapChar=NULL;
01064 }
01065
01066
01067 if ((pSwapChar != NULL) && ok)
01068 {
01069 if (IS_A(pSwapChar,TextChar))
01070 {
01071 TextChar* pSwapTextChar = (TextChar*)pSwapChar;
01072 WCHAR CharValue = pSwapTextChar->GetUnicodeValue();
01073 CharCase Result = TextManager::ProcessCharCase(&CharValue, Swap);
01074
01075 ok = (Result != Failed);
01076
01077 if (ok && (Result != UnknownType))
01078 {
01079
01080 ok = StoreCharCodeAction::DoStoreCharacterCode( this, &UndoActions, pSwapTextChar);
01081
01082
01083 if (ok)
01084 pSwapTextChar->SetUnicodeValue(CharValue);
01085 }
01086 }
01087
01088
01089 if (ok)
01090 {
01091 pStory->MoveCaretRightAChar();
01092 pStory->GetCaret()->HasMoved();
01093 pStory->GetCaret()->ScrollToShow();
01094 }
01095 }
01096 }
01097
01098
01099 if (ok)
01100 {
01101 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
01102 ok = UpdateChangedNodes(&ObjChange);
01103 }
01104
01105 if (!ok)
01106 {
01107 InformError();
01108 FailAndExecute();
01109 }
01110
01111 End();
01112 }
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 void OpTextFormat::GetOpName(String_256* OpName)
01125 {
01126 *OpName = String_256(_R(IDS_TYPING));
01127 }
01128
01129
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 PositionCaretAction::PositionCaretAction()
01142 {
01143 pTextStory = NULL;
01144 pNearNode = NULL;
01145 AttachDirection = NEXT;
01146 }
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157 PositionCaretAction::~PositionCaretAction()
01158 {
01159 }
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172 ActionCode PositionCaretAction::Execute()
01173 {
01174 ERROR2IF(pTextStory==NULL,AC_FAIL,"PositionCaretAction::Execute() - pTextStory==NULL");
01175 ERROR2IF( pNearNode==NULL,AC_FAIL,"PositionCaretAction::Execute() - pNearNode==NULL");
01176 CaretNode* pCaret = pTextStory->GetCaret();
01177 ERROR2IF( pCaret==NULL,AC_FAIL,"PositionCaretAction::Execute() - pCaret==NULL");
01178
01179
01180 BaseTextClass* pReDoAttachNode = NULL;
01181 AttachNodeDirection ReDoAttachDir = NEXT;
01182 if (!GetCaretNeighbour(pTextStory, &pReDoAttachNode, &ReDoAttachDir))
01183 return AC_FAIL;
01184 if (PositionCaretAction::Init(pOperation,pOppositeActLst,pTextStory,pReDoAttachNode,ReDoAttachDir)==AC_FAIL)
01185 return AC_FAIL;
01186
01187
01188 Node* pAttachNode = pNearNode;
01189 AttachNodeDirection AttachDir = AttachDirection;
01190 if (AttachDirection==FIRSTCHILD)
01191 pNearNode->GetAttachNodeAndDirectionToAttachFirstChildObject(&pAttachNode,&AttachDir);
01192
01193
01194 BOOL CaretWasSelected = pCaret->IsSelected();
01195 if (CaretWasSelected)
01196 pCaret->SetSelected(FALSE);
01197 pCaret->MoveNode(pAttachNode, AttachDir);
01198 if (CaretWasSelected)
01199 pCaret->SetSelected(TRUE);
01200
01201 pTextStory->AttachCaretAttributes();
01202 pCaret->ScrollToShow();
01203
01204 return AC_OK;
01205 }
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229 ActionCode PositionCaretAction::Init(Operation* pOp,
01230 ActionList* pActionList,
01231 TextStory* pStory,
01232 BaseTextClass* pAttachNode,
01233 AttachNodeDirection Direction)
01234 {
01235 UINT32 ActSize = sizeof(PositionCaretAction);
01236
01237 PositionCaretAction* pNewAction = NULL;
01238
01239 ActionCode Ac = Action::Init( pOp, pActionList, ActSize, CC_RUNTIME_CLASS(PositionCaretAction), (Action**)&pNewAction);
01240 if ((Ac == AC_OK) && (pNewAction != NULL))
01241 {
01242 ERROR2IF(pStory == NULL, AC_FAIL, "TextStory pointer was NULL");
01243 ERROR2IF(pAttachNode == NULL, AC_FAIL, "Attachment node pointer was NULL");
01244 pNewAction->pTextStory = pStory;
01245 pNewAction->pNearNode = pAttachNode;
01246 pNewAction->AttachDirection = Direction;
01247 }
01248
01249 return Ac;
01250 }
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264 BOOL PositionCaretAction::DoStoreCaretPosition(Operation* pOp, TextStory* pStory)
01265 {
01266 ERROR2IF(pStory==NULL,FALSE,"PositionCaretAction::DoStoreCaretPosition() - pStory==NULL");
01267 ERROR2IF(pOp ==NULL,FALSE,"PositionCaretAction::DoStoreCaretPosition() - pOp==NULL");
01268
01269
01270 CaretNode* pCaret = pStory->GetCaret();
01271 ERROR2IF(pCaret==NULL,FALSE,"PositionCaretAction::DoStoreCaretPosition() - pCaret==NULL");
01272
01273 ActionList* pActionList = pOp->GetUndoActionList();
01274 ERROR2IF(pActionList==NULL,FALSE,"PositionCaretAction::DoStoreCaretPosition() - pActionList==NULL");
01275
01276
01277 BaseTextClass* pReattachNode = NULL;
01278 AttachNodeDirection AttachDir = NEXT;
01279 if (GetCaretNeighbour(pStory, &pReattachNode, &AttachDir)==FALSE)
01280 return FALSE;
01281
01282
01283 if (PositionCaretAction::Init(pOp, pActionList, pStory, pReattachNode, AttachDir)==AC_FAIL)
01284 return FALSE;
01285
01286 return TRUE;
01287 }
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303 BOOL PositionCaretAction::GetCaretNeighbour(TextStory* pStory, BaseTextClass** ppNeighbour,
01304 AttachNodeDirection* pDirection)
01305 {
01306 ERROR2IF( pStory== NULL,FALSE,"PositionCaretAction::GetCaretNeighbour() - pStory==NULL");
01307 ERROR2IF(ppNeighbour== NULL,FALSE,"PositionCaretAction::GetCaretNeighbour() - ppNeighbour==NULL");
01308 ERROR2IF( pDirection== NULL,FALSE,"PositionCaretAction::GetCaretNeighbour() - pDirection==NULL");
01309
01310
01311 CaretNode* pCaret = pStory->GetCaret();
01312 ERROR2IF(pCaret==NULL,FALSE,"PositionCaretAction::GetCaretNeighbour() - story has no caret");
01313 *ppNeighbour = pCaret->FindPrevVTNInLine();
01314 *pDirection = NEXT;
01315 if (*ppNeighbour==NULL)
01316 {
01317 *ppNeighbour = pCaret->FindNextVTNInLine();
01318 *pDirection = PREV;
01319 }
01320 if (*ppNeighbour==NULL)
01321 {
01322 *ppNeighbour = pCaret->FindParentLine();
01323 ERROR2IF(*ppNeighbour==NULL,FALSE,"PositionCaretAction::GetCaretNeighbour() - caret has no parent TExtLine");
01324 *pDirection = FIRSTCHILD;
01325 }
01326
01327 return TRUE;
01328 }
01329
01330
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342 OpTextKern::OpTextKern(): OpTextUndoable()
01343 {
01344 }
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359 BOOL OpTextKern::Init()
01360 {
01361 return (RegisterOpDescriptor(0,
01362 _R(IDS_KERNOP),
01363 CC_RUNTIME_CLASS(OpTextKern),
01364 OPTOKEN_KERNTEXT,
01365 OpTextKern::GetState,
01366 0,
01367 0,
01368 0,
01369 0,
01370 SYSTEMBAR_ILLEGAL,
01371 TRUE,
01372 FALSE,
01373 FALSE,
01374 0,
01375 GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION | DONT_GREY_WHEN_SELECT_INSIDE
01376 ));
01377 }
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390 OpState OpTextKern::GetState(String_256* UIDescription, OpDescriptor*)
01391 {
01392 OpState OpSt;
01393 OpSt.Greyed = TRUE;
01394
01395 TextStory* pStory = TextStory::GetFocusStory();
01396 if (pStory != NULL)
01397 {
01398 CaretNode* pCaret = pStory->GetCaret();
01399 if (pCaret != NULL)
01400 {
01401 if (pCaret->IsSelected() && pStory->GetSelectionEnd() == NULL)
01402 OpSt.Greyed = FALSE;
01403 }
01404 }
01405
01406 return OpSt;
01407 }
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425 void OpTextKern::DoWithParam(OpDescriptor*, OpParam* pOpParam)
01426 {
01427
01428 DocCoord KernValue(pOpParam->Param1, pOpParam->Param2);
01429
01430
01431 TextStory* pFocusStory=TextStory::GetFocusStory();
01432 CaretNode* pCaret = NULL;
01433 ERROR3IF(pFocusStory==NULL,"OpTextKern::DoWithParam() - The focus story is missing");
01434 if (pFocusStory != NULL)
01435 pCaret = pFocusStory->GetCaret();
01436 ERROR3IF(pCaret==NULL,"OpTextKern::DoWithParam() - The text story's caret is missing");
01437 BOOL ok = ((pFocusStory != NULL) && (pCaret != NULL));
01438
01439
01440 if (ok)
01441 ok = DoStartTextOp(pFocusStory);
01442
01443
01444 if ( ok && (pFocusStory->GetSelectionEnd() == NULL))
01445 {
01446 ok = DoInsertKernWithMerge(pCaret, KernValue);
01447 }
01448
01449
01450 if (ok)
01451 {
01452 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
01453 ok = UpdateChangedNodes(&ObjChange);
01454 }
01455
01456 GetApplication()->UpdateSelection();
01457
01458 if (!ok)
01459 FailAndExecute();
01460
01461 End();
01462 }
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479 BOOL OpTextKern::DoInsertKernWithMerge(VisibleTextNode* TTContextNode, DocCoord& Value)
01480 {
01481 ERROR2IF(TTContextNode == NULL, FALSE, "TTContextNode is NULL");
01482 DocCoord KernValue = Value;
01483 AbstractTextChar* pPrevATC = (AbstractTextChar*)TTContextNode->FindPrevious(CC_RUNTIME_CLASS(AbstractTextChar));
01484 AbstractTextChar* pNextATC = (AbstractTextChar*)TTContextNode->FindNext(CC_RUNTIME_CLASS(AbstractTextChar));
01485 BOOL ok = TRUE;
01486
01487
01488 ObjChangeParam ObjDelete(OBJCHANGE_STARTING,ObjChangeFlags(TRUE),NULL,this);
01489 if (ok && (pNextATC!=NULL) && IS_A(pNextATC, KernCode))
01490 {
01491 KernValue = KernValue + ((KernCode*)pNextATC)->GetValue();
01492 ok = pNextATC->AllowOp(&ObjDelete);
01493 if (ok)
01494 ok = DoHideNode(pNextATC, TRUE);
01495 }
01496
01497
01498 if (ok && (pPrevATC!=NULL) && IS_A(pPrevATC, KernCode) && (KernValue.x==0) && (KernValue.y==0))
01499 {
01500 ok = pPrevATC->AllowOp(&ObjDelete);
01501 if (ok)
01502 ok = DoHideNode(pPrevATC, TRUE);
01503 pPrevATC = NULL;
01504 }
01505
01506
01507 if (ok && (KernValue.x!=0 || KernValue.y!=0))
01508 {
01509
01510 if ((pPrevATC == NULL) || !IS_A(pPrevATC,KernCode) )
01511 {
01512
01513 KernCode* pKernCode = NULL;
01514 ALLOC_WITH_FAIL(pKernCode, (new KernCode()), this);
01515 ok = (pKernCode != NULL);
01516
01517
01518 if (ok)
01519 {
01520 AbstractTextChar* pAttrChar = pPrevATC;
01521 if (pAttrChar == NULL)
01522 pAttrChar = pNextATC;
01523 if (pAttrChar != NULL)
01524 ok = pAttrChar->CopyChildrenTo(pKernCode);
01525
01526 }
01527
01528
01529 if (ok)
01530 {
01531 pKernCode->SetValue(KernValue);
01532 ObjChangeParam ObjInsert(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
01533 ok = TTContextNode->AllowOp(&ObjInsert);
01534 if (ok)
01535 ok = pKernCode->DoInsertNewNode(this,TTContextNode,PREV);
01536 }
01537 }
01538 else
01539 {
01540
01541 ObjChangeParam ObjEdit(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
01542 if (pPrevATC->AllowOp(&ObjEdit))
01543 {
01544
01545 ok = StoreKernCodeAction::DoStoreKernValue(this, &UndoActions, (KernCode*)pPrevATC);
01546
01547
01548 if (ok)
01549 ((KernCode*)pPrevATC)->SetValue(KernValue);
01550 }
01551 }
01552 }
01553
01554 return ok;
01555 }
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568 void OpTextKern::PerformMergeProcessing()
01569 {
01570
01571 OperationHistory* pOpHist = &pOurDoc->GetOpHistory();
01572 ERROR3IF(pOpHist->FindLastOp() != this, "Last Op should be this op");
01573
01574
01575 Operation* pPrevOp = pOpHist->FindPrevToLastOp();
01576
01577 if ((pPrevOp != NULL) && IS_A(pPrevOp, OpTextKern))
01578 {
01579
01580
01581
01582 StoreKernCodeAction* pThisStoreKern = (StoreKernCodeAction*)GetUndoActionList()->FindActionOfClass(CC_RUNTIME_CLASS(StoreKernCodeAction));
01583 StoreKernCodeAction* pPrevStoreKern = (StoreKernCodeAction*)pPrevOp->GetUndoActionList()->FindActionOfClass(CC_RUNTIME_CLASS(StoreKernCodeAction));
01584 InvalidateArbitaryAction* pThisInvalidRect = (InvalidateArbitaryAction*)GetUndoActionList()->FindActionOfClass(CC_RUNTIME_CLASS(InvalidateArbitaryAction));
01585 InvalidateArbitaryAction* pPrevInvalidRect = (InvalidateArbitaryAction*)pPrevOp->GetUndoActionList()->FindActionOfClass(CC_RUNTIME_CLASS(InvalidateArbitaryAction));
01586
01587 if ((pThisStoreKern != NULL) && (pPrevStoreKern != NULL) &&
01588 (pThisInvalidRect != NULL) && (pPrevInvalidRect != NULL) &&
01589 (pThisStoreKern->GetKernCode() == pPrevStoreKern->GetKernCode()) &&
01590 (pThisInvalidRect->GetSpread() == pPrevInvalidRect->GetSpread()))
01591 {
01592
01593
01594
01595 DocRect AllInvalid = pThisInvalidRect->GetRect().Union(pPrevInvalidRect->GetRect());
01596 pPrevInvalidRect->SetRect(AllInvalid);
01597
01598
01599 pOpHist->DeleteLastOp();
01600 }
01601 }
01602 }
01603
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614 OpTextAutoKern::OpTextAutoKern(): OpTextUndoable()
01615 {
01616 }
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630 BOOL OpTextAutoKern::Init()
01631 {
01632 return (RegisterOpDescriptor(0,
01633 _R(IDS_AUTOKERNOP),
01634 CC_RUNTIME_CLASS(OpTextAutoKern),
01635 OPTOKEN_AUTOKERNTEXT,
01636 OpTextAutoKern::GetState,
01637 0,
01638 0,
01639 0,
01640 0,
01641 SYSTEMBAR_ILLEGAL,
01642 TRUE,
01643 FALSE,
01644 FALSE,
01645 0,
01646 GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION | DONT_GREY_WHEN_SELECT_INSIDE
01647 ));
01648 }
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660 OpState OpTextAutoKern::GetState(String_256* UIDescription, OpDescriptor*)
01661 {
01662 OpState OpSt;
01663
01664 if (TextStory::GetFocusStory())
01665 OpSt.Greyed = FALSE;
01666 else
01667 OpSt.Greyed = TRUE;
01668
01669 return OpSt;
01670 }
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683 void OpTextAutoKern::DoWithParam(OpDescriptor*, OpParam* pOpParam)
01684 {
01685 bool NewIsAutoKerning = pOpParam->Param1 != 0;
01686
01687 TextStory *pTextStory = TextStory::GetFocusStory();
01688 BOOL ok = pTextStory != 0;
01689
01690
01691 ObjChangeFlags ChangeFlags;
01692 ChangeFlags.RegenerateNode = TRUE;
01693
01694
01695 if (ok) ok = DoStartTextOp(pTextStory);
01696
01697 if (ok)
01698 {
01699 ObjChangeParam ObjChange(OBJCHANGE_STARTING, ChangeFlags, pTextStory, this);
01700 ok = pTextStory->AllowOp(&ObjChange);
01701 }
01702
01703 if (ok) ok = DoInvalidateNodeRegion(pTextStory, TRUE, FALSE);
01704
01705 if (ok) ok = ToggleAutoKerningAction::Init(this, &UndoActions, pTextStory, NewIsAutoKerning) != AC_FAIL;
01706
01707 if (ok) ok = DoInvalidateNodeRegion(pTextStory, TRUE, FALSE);
01708
01709
01710
01711 if (ok)
01712 {
01713 ObjChangeParam ObjChange(OBJCHANGE_FINISHED, ChangeFlags, pTextStory, this);
01714 ok = UpdateChangedNodes(&ObjChange);
01715 }
01716
01717 if (!ok)
01718 FailAndExecute();
01719
01720 End();
01721 }
01722
01723
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735 OpFitTextToCurve::OpFitTextToCurve(): OpTextUndoable()
01736 {
01737 }
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752 BOOL OpFitTextToCurve::Init()
01753 {
01754 return (RegisterOpDescriptor(0,
01755 _R(IDS_FITTEXTTOPATHOP),
01756 CC_RUNTIME_CLASS(OpFitTextToCurve),
01757 OPTOKEN_FITTEXTTOPATH,
01758 OpFitTextToCurve::GetState,
01759 0,
01760 _R(IDBBL_FITTEXTTOCURVE),
01761 _R(IDD_BARCONTROLSTORE),
01762 _R(IDC_FITTEXTTOCURVE),
01763 SYSTEMBAR_EDIT,
01764 TRUE,
01765 FALSE,
01766 FALSE,
01767 0,
01768 GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION | DONT_GREY_WHEN_SELECT_INSIDE
01769 ));
01770 }
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783 OpState OpFitTextToCurve::GetState(String_256* UIDescription, OpDescriptor*)
01784 {
01785 OpState OpSt;
01786
01787 NodeRenderableInk* pPath = NULL;
01788 TextStory* pStory = NULL;
01789 UINT32 IDS = 0;
01790
01791
01792
01793 if (!FindPathAndText(&pPath, &pStory, NULL, &IDS))
01794 {
01795 OpSt.Greyed = TRUE;
01796 if (IDS == 0)
01797 IDS = _R(IDS_NOTPATHANDTEXTSEL);
01798 }
01799 else
01800 {
01801
01802 if (pPath == NULL)
01803 IDS = _R(IDS_REMOVETEXTFROMPATHOP);
01804 }
01805
01806 if (IDS != 0)
01807 *UIDescription = String_256(IDS);
01808
01809 return(OpSt);
01810 }
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822 void OpFitTextToCurve::Do(OpDescriptor*)
01823 {
01824
01825 NodeRenderableInk* pObject = NULL;
01826 TextStory* pStory = NULL;
01827 UINT32 dummy = 0;
01828 BOOL ok=FindPathAndText(&pObject, &pStory, this, &dummy);
01829
01830
01831 if (ok) ok = DoStartSelOp(TRUE, TRUE);
01832
01833 BeginSlowJob();
01834
01835
01836 if (ok)
01837 {
01838 ObjChangeParam ObjInsert(OBJCHANGE_STARTING,ObjChangeFlags(FALSE,FALSE,FALSE,FALSE,FALSE,TRUE),NULL,this);
01839 ok = pStory->AllowOp(&ObjInsert);
01840 }
01841
01842
01843 if (ok && (pObject != NULL))
01844 {
01845 ObjChangeParam ObjDelete(OBJCHANGE_STARTING,ObjChangeFlags(TRUE),NULL,this);
01846 ObjChangeParam ObjMove(OBJCHANGE_STARTING,ObjChangeFlags(FALSE, FALSE, TRUE),NULL,this);
01847 if (!IS_A(pObject,NodePath))
01848 ok = pObject->AllowOp(&ObjDelete);
01849 else
01850 ok = pObject->AllowOp(&ObjMove);
01851 }
01852
01853
01854 if (!ok)
01855 {
01856 FailAndExecute();
01857 End();
01858 return;
01859 }
01860
01861
01862 if (ok) ok = DoLocaliseCommonAttributes(pStory);
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873 if (ok && pObject && pStory)
01874 {
01875 Node* pCompoundAboveObj = NULL;
01876 Node* pCompoundAboveText = NULL;
01877
01878 PORTNOTE("other", "Removed live effects usage from text");
01879 #ifndef EXCLUDE_FROM_XARALX
01880
01881 ListRange* pStack = EffectsStack::GetEffectsStackFromNode(pObject, FALSE, TRUE, TRUE);
01882 if (pStack)
01883 {
01884 pCompoundAboveObj = pStack->FindLast();
01885 delete pStack;
01886 }
01887
01888 pStack = EffectsStack::GetEffectsStackFromNode(pStory, FALSE, TRUE, TRUE);
01889 if (pStack)
01890 {
01891 pCompoundAboveText = pStack->FindLast();
01892 delete pStack;
01893 }
01894
01895
01896 if (pCompoundAboveObj!=NULL && pCompoundAboveText!=NULL)
01897 {
01898 OpLiveEffect::DoDeleteAllPostProcessors(this, pObject, TRUE, TRUE);
01899 pCompoundAboveObj = NULL;
01900 }
01901 #endif
01902
01903
01904
01905
01906
01907 DocRect ObjectBounds = pObject->GetBoundingRect();
01908 DocRect StoryBounds = pStory->GetBoundingRect();
01909
01910 Trans2DMatrix* pTransMat = new Trans2DMatrix(Matrix(ObjectBounds.lo.x-StoryBounds.lo.x, ObjectBounds.lo.y-StoryBounds.lo.y));
01911 ok = (pTransMat!=NULL);
01912 if (ok)
01913 ok = DoTransformNode(pStory, pTransMat);
01914
01915
01916
01917 if (pCompoundAboveObj!=NULL && pCompoundAboveText==NULL)
01918 {
01919 DoMoveNode(pStory, pObject, NEXT);
01920 }
01921 }
01922
01923 if (pObject == NULL)
01924 {
01925
01926
01928 if (ok) ok = MatrixFitToPathAction::DoMatrixRemoveFromPath(this, &UndoActions, pStory);
01929
01930
01931 pObject = pStory->GetTextPath();
01932 if (pObject != NULL)
01933 {
01934
01935
01936 TextStoryInfo StoryInfo;
01937 if (ok) ok = pStory->CreateUntransformedPath(&StoryInfo);
01938 if (ok)
01939 {
01940 delete StoryInfo.pPath;
01941 if (StoryInfo.WordWrapping)
01942 pStory->SetStoryWidth(StoryInfo.PathLength - StoryInfo.LeftPathIndent - StoryInfo.RightPathIndent);
01943
01944
01945 ok = DoMoveNode(pObject, pStory, NEXT);
01946 }
01947
01948 if (ok) pObject->SetSelected(FALSE);
01949 if (ok) pStory->SetSelected(TRUE);
01950 }
01951 }
01952 else
01953 {
01954
01955 if (ok) pObject->SetSelected(FALSE);
01956 if (ok) ok = DoMoveNode(pObject,pStory,FIRSTCHILD);
01957
01958
01959 if (ok && !IS_A(pObject,NodePath))
01960 {
01961 Range pThing(pObject, pObject, RangeControl(TRUE, TRUE));
01962 ok = DoMakeShapes(pThing);
01963 }
01964
01965 if (ok) ok = MatrixRemoveFromPathAction::DoMatrixFitToPath(this, &UndoActions, pStory);
01966 if (ok) pStory->SetSelected(TRUE);
01967 }
01968
01969
01970 if (ok) ok = DoFactorOutCommonChildAttributes(pStory);
01971
01972
01973 if (ok)
01974 {
01975 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(FALSE,FALSE,FALSE,FALSE,FALSE,TRUE),NULL,this);
01976 ok = UpdateChangedNodes(&ObjChange);
01977 }
01978
01979 if (!ok)
01980 {
01981 FailAndExecute();
01982 InformError();
01983 }
01984
01985 End();
01986 }
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004 BOOL OpFitTextToCurve::FindPathAndText(NodeRenderableInk** pPath, TextStory** pStory, UndoableOperation* pOp, UINT32* ID)
02005 {
02006 OpState OpSt;
02007
02008
02009 *pStory = NULL;
02010 *pPath= NULL;
02011
02012
02013 ObjChangeParam ObjDeleteChange(OBJCHANGE_STARTING,ObjChangeFlags(TRUE),NULL,pOp);
02014 ObjChangeParam ObjNotChange(OBJCHANGE_STARTING,ObjChangeFlags(FALSE),NULL,pOp);
02015
02016 BOOL FoundOnePath = FALSE;
02017 BOOL FoundOneTextStory = FALSE;
02018 BOOL FoundMultiple = FALSE;
02019 BOOL StoryHadPath = FALSE;
02020
02021 SelRange* Selected = GetApplication()->FindSelection();
02022 Node* pNode = Selected->FindFirst();
02023
02024 BOOL bFoundTextStoryWithController = FALSE;
02025 BOOL bFoundPathWithController = FALSE;
02026
02027 BecomeA TestBecomeAPath(BECOMEA_TEST, CC_RUNTIME_CLASS(NodePath));
02028
02029 while (pNode && !FoundMultiple)
02030 {
02031
02032 if (pNode->NeedsParent(NULL))
02033 {
02034
02035 *pStory = (TextStory *)pNode->FindNext(CC_RUNTIME_CLASS(BaseTextClass));
02036
02037 if ((*pStory) == NULL)
02038 {
02039 *pStory = (TextStory *)pNode->FindPrevious(CC_RUNTIME_CLASS(BaseTextClass));
02040 }
02041
02042
02043 if ((*pStory) != NULL)
02044 bFoundTextStoryWithController = TRUE;
02045
02046
02047 if (!bFoundTextStoryWithController)
02048 {
02049 *pPath = (NodeRenderableInk *)pNode->FindNext(CC_RUNTIME_CLASS(NodeRenderableInk));
02050
02051 if ((*pPath) == NULL)
02052 {
02053 *pPath = (NodeRenderableInk *)pNode->FindPrevious(CC_RUNTIME_CLASS(NodeRenderableInk));
02054 }
02055
02056 if ((*pPath) != NULL && (*pPath)->NeedsParent(NULL))
02057 {
02058 *pPath = NULL;
02059 }
02060 }
02061
02062 if ((*pPath) != NULL)
02063 {
02064 bFoundPathWithController = TRUE;
02065 }
02066 }
02067
02068
02069 if (pNode->IsCompound())
02070 {
02071 if (pNode->IsController())
02072 {
02073
02074 *pStory = (TextStory *)pNode->FindFirstChild(CC_RUNTIME_CLASS(BaseTextClass));
02075
02076 if ((*pStory) != NULL)
02077 bFoundTextStoryWithController = TRUE;
02078
02079 if (!bFoundTextStoryWithController)
02080 {
02081
02082 *pPath = (NodeRenderableInk *)pNode->FindFirstChild(CC_RUNTIME_CLASS(NodeRenderableInk));
02083
02084 while (*pPath && (*pPath)->NeedsParent(NULL))
02085 {
02086 *pPath = (NodeRenderableInk *)(*pPath)->FindNext(CC_RUNTIME_CLASS(NodeRenderableInk));
02087 }
02088 }
02089 }
02090
02091 if ((*pPath) != NULL)
02092 {
02093 bFoundPathWithController = TRUE;
02094 }
02095 }
02096
02097 if ((pNode->IS_KIND_OF(BaseTextClass) || bFoundTextStoryWithController)
02098 && (*pStory) != pNode)
02099 {
02100
02101 bFoundTextStoryWithController = FALSE;
02102
02103 TextStory* pTS = NULL;
02104
02105 if (*(pStory) == NULL)
02106 {
02107 if (IS_A(pNode,TextStory))
02108 pTS = (TextStory*)pNode;
02109 else
02110 pTS = (TextStory*)pNode->FindParent(CC_RUNTIME_CLASS(TextStory));
02111 }
02112 else
02113 {
02114 pTS = *pStory;
02115 }
02116
02117 if (pTS != NULL)
02118 {
02119 if (FoundOneTextStory && (pTS != *pStory))
02120 FoundMultiple = TRUE;
02121 else
02122 {
02123
02124 if (pTS->AllowOp(&ObjNotChange,FALSE))
02125 {
02126 FoundOneTextStory = TRUE;
02127 *pStory = pTS;
02128 if ((*pStory)->GetTextPath() != NULL)
02129 {
02130 FoundOnePath = TRUE;
02131 StoryHadPath = TRUE;
02132 }
02133 }
02134 }
02135 }
02136 }
02137 else if (pNode->IsAnObject() &&
02138 !pNode->IsCompound() &&
02139 ((NodeRenderableInk*)pNode)->CanBecomeA(&TestBecomeAPath) ||
02140 bFoundPathWithController && (*pPath) != pNode
02141 )
02142 {
02143 if (FoundOnePath)
02144 FoundMultiple = TRUE;
02145 else
02146 {
02147 if (bFoundPathWithController)
02148 {
02149 if (!(*pPath)->AllowOp(&ObjDeleteChange, FALSE))
02150 {
02151 *pPath = NULL;
02152 }
02153 else
02154 {
02155 FoundOnePath = TRUE;
02156 }
02157 }
02158 else if (pNode->AllowOp(&ObjDeleteChange,FALSE))
02159 {
02160 FoundOnePath = TRUE;
02161 *pPath = (NodePath*)pNode;
02162 }
02163 }
02164 }
02165
02166 pNode = Selected->FindNext(pNode);
02167 }
02168
02169
02170 if (!FoundOneTextStory && (TextStory::GetFocusStory() != NULL))
02171 FoundOneTextStory = TRUE;
02172
02173 *ID = ObjDeleteChange.GetReasonForDenial();
02174
02175 if (StoryHadPath)
02176 *pPath = NULL;
02177
02178 return !FoundMultiple && ((FoundOnePath && FoundOneTextStory) || (StoryHadPath && FoundOneTextStory));
02179 }
02180
02181
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194 BOOL OpReverseStoryPath::Init()
02195 {
02196 return (RegisterOpDescriptor(0,
02197 _R(IDS_REVERSEPATHOP),
02198 CC_RUNTIME_CLASS(OpReverseStoryPath),
02199 OPTOKEN_REVERSESTORYPATH,
02200 OpReverseStoryPath::GetState));
02201 }
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214 OpState OpReverseStoryPath::GetState(String_256*, OpDescriptor*)
02215 {
02216 OpState State;
02217 State.Greyed = FALSE;
02218
02219 SelRange* Selection = GetApplication()->FindSelection();
02220 Node* pNode = Selection->FindFirst();
02221
02222 while (pNode != NULL)
02223 {
02224 if (IS_A(pNode,TextStory))
02225 {
02226 TextStory* pTS = (TextStory*)pNode;
02227 if (pTS->GetTextPath()==NULL )
02228 {
02229 State.Greyed = TRUE;
02230 break;
02231 }
02232 }
02233
02234 pNode = Selection->FindNext(pNode);
02235 }
02236
02237 return State;
02238 }
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252 void OpReverseStoryPath::Do(OpDescriptor*)
02253 {
02254 SelRange* pSelection = GetApplication()->FindSelection();
02255 Node* pNode = pSelection->FindFirst();
02256 BOOL ok = TRUE;
02257
02258 if (ok && (pNode != NULL))
02259 ok = DoStartTextOp(NULL);
02260
02261 while (ok && (pNode != NULL))
02262 {
02263 if (IS_A(pNode,TextStory))
02264 {
02265 NodePath* pPath = ((TextStory*)pNode)->GetTextPath();
02266
02267 if (pPath != NULL)
02268 {
02269 ObjChangeParam ObjEdit(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
02270 if (pNode->AllowOp(&ObjEdit))
02271 ok = ReversePathAction::DoReversePath(this, &UndoActions, (TextStory*)pNode);
02272 }
02273 }
02274
02275 pNode = pSelection->FindNext(pNode);
02276 }
02277
02278
02279 if (ok)
02280 {
02281 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
02282 ok = UpdateChangedNodes(&ObjChange);
02283 }
02284
02285
02286 if (ok)
02287 pSelection->Update();
02288
02289
02290 if (!ok)
02291 {
02292 FailAndExecute();
02293 InformError();
02294 }
02295
02296 End();
02297 }
02298
02299 #endif
02300
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312 PrePostTextAction::PrePostTextAction()
02313 {
02314 HasEffect = TRUE;
02315 pTextStoryToReformat = NULL;
02316 CaretContextNode = NULL;
02317 CaretAttachDir = PREV;
02318 }
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329 PrePostTextAction::~PrePostTextAction()
02330 {
02331 }
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358 ActionCode PrePostTextAction::Init( Operation* pOp,
02359 ActionList* pActionList,
02360 TextStory* pStory,
02361 BOOL ThisActionReformats,
02362 BOOL ToTail)
02363 {
02364 UINT32 ActSize = sizeof(PrePostTextAction);
02365 PrePostTextAction* pNewAction;
02366 ActionCode Ac = Action::Init( pOp, pActionList, ActSize, CC_RUNTIME_CLASS(PrePostTextAction), (Action**)&pNewAction);
02367
02368 if (Ac==AC_OK && pNewAction!=NULL)
02369 {
02370 pNewAction->m_bToTail = ToTail;
02371
02372 pNewAction->HasEffect = ThisActionReformats;
02373 pNewAction->pTextStoryToReformat = pStory;
02374
02375
02376
02377 CaretNode* pCaret = pStory->GetCaret();
02378 ERROR2IF(pCaret==NULL,AC_FAIL,"PrePostTextAction::Init() - story has no caret");
02379 pNewAction->CaretAttachDir = PREV;
02380 pNewAction->CaretContextNode = pCaret->FindNextVTNInLine();
02381 if (pNewAction->CaretContextNode==NULL)
02382 {
02383 pNewAction->CaretAttachDir = NEXT;
02384 pNewAction->CaretContextNode = pCaret->FindPrevVTNInLine();
02385 ERROR2IF(pNewAction->CaretContextNode==NULL,AC_FAIL,"PrePostTextAction::Init() - could find no context node for caret!");
02386 }
02387
02388
02389 if (ToTail)
02390 {
02391 pStory->FlagNodeAndDescendantsModifiedByOpAndParentsHaveDescendantModifiedByOp();
02392 pStory->FormatAndChildren(NULL,FALSE);
02393
02394
02395
02396 pActionList->RemoveItem(pNewAction);
02397 pActionList->AddHead(pNewAction);
02398 }
02399 }
02400
02401 return Ac;
02402 }
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416 BOOL PrePostTextAction::DoFormatStory(UndoableOperation* pUndoOp, TextStory* pStory,
02417 BOOL ToTail)
02418 {
02419 ERROR2IF(pUndoOp==NULL,FALSE,"PrePostTextAction::DoFormatStory() - NULL operation pointer");
02420 ERROR2IF( pStory==NULL,FALSE,"PrePostTextAction::DoFormatStory() - NULL story pointer");
02421
02422
02423 BOOL ok = pStory->FormatAndChildren(pUndoOp,!ToTail);
02424
02425
02426 ActionList* pActionList = pUndoOp->GetUndoActionList();
02427 ERROR2IF(pActionList==NULL,FALSE,"PrePostTextAction::DoFormatStory() - pActionList==NULL");
02428 if (ok) ok = (Init(pUndoOp, pActionList, pStory, FALSE, ToTail) != AC_FAIL);
02429
02430 return ok;
02431 }
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445 ActionCode PrePostTextAction::Execute()
02446 {
02447 ERROR3IF(pTextStoryToReformat == NULL, "The TextStory pointer is NULL");
02448
02449
02450 ActionCode Act;
02451 Act = PrePostTextAction::Init(pOperation,
02452 pOppositeActLst,
02453 pTextStoryToReformat,
02454 !HasEffect,
02455 m_bToTail);
02456
02457 if (Act == AC_FAIL)
02458 return AC_FAIL;
02459
02460 if (pTextStoryToReformat == NULL)
02461 return Act;
02462
02463 if (pTextStoryToReformat->FindParent() == NULL)
02464
02465 return Act;
02466
02467
02468 if (HasEffect && pTextStoryToReformat!=NULL)
02469 {
02470
02471 pTextStoryToReformat->MoveCaretToCharacter(CaretContextNode, CaretAttachDir);
02472
02473 if (!pTextStoryToReformat->FormatAndChildren(NULL,FALSE,FALSE))
02474 return AC_FAIL;
02475 }
02476 return Act;
02477 }
02478
02479 #if !defined(EXCLUDE_FROM_RALPH)
02480
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502 void OpTextCaret::DoMoveCaretLeft(BOOL WithSelect, BOOL AWord)
02503 {
02504
02505 BOOL Success = TRUE;
02506 if (!PreCaretMove())
02507 {
02508 Success = FALSE;
02509 goto DoneMovement;
02510 }
02511
02512 if (WithSelect)
02513 {
02514 BOOL MoveSelection = TRUE;
02515 VisibleTextNode* pSelEnd = pCaret;
02516 VisibleTextNode* pSelStart = pOtherSelEnd;
02517
02518
02519 if (AWord)
02520 {
02521
02522 if (SelToRightOfCaret && pSelStart->IsAnEOLNode())
02523 {
02524 pSelStart = pSelStart->FindPrevVTNInStory();
02525 MoveSelection = FALSE;
02526 }
02527 else
02528 pSelStart = pStory->GetPrevWordChar(pSelStart);
02529 }
02530 else
02531 {
02532 VisibleTextNode* pTemp = pSelStart->FindPrevVTNInStory();
02533 if (pTemp != NULL)
02534 pSelStart = pTemp;
02535 }
02536
02537 ERROR3IF(pSelStart == NULL, "Failed to find selection start");
02538 ERROR3IF(pSelEnd == NULL, "Failed to find selection end (where's the caret!)");
02539 VisibleTextNode* pScrollTo = pSelStart;
02540 if ((pSelStart != NULL) && (pSelEnd != NULL))
02541 {
02542
02543
02544 VisibleTextNode* pPrev = pSelStart->FindPrevVTNInStory();
02545 if ((pPrev != NULL) && (pSelStart != pSelEnd) && (pPrev->IsSelected() || pPrev->IsACaret()))
02546 {
02547 VisibleTextNode* pTemp = pSelEnd;
02548 pSelEnd = pSelStart;
02549 pSelStart = pTemp;
02550 pTemp = pSelEnd->FindPrevVTNInStory();
02551 if (AWord && MoveSelection && (pTemp != NULL) && !pSelEnd->IsAnEOLNode())
02552 pSelEnd = pTemp;
02553 pScrollTo = pSelEnd;
02554 }
02555
02556
02557 pScrollTo->ScrollToShow();
02558 OpTextCaret::SelectStoryCharacters(pSelStart, pSelEnd, pStory, pCaret);
02559 }
02560 }
02561 else
02562 {
02563
02564 if (pStory->GetSelectionEnd() != NULL)
02565 MoveCaretToSelectionEnd(TRUE);
02566 else
02567 {
02568 if (pCaret->FindPrevVTNInStory() != NULL)
02569 {
02570 NodeRenderableInk::DeselectAll(TRUE, FALSE);
02571 if (AWord)
02572 Success = pStory->MoveCaretLeftAWord();
02573 else
02574 Success = pStory->MoveCaretLeftAChar();
02575 pCaret->ScrollToShow();
02576 pCaret->Select(TRUE);
02577 }
02578 }
02579 }
02580
02581 DoneMovement:
02582 if (!Success)
02583 {
02584 FailAndExecute();
02585 InformError();
02586 }
02587
02588 CompleteOperation();
02589 }
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605 void OpTextCaret::DoMoveCaretRight(BOOL WithSelect, BOOL AWord)
02606 {
02607 BOOL Success = TRUE;
02608 if (!PreCaretMove())
02609 {
02610 Success = FALSE;
02611 goto DoneMovement;
02612 }
02613
02614 if (WithSelect)
02615 {
02616 VisibleTextNode* pSelEnd = pCaret;
02617 VisibleTextNode* pSelStart = pOtherSelEnd;
02618
02619
02620 if (AWord)
02621 {
02622
02623
02624 if (pSelStart->IsAnEOLNode() && SelToRightOfCaret)
02625 pSelStart = pStory->GetNextWordChar(pSelStart);
02626 pSelStart = pSelStart->FindNextVTNInStory();
02627 pSelStart = pStory->GetNextWordChar(pSelStart);
02628 }
02629 else
02630 pSelStart = pSelStart->FindNextVTNInStory();
02631
02632 ERROR3IF(pSelStart == NULL, "Failed to find slection start");
02633 ERROR3IF(pSelEnd == NULL, "Failed to find slection end (where's the caret!)");
02634 VisibleTextNode* pScrollTo = pSelStart;
02635 if ((pSelStart != NULL) && (pSelEnd != NULL))
02636 {
02637
02638
02639 VisibleTextNode* pNext = pSelStart->FindNextVTNInStory();
02640 if ((pNext == NULL) || (pNext != NULL) && (pSelStart != pSelEnd) && (pNext != pSelEnd) && !pNext->IsSelected())
02641 {
02642 VisibleTextNode* pTemp = pSelEnd;
02643 pSelEnd = pSelStart;
02644 pSelStart = pTemp;
02645 if (AWord && (pSelEnd->FindPrevVTNInStory() != NULL) && (pSelEnd->FindNext() != pStory->FindLastVTN()))
02646 pSelEnd = pSelEnd->FindPrevVTNInStory();
02647 pScrollTo = pSelEnd;
02648 }
02649
02650
02651 pScrollTo->ScrollToShow();
02652 OpTextCaret::SelectStoryCharacters(pSelStart, pSelEnd, pStory, pCaret);
02653 }
02654 }
02655 else
02656 {
02657
02658 if (pStory->GetSelectionEnd() != NULL)
02659 MoveCaretToSelectionEnd(FALSE);
02660 else
02661 {
02662
02663 if (pCaret->FindNextVTNInStory() != pStory->FindLastVTN())
02664 {
02665 NodeRenderableInk::DeselectAll(TRUE,FALSE);
02666 if (AWord)
02667 pStory->MoveCaretRightAWord();
02668 else
02669 pStory->MoveCaretRightAChar();
02670 pCaret->ScrollToShow();
02671 pCaret->Select(TRUE);
02672 }
02673 }
02674 }
02675
02676 DoneMovement:
02677 if (!Success)
02678 {
02679 FailAndExecute();
02680 InformError();
02681 }
02682
02683 CompleteOperation();
02684 }
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696 void OpTextCaret::DoMoveCaretUp(BOOL WithSelect)
02697 {
02698 BOOL Success = TRUE;
02699 if (!PreCaretMove())
02700 {
02701 Success = FALSE;
02702 goto DoneMovement;
02703 }
02704
02705 if (WithSelect)
02706 {
02707 VisibleTextNode* pSelEnd = pCaret;
02708 VisibleTextNode* pSelStart = pOtherSelEnd;
02709
02710
02711 BOOL SelToLeftOfNewEnd = TRUE;
02712 pSelStart = GetCharacterLineChange(pSelStart, SelToRightOfCaret, &SelToLeftOfNewEnd, TRUE);
02713
02714 if (pSelStart == NULL)
02715 {
02716 DoMoveCaretHome(TRUE, TRUE);
02717 return;
02718 }
02719 else
02720 {
02721 ERROR3IF(pSelEnd == NULL, "Failed to find slection end (where's the caret!)");
02722 if ((pSelStart != NULL) && (pSelEnd != NULL))
02723 {
02724 if (!SelToLeftOfNewEnd && (pSelStart->FindNextVTNInStory() != NULL))
02725 pSelStart = pSelStart->FindNextVTNInStory();
02726 VisibleTextNode* pScrollTo = pSelStart;
02727
02728
02729 VisibleTextNode* pPrev = pSelStart->FindPrevVTNInStory();
02730 if ((pPrev != NULL) && (pSelStart != pSelEnd) && (pPrev->IsSelected() || pPrev->IsACaret()))
02731 {
02732 VisibleTextNode* pTemp = pSelEnd;
02733 pSelEnd = pSelStart;
02734 pSelStart = pTemp;
02735 if (pSelEnd->FindPrevVTNInStory() != NULL)
02736 pSelEnd = pSelEnd->FindPrevVTNInStory();
02737 pScrollTo = pSelEnd;
02738 }
02739
02740
02741 pScrollTo->ScrollToShow();
02742 OpTextCaret::SelectStoryCharacters(pSelStart, pSelEnd, pStory, pCaret);
02743 }
02744 }
02745 }
02746 else
02747 {
02748 if (pStory->GetSelectionEnd() != NULL)
02749 MoveCaretToSelectionEnd(TRUE);
02750 else
02751 {
02752 BOOL ToLeft = FALSE;
02753 VisibleTextNode* pNewPos = GetCharacterLineChange(pCaret, TRUE, &ToLeft, TRUE);
02754
02755 if (pNewPos != NULL)
02756 {
02757 NodeRenderableInk::DeselectAll(TRUE,FALSE);
02758 pStory->MoveCaretToCharacter(pNewPos, ToLeft?PREV:NEXT);
02759 pCaret->ScrollToShow();
02760 pCaret->Select(TRUE);
02761 }
02762 }
02763 }
02764
02765 DoneMovement:
02766 if (!Success)
02767 {
02768 FailAndExecute();
02769 InformError();
02770 }
02771
02772 CompleteOperation();
02773 }
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786 void OpTextCaret::DoMoveCaretDown(BOOL WithSelect)
02787 {
02788 BOOL Success = TRUE;
02789 if (!PreCaretMove())
02790 {
02791 Success = FALSE;
02792 goto DoneMovement;
02793 }
02794
02795 if (WithSelect)
02796 {
02797
02798 VisibleTextNode* pSelEnd = pCaret;
02799 VisibleTextNode* pSelStart = pOtherSelEnd;
02800 VisibleTextNode* pOldSelStart = pSelStart;
02801 BOOL SelToLeftOfNewEnd = TRUE;
02802 pSelStart = GetCharacterLineChange(pSelStart, SelToRightOfCaret, &SelToLeftOfNewEnd, FALSE);
02803
02804 if (pSelStart == NULL)
02805 {
02806 DoMoveCaretEnd(TRUE, TRUE);
02807 return;
02808 }
02809 else
02810 {
02811 ERROR3IF(pSelEnd == NULL, "Failed to find selection end (where's the caret!)");
02812 if ((pSelStart != NULL) && (pSelEnd != NULL))
02813 {
02814 if (!SelToLeftOfNewEnd && (pSelStart->FindNextVTNInStory() != NULL))
02815 pSelStart = pSelStart->FindNextVTNInStory();
02816 VisibleTextNode* pScrollTo = pSelStart;
02817
02818
02819
02820 VisibleTextNode* pNext = pSelStart->FindNextVTNInStory();
02821 if ((pNext == NULL) || ((pNext != NULL) && (pSelStart != pSelEnd) && (pNext != pSelEnd) && !pNext->IsSelected()))
02822 {
02823 VisibleTextNode* pTemp = pSelEnd;
02824 pSelEnd = pSelStart;
02825 pSelStart = pTemp;
02826 VisibleTextNode *pPrev = pSelEnd->FindPrevVTNInStory();
02827 if ((pPrev != NULL) && (pPrev != pOldSelStart))
02828 pSelEnd = pPrev;
02829 pScrollTo = pSelEnd;
02830 }
02831
02832 if (pScrollTo->IsAnEOLNode() && (pScrollTo->FindNextVTNInStory() != NULL))
02833 pScrollTo = pScrollTo->FindNextVTNInStory();
02834
02835
02836 pScrollTo->ScrollToShow();
02837 OpTextCaret::SelectStoryCharacters(pSelStart, pSelEnd, pStory, pCaret);
02838 }
02839 }
02840 }
02841 else
02842 {
02843 if (pStory->GetSelectionEnd() != NULL)
02844 MoveCaretToSelectionEnd(FALSE);
02845 else
02846 {
02847 BOOL ToLeft = FALSE;
02848 VisibleTextNode* pNewPos = GetCharacterLineChange(pCaret, TRUE, &ToLeft, FALSE);
02849
02850 if (pNewPos != NULL)
02851 {
02852 NodeRenderableInk::DeselectAll(TRUE,FALSE);
02853 pStory->MoveCaretToCharacter(pNewPos, ToLeft?PREV:NEXT);
02854 pCaret->ScrollToShow();
02855 pCaret->Select(TRUE);
02856 }
02857 }
02858 }
02859
02860 DoneMovement:
02861 if (!Success)
02862 {
02863 FailAndExecute();
02864 InformError();
02865 }
02866
02867 CompleteOperation();
02868 }
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882 void OpTextCaret::DoMoveCaretHome(BOOL WithSelect, BOOL ToStoryStart)
02883 {
02884 if (!PreCaretMove())
02885 {
02886 FailAndExecute();
02887 InformError();
02888 End();
02889 return;
02890 }
02891
02892 VisibleTextNode* pMoveChar = pStory->GetSelectionEnd();
02893 if (ToStoryStart)
02894 pMoveChar = pStory->FindFirstVTN();
02895 else
02896 {
02897 if (pMoveChar == NULL)
02898 pMoveChar = GetLineStartCharacter(pCaret);
02899 else
02900 pMoveChar = GetLineStartCharacter(pMoveChar);
02901 }
02902
02903 if (pMoveChar == NULL)
02904 return ;
02905
02906 if (WithSelect)
02907 {
02908
02909 VisibleTextNode* pSelEndChar = pCaret;
02910 VisibleTextNode* pSelStartChar = (VisibleTextNode*)pMoveChar;
02911 if ((pSelEndChar != NULL) && (pSelStartChar != NULL))
02912 {
02913
02914 if (pSelStartChar != pSelEndChar)
02915 {
02916 VisibleTextNode* pChar = pSelEndChar;
02917 while (pChar != NULL)
02918 {
02919 if (pChar == pSelStartChar)
02920 {
02921 pSelStartChar = pCaret->FindNextVTNInStory();
02922 pSelEndChar = pChar->FindPrevVTNInStory();
02923 break;
02924 }
02925
02926 pChar = pChar->FindNextVTNInStory();
02927 }
02928
02929 if (pChar==NULL)
02930 pSelEndChar = pCaret->FindPrevVTNInStory();
02931 }
02932
02933 if (pSelStartChar != NULL)
02934 pSelStartChar->ScrollToShow();
02935 SelectStoryCharacters(pSelStartChar, pSelEndChar, pStory, pCaret);
02936 }
02937 }
02938 else
02939 {
02940 NodeRenderableInk::DeselectAll(TRUE,FALSE);
02941 if (pMoveChar != pCaret)
02942 pStory->MoveCaretToCharacter(pMoveChar, PREV);
02943 pCaret->ScrollToShow();
02944 pCaret->Select(TRUE);
02945 }
02946
02947 CompleteOperation();
02948 }
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961 void OpTextCaret::DoMoveCaretEnd(BOOL WithSelect, BOOL ToStoryEnd)
02962 {
02963 if (!PreCaretMove())
02964 {
02965 FailAndExecute();
02966 InformError();
02967 End();
02968 return;
02969 }
02970
02971 VisibleTextNode* pMoveChar = pStory->GetSelectionEnd();
02972 if (ToStoryEnd)
02973 pMoveChar = pStory->FindLastVTN();
02974 else
02975 {
02976 if (pMoveChar == NULL)
02977 pMoveChar = GetLineEndCharacter(pCaret);
02978 else
02979 pMoveChar = GetLineEndCharacter(pMoveChar);
02980 }
02981
02982 if (pMoveChar == NULL)
02983 return ;
02984
02985 if (WithSelect)
02986 {
02987
02988 VisibleTextNode* pSelStartChar = pCaret;
02989 VisibleTextNode* pSelEndChar = pMoveChar->FindPrevVTNInStory();
02990 if (pSelEndChar == NULL)
02991 pSelEndChar = pMoveChar;
02992
02993 if (pSelStartChar != pSelEndChar)
02994 {
02995
02996 VisibleTextNode* pChar = pSelEndChar;
02997 while (pChar != NULL)
02998 {
02999 if (pChar == pSelStartChar)
03000 {
03001 pSelStartChar = pSelEndChar->FindNextVTNInStory();
03002 pSelEndChar = pCaret->FindPrevVTNInStory();
03003 break;
03004 }
03005
03006 pChar = pChar->FindNextVTNInStory();
03007 }
03008 if (pChar == NULL)
03009 pSelStartChar = pCaret->FindNextVTNInStory();
03010 }
03011
03012 if (pSelEndChar != NULL)
03013 pSelEndChar->ScrollToShow();
03014
03015 SelectStoryCharacters(pSelStartChar, pSelEndChar, pStory, pCaret);
03016 }
03017 else
03018 {
03019 NodeRenderableInk::DeselectAll(TRUE,FALSE);
03020 if (pMoveChar != pCaret)
03021 {
03022 if (pMoveChar->IsAnEOLNode())
03023 pStory->MoveCaretToCharacter(pMoveChar, PREV);
03024 else
03025 pStory->MoveCaretToCharacter(pMoveChar, NEXT);
03026 }
03027 pCaret->ScrollToShow();
03028 pCaret->Select(TRUE);
03029 }
03030
03031 CompleteOperation();
03032 }
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045 BOOL OpTextCaret::PreCaretMove()
03046 {
03047
03048 ERROR2IF(pStory == NULL, FALSE, "(OpTextCaret::DoMoveCaretLeft) pStory was NULL");
03049 ERROR2IF(pCaret == NULL, FALSE, "(OpTextCaret::DoMoveCaretLeft) pCaret was NULL");
03050
03051 GetApplication()->FindSelection()->SetGag(TRUE);
03052
03053 return TRUE;
03054 }
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067 void OpTextCaret::DoSelectWordAtCaret()
03068 {
03069
03070 if (!PreCaretMove())
03071 {
03072 InformError();
03073 FailAndExecute();
03074 End();
03075 return;
03076 }
03077
03078 NodeRenderableInk::DeselectAll(TRUE,FALSE);
03079 DialogManager::DefaultKeyboardFocus();
03080
03081
03082 VisibleTextNode* pPrevWordStart = pStory->GetPrevWordChar(pCaret);
03083 if (pPrevWordStart==NULL)
03084 {
03085 ERROR3("OpTextCaret::DoSelectWordAtCaret() - failed to find start of previous word!");
03086 return;
03087 }
03088 if (pPrevWordStart!=pCaret)
03089 pStory->MoveCaretToCharacter(pPrevWordStart, PREV);
03090
03091
03092 VisibleTextNode* pNextWordStart = pStory->GetNextWordChar(pPrevWordStart);
03093 if (pNextWordStart==NULL)
03094 {
03095 ERROR3("OpTextCaret::DoSelectWordAtCaret() - failed to find start of next word!");
03096 return;
03097 }
03098
03099 #ifdef SELECT_CARET_AND_CHARS
03100
03101 pCaret->Select(TRUE);
03102 #endif
03103
03104
03105 VisibleTextNode* pVTN = pPrevWordStart;
03106 while (pVTN!=NULL && pVTN!=pNextWordStart)
03107 {
03108 if (!pVTN->IsAnEOLNode())
03109 pVTN->Select(TRUE);
03110 pVTN = pVTN->FindNextVTNInStory();
03111 ERROR3IF(pVTN==NULL,"OpTextCaret::DoSelectWordAtCaret() - never found pNextWordStart");
03112 }
03113
03114 GetApplication()->FindSelection()->SetGag(FALSE);
03115 CompleteOperation();
03116 }
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127 OpTextCaret::OpTextCaret()
03128 {
03129
03130 pStory = TextStory::GetFocusStory();
03131 ERROR3IF(pStory == NULL, "OpTextCaret created without a focus story");
03132
03133
03134 if (pStory != NULL)
03135 {
03136 pCaret = pStory->GetCaret();
03137 pOtherSelEnd = pStory->GetSelectionEnd(&SelToRightOfCaret);
03138
03139
03140 if (pOtherSelEnd == NULL)
03141 pOtherSelEnd = pCaret;
03142 }
03143 else
03144 {
03145 pCaret = NULL;
03146 pOtherSelEnd = NULL;
03147 }
03148
03149
03150 PreviousVerticalInset = VertInset;
03151 VertInset.LastInset = VERTICALMOVEINSET_NONE;
03152 VertInset.HoldingInset = VERTICALMOVEINSET_NONE;
03153 }
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166 void OpTextCaret::MoveCaretToSelectionEnd(BOOL MoveToLeft)
03167 {
03168 ERROR3IF(pStory == NULL, "pStory was NULL");
03169 ERROR3IF(pCaret == NULL, "pCaret was NULL");
03170
03171 if ((pStory != NULL) && (pCaret != NULL) )
03172 {
03173 BOOL SelToRightOfCaret = TRUE;
03174 VisibleTextNode* pSelEnd = pStory->GetSelectionEnd(&SelToRightOfCaret);
03175 ERROR3IF(pSelEnd == NULL, "Who cleared the selection before calling MoveCaretToSelectionEnd?");
03176
03177
03178 NodeRenderableInk::DeselectAll(TRUE,FALSE);
03179 if ((pSelEnd != NULL) && (MoveToLeft != SelToRightOfCaret))
03180 {
03181 if (pSelEnd->IsAnEOLNode())
03182 pStory->MoveCaretToCharacter(pSelEnd, PREV);
03183 else
03184 pStory->MoveCaretToCharacter(pSelEnd, MoveToLeft?PREV:NEXT);
03185 }
03186 pCaret->ScrollToShow();
03187 pCaret->Select(TRUE);
03188 }
03189 }
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202 void OpTextCaret::CompleteOperation()
03203 {
03204 GetApplication()->UpdateSelection();
03205
03206 End();
03207 }
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225 void OpTextCaret::SelectStoryCharacters(VisibleTextNode* pFirstToSel, VisibleTextNode* pLastToSel,
03226 TextStory* pStory, CaretNode* pCaret)
03227 {
03228 ERROR3IF(pStory == NULL, "Story pointer was NULL");
03229 if ((pFirstToSel == NULL) || (pLastToSel == NULL) || (pStory == NULL))
03230 return;
03231
03232
03233 if (pCaret == NULL)
03234 pCaret = pStory->GetCaret();
03235
03236 BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
03237 if (pBlobMgr == NULL)
03238 return;
03239
03240
03241 if (pFirstToSel != pLastToSel)
03242 {
03243 if (pFirstToSel->IsACaret())
03244 pFirstToSel = pFirstToSel->FindNextVTNInStory();
03245 else if (pLastToSel->IsACaret())
03246 pLastToSel = pLastToSel->FindPrevVTNInStory();
03247 }
03248
03249
03250 if (pLastToSel == pFirstToSel->FindPrevVTNInStory())
03251 {
03252 VisibleTextNode* pTemp = pFirstToSel;
03253 pFirstToSel = pLastToSel;
03254 pLastToSel = pTemp;
03255 }
03256
03257 Spread* pSpread = pStory->FindParentSpread();
03258
03259
03260 RenderRegionList* pRegionList = GetApplication()->GetRegionList();
03261 BOOL UseBlobMgr = !pRegionList->IsEmpty();
03262
03263 RenderRegion* pRegion = NULL;
03264
03265
03266 if (!UseBlobMgr)
03267 pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR );
03268
03269 while ( UseBlobMgr || pRegion != NULL )
03270 {
03271
03272 BOOL Select = FALSE;
03273 VisibleTextNode* pChar = pStory->FindFirstVTN();
03274 VisibleTextNode* pNextChar;
03275 while (pChar != NULL)
03276 {
03277 if (pChar == pFirstToSel)
03278 Select = TRUE;
03279
03280
03281 pNextChar = pChar->FindNextVTNInStory();
03282 if (pNextChar == NULL)
03283 Select = FALSE;
03284
03285 if (Select)
03286 {
03287 if (!pChar->IsSelected())
03288 {
03289 pChar->SetSelected(TRUE);
03290
03291 if (UseBlobMgr)
03292 pBlobMgr->RenderObjectBlobsOn(NULL, pSpread, pChar);
03293 else
03294 pChar->RenderObjectBlobs(pRegion);
03295 }
03296 }
03297 else
03298 {
03299 if (pChar->IsSelected())
03300 {
03301 if (UseBlobMgr)
03302 pBlobMgr->RenderObjectBlobsOff(NULL, pSpread, pChar);
03303 else
03304 pChar->RenderObjectBlobs(pRegion);
03305
03306 pChar->SetSelected(FALSE);
03307 }
03308 }
03309
03310 if (pChar == pLastToSel)
03311 Select = FALSE;
03312
03313 pChar = pNextChar;
03314
03315 }
03316
03317
03318 if (UseBlobMgr)
03319 UseBlobMgr = FALSE;
03320 else
03321 pRegion = DocView::GetNextOnTop(NULL);
03322 }
03323
03324 GetApplication()->UpdateSelection();
03325
03326 #ifdef SELECT_CARET_AND_CHARS
03327
03328 pCaret->Select(TRUE);
03329 #else
03330
03331 if (pStory->GetSelectionEnd() == NULL)
03332 pCaret->Select(TRUE);
03333 #endif
03334
03335 }
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358 VisibleTextNode* OpTextCaret::GetCharacterLineChange(VisibleTextNode* pCharacter, BOOL ToLeftOfChar,
03359 BOOL* NewToLeft, BOOL MoveUp)
03360 {
03361 ERROR2IF(pCharacter == NULL, NULL, "NULL entry param");
03362
03363
03364 TextLine* pCurrentLine = pCharacter->FindParentLine();
03365 ERROR2IF(pCurrentLine == NULL, NULL, "Character didn't have a parent text line");
03366 TextLine* pNewLine = NULL;
03367 if (MoveUp)
03368 pNewLine = pCurrentLine->FindPrevLine();
03369 else
03370 pNewLine = pCurrentLine->FindNextLine();
03371
03372
03373 VisibleTextNode* pResult = NULL;
03374 if (pNewLine != NULL)
03375 {
03376
03377 MILLIPOINT CurrentDistance = pCharacter->CalcCharDistAlongLine(ToLeftOfChar);
03378 if (PreviousVerticalInset.HoldingInset != VERTICALMOVEINSET_NONE &&
03379 PreviousVerticalInset.LastInset == CurrentDistance &&
03380 CurrentDistance != -1)
03381 {
03382 CurrentDistance = PreviousVerticalInset.HoldingInset;
03383 }
03384 else
03385 {
03386 PreviousVerticalInset.HoldingInset = VERTICALMOVEINSET_NONE;
03387 }
03388
03389
03390 if (CurrentDistance != -1)
03391 pResult = pNewLine->FindCharAtDistAlongLine(CurrentDistance, NewToLeft);
03392
03393
03394 if (pResult != NULL)
03395 {
03396 if (PreviousVerticalInset.HoldingInset != VERTICALMOVEINSET_NONE)
03397 VertInset.HoldingInset = PreviousVerticalInset.HoldingInset;
03398 else
03399 VertInset.HoldingInset = CurrentDistance;
03400 VertInset.LastInset = pResult->CalcCharDistAlongLine(!*NewToLeft);
03401 }
03402 }
03403
03404 return pResult;
03405 }
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419 VisibleTextNode* OpTextCaret::GetLineStartCharacter(VisibleTextNode* pCharacter)
03420 {
03421 ERROR2IF(pCharacter == NULL, NULL, "pCharacter was NULL");
03422 VisibleTextNode* pResult = NULL;
03423
03424 TextLine* pParent = pCharacter->FindParentLine();
03425 ERROR2IF(pParent == NULL, NULL, "Character didn't have a parent TextLine");
03426 pResult = pParent->FindFirstVTN();
03427
03428 ERROR2IF(pResult == NULL, NULL, "Line didn't have a VTN");
03429
03430 return pResult;
03431 }
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446 VisibleTextNode* OpTextCaret::GetLineEndCharacter(VisibleTextNode* pCharacter)
03447 {
03448 ERROR2IF(pCharacter == NULL, NULL, "pCharacter was NULL");
03449 VisibleTextNode* pResult = NULL;
03450
03451 TextLine* pParent = pCharacter->FindParentLine();
03452 ERROR2IF(pParent == NULL, NULL, "Character didn't have a parent TextLine");
03453 pResult = pParent->FindLastVTN();
03454
03455 ERROR2IF(pResult == NULL, NULL, "Line didn't have a VTN");
03456
03457 return pResult;
03458 }
03459
03460
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472 OpTextSelection::OpTextSelection()
03473 {
03474 StartSpread = NULL;
03475 pSelectionStory = NULL;
03476 }
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488 BOOL OpTextSelection::Init()
03489 {
03490 return (RegisterOpDescriptor(0,
03491 _R(IDS_OPTEXTSELECTION),
03492 CC_RUNTIME_CLASS(OpTextSelection),
03493 OPTOKEN_TEXTSELECTION,
03494 OpTextSelection::GetState,
03495 0,
03496 0,
03497 0,
03498 0,
03499 SYSTEMBAR_ILLEGAL,
03500 TRUE,
03501 FALSE,
03502 FALSE,
03503 0,
03504 GREY_WHEN_NO_CURRENT_DOC
03505 ));
03506 }
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521 OpState OpTextSelection::GetState(String_256* Description, OpDescriptor*)
03522 {
03523 OpState Blobby;
03524
03525 return Blobby;
03526 }
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542 BOOL OpTextSelection::DoDrag( DocCoord Anchor, Spread *pSpread, ClickModifiers ClickMods,
03543 Node* pClickNode)
03544 {
03545
03546 ERROR2IF(pClickNode == NULL, FALSE, "Pointer to clicked node was NULL!");
03547 ERROR2IF(!pClickNode->IsAVisibleTextNode(), FALSE, "Clicked node was not a text character");
03548 VisibleTextNode* pClickChar = (VisibleTextNode*)pClickNode;
03549 pSelectionStory = (TextStory*)(pClickNode->FindParent(CC_RUNTIME_CLASS(TextStory)));
03550 ERROR2IF(pSelectionStory == NULL, FALSE, "Clicked character didn't have a parent TextStory");
03551 pCaret = pSelectionStory->GetCaret();
03552 ERROR2IF(pCaret == NULL, FALSE, "TextStory didn't have a caret");
03553
03554
03555 StartPoint = Anchor;
03556 StartSpread = pSpread;
03557
03558 BOOL Success = TRUE;
03559
03560
03561 DialogManager::DefaultKeyboardFocus();
03562
03563 if (ClickMods.Adjust && !ClickMods.Constrain)
03564 {
03565
03566 Success = ExtendSelection(pClickChar, Anchor);
03567 End();
03568 return Success;
03569 }
03570 else
03571 {
03572 if (ClickMods.Constrain)
03573 {
03574
03575 Success = InitialCaretPosition(pClickChar) && SelectLine();
03576 End();
03577 return Success;
03578 }
03579 else
03580 {
03581
03582 Success = InitialCaretPosition(pClickChar);
03583 }
03584 }
03585
03586 if (Success)
03587 Success = StartDrag( DRAGTYPE_AUTOSCROLL );
03588
03589 return Success;
03590 }
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605 void OpTextSelection::DragPointerMove( DocCoord PointerPos, ClickModifiers ClickMods,
03606 Spread *pSpread, BOOL bSolidDrag)
03607 {
03608 ERROR3IF(((pSelectionStory == NULL) || (pCaret == NULL)), "A pointer was NULL");
03609 BOOL Success = TRUE;
03610
03611
03612
03613 if (pSpread != StartSpread)
03614 PointerPos = MakeRelativeToSpread(StartSpread, pSpread, PointerPos);
03615
03616
03617 VisibleTextNode* pFirstToSel = NULL;
03618 VisibleTextNode* pLastToSel = NULL;
03619 BOOL Ignore = FALSE;
03620 if (pSelectionStory->GetTextPath() != NULL)
03621 Success = GetNewSelEndsOnPath(PointerPos, &pFirstToSel, &pLastToSel, &Ignore);
03622 else
03623 Success = GetNewSelEndsInStory(PointerPos, &pFirstToSel, &pLastToSel);
03624
03625
03626 if (!Success || (pFirstToSel == NULL) || (pLastToSel == NULL))
03627 {
03628 if ((!pCaret->IsSelected() || (pSelectionStory->GetSelectionEnd() != NULL)) && !Ignore)
03629 {
03630 NodeRenderableInk::DeselectAll(TRUE,FALSE);
03631 pCaret->Select(TRUE);
03632 }
03633 }
03634 else
03635 {
03636 OpTextCaret::SelectStoryCharacters(pFirstToSel, pLastToSel, pSelectionStory, pCaret);
03637 }
03638
03639 if (!Success)
03640 {
03641 InformError();
03642 FailAndExecute();
03643 EndDrag();
03644 End();
03645 }
03646 }
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663 void OpTextSelection::DragFinished( DocCoord PointerPos, ClickModifiers ClickMods,
03664 Spread *pSpread, BOOL Success, BOOL bSolidDrag)
03665 {
03666 BOOL Worked = TRUE;
03667
03668
03669 if (Worked)
03670 Worked = EndDrag();
03671
03672
03673 BOOL Direction;
03674 if ((!Success) || (pSelectionStory->GetSelectionEnd(&Direction) == NULL) )
03675 {
03676 if ((pSelectionStory->GetCaret() != NULL) && !pSelectionStory->GetCaret()->IsSelected())
03677 {
03678 NodeRenderableInk::DeselectAll(TRUE,FALSE);
03679 pSelectionStory->GetCaret()->Select(TRUE);
03680 }
03681 }
03682
03683 GetApplication()->FindSelection()->Update();
03684
03685 End();
03686 }
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705 BOOL OpTextSelection::GetNewSelEndsOnPath(DocCoord Point, VisibleTextNode** pSelStart, VisibleTextNode** pSelEnd, BOOL* pIgnore)
03706 {
03707
03708 ERROR2IF(((pSelectionStory == NULL) || (pCaret == NULL)), FALSE, "Story or caret pointer was NULL");
03709 VisibleTextNode* pFirstChar = pSelectionStory->FindFirstVTN();
03710 ERROR2IF(pFirstChar == NULL, FALSE, "Selection Story had no characters");
03711
03712
03713 BOOL Success = TRUE;
03714 DocRect CharBoundsInDoc;
03715 DocRect CharBoundsInChar;
03716 BOOL ToLeftOfCaret = TRUE;
03717 OpTextSelection::SelectionPos CharSelPos = NOT_NEAR;
03718 VisibleTextNode* pCurrent = pFirstChar;
03719 VisibleTextNode* pChar = NULL;
03720 while ((pCurrent != NULL) && Success)
03721 {
03722 if (pCurrent->IsAnAbstractTextChar())
03723 {
03724
03725 Success = ((AbstractTextChar*)pCurrent)->GetMetricsRectBounds(&CharBoundsInDoc);
03726
03727
03728 if (Success)
03729 {
03730 CharSelPos = IsClickToLeftHalfOfChar((AbstractTextChar*)pCurrent, Point, FALSE);
03731
03732 if (CharSelPos != NOT_NEAR)
03733 {
03734 pChar = (AbstractTextChar*)pCurrent;
03735 break;
03736 }
03737 }
03738 }
03739
03740 if (pCurrent == (VisibleTextNode*)pCaret)
03741 ToLeftOfCaret = FALSE;
03742
03743 pCurrent = pCurrent->FindNextVTNInStory();
03744 }
03745
03746
03747 if (Success && (pChar != NULL))
03748 {
03749 *pIgnore = FALSE;
03750 Success = GetNewSelBoundsChars((CharSelPos == TO_LEFT), ToLeftOfCaret, pChar, pSelStart, pSelEnd);
03751 }
03752 else
03753 {
03754 *pIgnore = TRUE;
03755 pSelStart = NULL;
03756 pSelEnd = NULL;
03757 }
03758
03759 return Success;
03760 }
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775
03776
03777 BOOL OpTextSelection::GetNewSelEndsInStory(DocCoord Point, VisibleTextNode** pSelStart, VisibleTextNode** pSelEnd)
03778 {
03779
03780 ERROR2IF(((pSelectionStory == NULL) || (pCaret == NULL)), FALSE, "Story or caret pointer was NULL");
03781
03782 BOOL ToLeftPosChar = TRUE;
03783 VisibleTextNode* pPointerChar = NULL;
03784 if (!pSelectionStory->GetCharacterAtPoint(FALSE, Point, &pPointerChar, &ToLeftPosChar))
03785 return FALSE;
03786 ERROR2IF(pPointerChar == NULL, FALSE, "GetCharacterAtPoint failed to find a character");
03787
03788
03789 VisibleTextNode* pChar = pSelectionStory->FindFirstVTN();
03790 ERROR2IF(pChar == NULL, FALSE, "Selection Story had no characters");
03791 BOOL ToLeftOfCaret = TRUE;
03792 while (pChar != NULL)
03793 {
03794 if (pChar == pCaret)
03795 {
03796 ToLeftOfCaret = FALSE;
03797 break;
03798 }
03799
03800 if (pChar == pPointerChar)
03801 {
03802 break;
03803 }
03804
03805 pChar = pChar->FindNextVTNInStory();
03806 }
03807
03808
03809 return GetNewSelBoundsChars(ToLeftPosChar, ToLeftOfCaret, pPointerChar, pSelStart, pSelEnd);
03810 }
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833 BOOL OpTextSelection::GetNewSelBoundsChars(BOOL ToLeftOfChar, BOOL ToLeftOfCaret, VisibleTextNode* pFoundChar,
03834 VisibleTextNode** pSelStart, VisibleTextNode** pSelEnd)
03835 {
03836 ERROR2IF(((pFoundChar == NULL) || (pCaret == NULL)), FALSE, "NULL Pointer found");
03837 *pSelStart = NULL;
03838 *pSelEnd = NULL;
03839
03840
03841 if (ToLeftOfCaret)
03842 {
03843
03844 if (ToLeftOfChar)
03845 *pSelStart = pFoundChar;
03846 else
03847 {
03848 *pSelStart = pFoundChar->FindNextVTNInStory();
03849 if (*pSelStart == pCaret)
03850 *pSelStart = NULL;
03851 }
03852
03853 *pSelEnd = pCaret->FindPrevVTNInStory();
03854 }
03855 else
03856 {
03857
03858 if (!ToLeftOfChar)
03859 *pSelEnd = pFoundChar;
03860 else
03861 {
03862 *pSelEnd = pFoundChar->FindPrevVTNInStory();
03863 if (*pSelEnd == pCaret)
03864 *pSelEnd = NULL;
03865 }
03866
03867 *pSelStart = pCaret->FindNextVTNInStory();
03868 }
03869
03870 return TRUE;
03871 }
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886 BOOL OpTextSelection::InitialCaretPosition(VisibleTextNode* pSelectChar)
03887 {
03888 BOOL Success = TRUE;
03889
03890
03891 NodeRenderableInk::DeselectAll(TRUE,FALSE);
03892 if (pSelectionStory!=TextStory::GetFocusStory())
03893 if (!OpDeleteTextStory::RemoveEmptyFocusStory())
03894 return FALSE;
03895
03896
03897 OpTextSelection::SelectionPos ClickPos = TO_LEFT;
03898 if (pSelectChar->IsAnAbstractTextChar())
03899 ClickPos = IsClickToLeftHalfOfChar((AbstractTextChar*)pSelectChar, StartPoint, TRUE);
03900 ERROR3IF(ClickPos == NOT_NEAR,"Selection point was not near the character claimed");
03901 if (ClickPos == TO_LEFT)
03902 pSelectionStory->MoveCaretToCharacter(pSelectChar, PREV);
03903 if (ClickPos == TO_RIGHT)
03904 pSelectionStory->MoveCaretToCharacter(pSelectChar, NEXT);
03905
03906
03907 TextStory::SetFocusStory(pSelectionStory);
03908 pSelectionStory->GetCaret()->HasMoved();
03909 pSelectionStory->GetCaret()->ScrollToShow();
03910 pSelectionStory->GetCaret()->Select(TRUE);
03911
03912 return Success;
03913 }
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930 OpTextSelection::SelectionPos OpTextSelection::IsClickToLeftHalfOfChar(AbstractTextChar* pClickChar,
03931 DocCoord ClickPoint, BOOL MustChoose)
03932 {
03933 ERROR3IF(pSelectionStory == NULL, "pSelectionStory is NULL");
03934 ERROR3IF(pClickChar == NULL, "pClickChar is NULL");
03935
03936 SelectionPos Result = NOT_NEAR;
03937
03938 if ((pSelectionStory != NULL) && (pClickChar != NULL))
03939 {
03940
03941 Matrix CharMat(0,0);
03942 if (pClickChar->GetStoryAndCharMatrix(&CharMat)!=FALSE)
03943 CharMat=CharMat.Inverse();
03944 else
03945 ERROR3("GetStoryAndCharMatrix() failed");
03946
03947
03948 CharMat.transform(&ClickPoint);
03949
03950
03951 DocRect CharRect;
03952 if (pClickChar->GetMetricsRect(&CharRect))
03953 {
03954 if (CharRect.ContainsCoord(ClickPoint) || MustChoose)
03955 {
03956 if (ClickPoint.x > ((CharRect.lo.x+CharRect.hi.x)/2))
03957 Result = TO_RIGHT;
03958 else
03959 Result = TO_LEFT;
03960 }
03961 }
03962 else
03963 ERROR3("GetMetricsRectInStory failed");
03964 }
03965
03966 return Result;
03967 }
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981 BOOL OpTextSelection::SelectLine()
03982 {
03983 ERROR2IF(pSelectionStory == NULL, FALSE, "Selection story was NULL");
03984 CaretNode* pCaret = pSelectionStory->GetCaret();
03985 ERROR2IF(pCaret == NULL, FALSE, "Selection story didn't have a caret");
03986 TextLine* pLine = pCaret->FindParentLine();
03987 ERROR2IF(pLine == NULL, FALSE, "Caret didn't have a parent TextLine");
03988
03989
03990 NodeRenderableInk::DeselectAll(TRUE,FALSE);
03991 pSelectionStory->MoveCaretToStartOfLine();
03992
03993
03994 VisibleTextNode* pFirstChar = pCaret->FindNextVTNInStory();
03995 VisibleTextNode* pLastChar = pLine->FindLastVTN();
03996
03997
03998 OpTextCaret::SelectStoryCharacters(pFirstChar, pLastChar, pSelectionStory, pCaret);
03999
04000 return TRUE;
04001 }
04002
04003
04004
04005
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016
04017
04018
04019 BOOL OpTextSelection::ExtendSelection(VisibleTextNode* pClickChar, DocCoord ClickPoint)
04020 {
04021 BOOL Success = TRUE;
04022
04023
04024 if (pSelectionStory != TextStory::GetFocusStory())
04025 {
04026 Success = InitialCaretPosition(pClickChar);
04027 }
04028 else
04029 {
04030
04031 BOOL NewForwardsDirection = TRUE;
04032
04033 CaretNode* pCaret = pSelectionStory->GetCaret();
04034 ERROR2IF(pCaret == NULL, FALSE, "Caret not found");
04035
04036
04037
04038 VisibleTextNode* pChar = pCaret->FindNextVTNInStory();
04039 while ((pChar != NULL) && (pChar != pClickChar))
04040 {
04041 pChar = pChar->FindNextVTNInStory();
04042 }
04043 if (pChar != NULL)
04044 NewForwardsDirection = TRUE;
04045 else
04046 NewForwardsDirection = FALSE;
04047
04048
04049 VisibleTextNode* pNewSelEndChar = pClickChar;
04050 SelectionPos ClickPos = TO_LEFT;
04051 if (pClickChar->IsAnAbstractTextChar())
04052 ClickPos = IsClickToLeftHalfOfChar((AbstractTextChar*)pClickChar, ClickPoint, TRUE);
04053 if (NewForwardsDirection && (ClickPos==TO_LEFT))
04054 {
04055
04056 pNewSelEndChar = pClickChar->FindPrevVTNInStory();
04057 }
04058 if (!NewForwardsDirection && (ClickPos==TO_RIGHT))
04059 {
04060
04061 pNewSelEndChar = pClickChar->FindNextVTNInStory();
04062 }
04063 if (pNewSelEndChar->IsACaret())
04064 pNewSelEndChar = NULL;
04065
04066
04067 VisibleTextNode* pSelStartChar = NULL;
04068 if (NewForwardsDirection)
04069 pSelStartChar = pCaret->FindNextVTNInStory();
04070 else
04071 {
04072 pSelStartChar = pNewSelEndChar;
04073 pNewSelEndChar = pCaret->FindPrevVTNInStory();
04074 }
04075
04076
04077 if ((pSelStartChar == NULL) || (pNewSelEndChar == NULL))
04078 {
04079 NodeRenderableInk::DeselectAll(TRUE,FALSE);
04080 pCaret->Select(TRUE);
04081 }
04082 else
04083 {
04084 OpTextCaret::SelectStoryCharacters(pSelStartChar, pNewSelEndChar, pSelectionStory, pCaret);
04085 pNewSelEndChar->ScrollToShow();
04086 }
04087 }
04088
04089 GetApplication()->UpdateSelection();
04090 return Success;
04091 }
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106 BOOL OpTextSelection::DoSelectAllText(TextStory* pStory)
04107 {
04108 ERROR2IF(pStory == NULL, FALSE, "Story pointer was NULL");
04109 CaretNode* pCaret = pStory->GetCaret();
04110 ERROR2IF(pCaret == NULL, FALSE, "Story didn't have a caret");
04111 BOOL ok = TRUE;
04112
04113 NodeRenderableInk::DeselectAll(TRUE, FALSE);
04114
04115
04116 VisibleTextNode* pStartChar = pStory->FindFirstVTN();
04117 if (ok && (pStartChar != pCaret))
04118 ok = pStory->MoveCaretToCharacter(pStartChar, PREV);
04119
04120
04121 pStartChar = pStory->FindFirstVTN();
04122 VisibleTextNode* pEndChar = pStory->FindLastVTN();
04123 if ((pStartChar == NULL) || (pEndChar == NULL))
04124 ok = FALSE;
04125
04126 if (ok)
04127 {
04128 OpTextCaret::SelectStoryCharacters(pStartChar, pEndChar, pStory, pCaret);
04129 }
04130 else
04131 {
04132 FailAndExecute();
04133 InformError();
04134 }
04135
04136 End();
04137
04138 return ok;
04139 }
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153
04154 BOOL OpTextSelection::DoSelectLineText()
04155 {
04156
04157 pSelectionStory = TextStory::GetFocusStory();;
04158 ERROR2IF(pSelectionStory == NULL, FALSE, "No focus text story");
04159 pCaret = pSelectionStory->GetCaret();
04160 ERROR2IF(pCaret == NULL, FALSE, "TextStory didn't have a caret");
04161
04162 BOOL ok = SelectLine();
04163
04164 if (!ok)
04165 {
04166 FailAndExecute();
04167 InformError();
04168 }
04169
04170 End();
04171
04172 return ok;
04173 }
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185 BOOL OpDeleteTextStory::Init()
04186 {
04187 return RegisterOpDescriptor(0,
04188 _R(IDS_DELETETEXTSTORY),
04189 CC_RUNTIME_CLASS(OpDeleteTextStory),
04190 OPTOKEN_DELETESTORY,
04191 OpDeleteTextStory::GetState);
04192 }
04193
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203
04204 OpState OpDeleteTextStory::GetState(String_256* UIDescription, OpDescriptor*)
04205 {
04206 OpState OpSt;
04207
04208 return OpSt;
04209 }
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223 void OpDeleteTextStory::DoWithParam(OpDescriptor* pOpDesc, OpParam* pParam)
04224 {
04225 TextStory* pStory = (TextStory*) (void *) pParam->Param1;
04226 if (pStory == NULL)
04227 {
04228 ERROR3("Story pointer was NULL");
04229 return;
04230 }
04231 ERROR3IF(!IS_A(pStory,TextStory),"Story pointer didn't point to a TextStory!");
04232
04233 BOOL ok = DoStartSelOp(TRUE, TRUE);
04234
04235 if (ok)
04236 ok = DoActions(this, pStory);
04237
04238 if (ok)
04239 {
04240 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,ObjChangeFlags(TRUE), pStory, this);
04241 ok = UpdateChangedNodes(&ObjChange);
04242 }
04243
04244 if (!ok)
04245 {
04246 FailAndExecute();
04247 InformError();
04248 }
04249
04250 End();
04251 }
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266 BOOL OpDeleteTextStory::DoActions(UndoableOperation* pOp, TextStory* pEmptyStory)
04267 {
04268 ERROR2IF(pEmptyStory == NULL, FALSE, "Story pointer was NULL");
04269
04270 BOOL ok = TRUE;
04271
04272 ObjChangeParam ObjDeleteChange(OBJCHANGE_STARTING, ObjChangeFlags(TRUE), pEmptyStory, pOp);
04273 if (ok && pEmptyStory->AllowOp(&ObjDeleteChange))
04274 {
04275 if (pEmptyStory->GetCaret() != NULL)
04276 pEmptyStory->GetCaret()->DeSelect(TRUE);
04277
04278 if (ok)
04279 ok = pOp->DoInvalidateNodeRegion(pEmptyStory, TRUE, FALSE);
04280
04281
04282 if (ok && (pEmptyStory->GetTextPath() != NULL))
04283 {
04284 NodePath* pTextPath = pEmptyStory->GetTextPath();
04285
04286
04287 if (ok) ok = pOp->DoLocaliseCommonAttributes(pEmptyStory);
04288 if (ok) ok = pOp->DoMoveNode(pTextPath,pEmptyStory,NEXT);
04289 if (ok) pTextPath->DeSelect(FALSE);
04290
04291
04292 if (ok)
04293 ok = pOp->DoFactorOutCommonChildAttributes(pEmptyStory);
04294 }
04295
04296
04297 if (ok)
04298 ok = pOp->DoHideNode(pEmptyStory, TRUE);
04299
04300 if (ok && (TextStory::GetFocusStory() == pEmptyStory))
04301 TextStory::SetFocusStory(NULL);
04302
04303 GetApplication()->UpdateSelection();
04304 }
04305
04306 return ok;
04307 }
04308
04309
04310
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321 BOOL OpDeleteTextStory::RemoveEmptyFocusStory(UndoableOperation* pOp)
04322 {
04323 BOOL ok = TRUE;
04324 TextStory* pTS = TextStory::GetFocusStory();
04325 CaretNode* pCaret = NULL;
04326 if (pTS != NULL)
04327 pCaret = pTS->GetCaret();
04328 if ((pTS != NULL) && (pCaret != NULL))
04329 {
04330
04331 VisibleTextNode* pFirstChar = pTS->FindFirstVTN();
04332 if (pFirstChar == NULL)
04333 InformError();
04334 else
04335 {
04336 if (!IS_A(pFirstChar,TextChar))
04337 pFirstChar = pFirstChar->FindNextTextCharInStory();
04338 }
04339
04340
04341 if (pFirstChar == NULL)
04342 {
04343
04344 if (pOp == NULL)
04345 {
04346 OpDescriptor* OpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpDeleteTextStory));
04347 if (OpDesc != NULL)
04348 {
04349 OpParam p((void*)pTS,0);
04350 OpDesc->Invoke(&p);
04351 }
04352 else
04353 ok = FALSE;
04354 }
04355 else
04356 ok = OpDeleteTextStory::DoActions(pOp, pTS);
04357 }
04358 }
04359
04360 return ok;
04361 }
04362
04363 void OpDeleteTextStory::PerformMergeProcessing()
04364 {
04365 MergeWithPrevious();
04366 }
04367
04368
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381 BOOL OpApplyJustificationToStory::Init()
04382 {
04383 BOOL ok = TRUE;
04384
04385 ok = ok && RegisterOpDescriptor(0,
04386 _R(IDS_APPLYLEFTJUSTIFY),
04387 CC_RUNTIME_CLASS(OpApplyLeftJustifyToStory),
04388 OPTOKEN_APPLYLEFTJUSTIFY,
04389 OpApplyJustificationToStory::GetState);
04390 ok = ok && RegisterOpDescriptor(0,
04391 _R(IDS_APPLYCENTREJUSTIFY),
04392 CC_RUNTIME_CLASS(OpApplyCentreJustifyToStory),
04393 OPTOKEN_APPLYCENTREJUSTIFY,
04394 OpApplyJustificationToStory::GetState);
04395 ok = ok && RegisterOpDescriptor(0,
04396 _R(IDS_APPLYRIGHTJUSTIFY),
04397 CC_RUNTIME_CLASS(OpApplyRightJustifyToStory),
04398 OPTOKEN_APPLYRIGHTJUSTIFY,
04399 OpApplyJustificationToStory::GetState);
04400 ok = ok && RegisterOpDescriptor(0,
04401 _R(IDS_APPLYFULLJUSTIFY),
04402 CC_RUNTIME_CLASS(OpApplyFullJustifyToStory),
04403 OPTOKEN_APPLYFULLJUSTIFY,
04404 OpApplyJustificationToStory::GetState);
04405
04406 return ok;
04407 }
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420 OpState OpApplyJustificationToStory::GetState(String_256* pUIDesc, OpDescriptor* pOpDesc)
04421 {
04422 OpState OpSt;
04423
04424 SelRange* pSelection = GetApplication()->FindSelection();
04425 Node* pNode = pSelection->FindFirst();
04426
04427
04428 BOOL FoundSelStory = FALSE;
04429 while (pNode != NULL)
04430 {
04431 if (IS_A(pNode, TextStory))
04432 {
04433 FoundSelStory = TRUE;
04434 break;
04435 }
04436
04437 pNode = pSelection->FindNext(pNode);
04438 }
04439
04440 OpSt.Greyed = !FoundSelStory;
04441
04442 return OpSt;
04443 }
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455 void OpApplyLeftJustifyToStory::Do(OpDescriptor* pOpDesc)
04456 {
04457 AttrTxtJustification* ApplyAttrib = new AttrTxtJustification();
04458
04459 if (ApplyAttrib != NULL)
04460 {
04461 ApplyAttrib->Value.justification = JLEFT;
04462 AttributeManager::AttributeSelected(ApplyAttrib, NULL);
04463 }
04464 }
04465
04466
04467
04468
04469
04470
04471
04472
04473
04474
04475
04476 void OpApplyCentreJustifyToStory::Do(OpDescriptor* pOpDesc)
04477 {
04478 AttrTxtJustification* ApplyAttrib = new AttrTxtJustification();
04479
04480 if (ApplyAttrib != NULL)
04481 {
04482 ApplyAttrib->Value.justification = JCENTRE;
04483 AttributeManager::AttributeSelected(ApplyAttrib, NULL);
04484 }
04485 }
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497 void OpApplyRightJustifyToStory::Do(OpDescriptor* pOpDesc)
04498 {
04499 AttrTxtJustification* ApplyAttrib = new AttrTxtJustification();
04500
04501 if (ApplyAttrib != NULL)
04502 {
04503 ApplyAttrib->Value.justification = JRIGHT;
04504 AttributeManager::AttributeSelected(ApplyAttrib, NULL);
04505 }
04506 }
04507
04508
04509
04510
04511
04512
04513
04514
04515
04516
04517
04518 void OpApplyFullJustifyToStory::Do(OpDescriptor* pOpDesc)
04519 {
04520 AttrTxtJustification* ApplyAttrib = new AttrTxtJustification();
04521
04522 if (ApplyAttrib != NULL)
04523 {
04524 ApplyAttrib->Value.justification = JFULL;
04525 AttributeManager::AttributeSelected(ApplyAttrib, NULL);
04526 }
04527 }
04528
04529
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541 OpTextPaste::OpTextPaste()
04542 {
04543
04544 }
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556 BOOL OpTextPaste::Init()
04557 {
04558 return RegisterOpDescriptor(0,
04559 _R(IDS_TEXTPASTEOP),
04560 CC_RUNTIME_CLASS(OpTextPaste),
04561 OPTOKEN_TEXTPASTE,
04562 OpTextPaste::GetState,
04563 0,
04564 _R(IDBBL_TEXTPASTEOP));
04565 }
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578 OpState OpTextPaste::GetState(String_256*, OpDescriptor*)
04579 {
04580 OpState os;
04581 return os;
04582 }
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594 void OpTextPaste::Do(OpDescriptor*)
04595 {
04596 BeginSlowJob();
04597 if (!DoPasteTextHelper())
04598 FailAndExecute();
04599 End();
04600 }
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614 BOOL OpTextPaste::DoPasteTextHelper()
04615 {
04616
04617 BOOL ExternalData = FALSE;
04618 if (!InternalClipboard::PrepareForPaste(&ExternalData)) return FALSE;
04619
04620
04621 INT32 NumObjects = 0;
04622 INT32 NumStories = 0;
04623 TextStory* pFirstStory = NULL;
04624 Node* pNode = InternalClipboard::GetInsertionLayer()->FindFirstChild();
04625 while (pNode!=NULL)
04626 {
04627 NumObjects += 1;
04628 if (IS_A(pNode,TextStory))
04629 {
04630 NumStories += 1;
04631 if (pFirstStory==NULL)
04632 pFirstStory = (TextStory*)pNode;
04633 }
04634 pNode = pNode->FindNext();
04635 }
04636
04637
04638 TextStory* pFocusStory = TextStory::GetFocusStory();
04639 if (NumStories!=1 || NumObjects!=1 || pFocusStory==NULL)
04640 return DoPasteStandard(FALSE,ExternalData);
04641
04642 if (!DoStartSelOp(TRUE,TRUE))
04643 return FALSE;
04644
04645
04646 VisibleTextNode* pFirstVTN = pFocusStory->FindFirstVTN();
04647 VisibleTextNode* pLastVTN = pFocusStory->FindLastVTN();
04648 ERROR2IF(pFirstVTN==NULL || pLastVTN==NULL, FALSE,"OpTextPaste::PasteTextHelper() - Focus story has no VTN");
04649 Range pFocusStorySelection(pFirstVTN,pLastVTN,RangeControl(TRUE));
04650 ObjChangeParam ObjChange(OBJCHANGE_STARTING,ObjChangeFlags(),NULL,this);
04651 if (!pFocusStorySelection.AllowOp(&ObjChange))
04652
04653 return DoPasteStandard(FALSE,ExternalData);
04654
04655 String_256 MasterText = pFocusStory->GetStoryAsString();
04656
04657
04658 if (!pFocusStory->DeleteSelectedText(this))
04659 return FALSE;
04660
04661
04662 BaseDocument* pDoc = pFocusStory->FindOwnerDoc();
04663 ERROR2IF(pDoc==NULL,FALSE,"OpTextPaste::PasteTextHelper() - Focus story has no parent document!");
04664
04665
04666 InformDocComponentsOfOperationsOutcome(pDoc);
04667
04668
04669 BOOL ok = TRUE;
04670 CALL_WITH_FAIL((pDoc->StartComponentCopy()),this, ok)
04671 if (!ok) return FALSE;
04672 Range PasteRange;
04673 if (!DoPasteText(pFirstStory,pFocusStory,&PasteRange))
04674 return FALSE;
04675 CALL_WITH_FAIL((PasteRange.CopyComponentDataToDoc(InternalClipboard::Instance(), pDoc)), this, ok);
04676 if (!ok) return FALSE;
04677
04678
04679 if (!InternalClipboard::PasteCompleted()) return FALSE;
04680
04681 CaretNode* pCaret = pFocusStory->GetCaret();
04682 if (!DoSelectNode(pCaret,NULL)) return FALSE;
04683
04684
04685 SliceHelper::OnTextStoryChanged(pFocusStory, this, &ObjChange, MasterText);
04686
04687
04688 ObjChange.Define(OBJCHANGE_FINISHED,ObjChangeFlags(),NULL,this);
04689 if (!UpdateChangedNodes(&ObjChange))
04690 return FALSE;
04691
04692
04693 pCaret->ScrollToShow();
04694 return TRUE;
04695 }
04696
04697
04698
04699
04700
04701
04702
04703
04704
04705
04706
04707
04708
04709
04710 BOOL OpTextPaste::DoPasteText(TextStory* pPasteStory, TextStory* pFocusStory, Range* pPasteRange)
04711 {
04712 BaseDocument* pDoc = pFocusStory->FindOwnerDoc();
04713 ERROR2IF(pPasteStory==NULL, FALSE, "Null paste story passed to PasteText()");
04714 ERROR2IF(pFocusStory==NULL, FALSE, "Null focus story passed to PasteText()");
04715 UndoableOperation* pUndoOp = this;
04716
04717
04718 CaretNode* pCaret = pFocusStory->GetCaret();
04719 ERROR2IF(pCaret==NULL,FALSE,"OpTextPaste::DoPasteText() - focus story has no caret!");
04720 TextLine* pCaretLine = pCaret->FindParentLine();
04721 ERROR2IF(pCaretLine==NULL,FALSE,"OpTextPaste::DoPasteText() - caret in dest story has no parent TextLine");
04722 TextLine* pFirstSrcLine = pPasteStory->FindFirstLine();
04723 ERROR2IF(pFirstSrcLine==NULL,FALSE,"OpTextPaste::DoPasteText() - story to paste has no lines");
04724 VisibleTextNode* pCaretLineLastVTN = pCaretLine->FindLastVTN();
04725 ERROR2IF(pCaretLineLastVTN==NULL,FALSE,"OpTextPaste::DoPasteText() - Caret line has no VTN!");
04726
04727
04728 AttrTypeSet NonLineLevelAttrs;
04729 BOOL ok = pPasteStory->AddNonLineLevelDescendantAttrsToSet(&NonLineLevelAttrs);
04730 if (ok) ok = pFocusStory->AddNonLineLevelDescendantAttrsToSet(&NonLineLevelAttrs);
04731
04732
04733 VisibleTextNode* pFirstPastedVTN = NULL;
04734 VisibleTextNode* pLastPastedVTN = NULL;
04735
04736
04737
04738
04739
04740 if (ok) ok = pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,TRUE,&NonLineLevelAttrs);
04741 if (ok) ok = pFirstSrcLine->DoLocaliseCommonAttributes(NULL,FALSE,TRUE,&NonLineLevelAttrs);
04742 VisibleTextNode* pSrcVTN = pFirstSrcLine->FindFirstVTN();
04743 while (ok && pSrcVTN!=NULL)
04744 {
04745 if (!pSrcVTN->IsACaret())
04746 {
04747 VisibleTextNode* pVTNCopy = NULL;
04748 CALL_WITH_FAIL(pSrcVTN->NodeCopy((Node**)&pVTNCopy), pUndoOp, ok);
04749 if (ok) pVTNCopy->ClearSelection(TRUE);
04750 if (ok) ok = pVTNCopy->DoInsertNewNode(pUndoOp,pCaret,PREV);
04751
04752 if (ok)
04753 {
04754
04755
04756 Node* pNode = pVTNCopy->FindFirstDepthFirst();
04757 while (ok && pNode && pNode!=pVTNCopy)
04758 {
04759 if (pNode->IsRenderable())
04760 ok = ((NodeRenderable*)pNode)->CopyComponentData(InternalClipboard::Instance(), pDoc);
04761
04762 pNode = pNode->FindNextDepthFirst(pVTNCopy);
04763 }
04764 if (!ok)
04765 pDoc->AbortComponentCopy();
04766 }
04767
04768 #ifdef PHIL_ATTRS_FIX
04769
04770 if (ok) ok = pCaret->DoApplyAttrsTo(pUndoOp, pVTNCopy, FALSE);
04771 #endif
04772
04773 if (pFirstPastedVTN==NULL)
04774 pFirstPastedVTN = pVTNCopy;
04775 }
04776 pSrcVTN = pSrcVTN->FindNextVTNInLine();
04777 }
04778 if (ok) ok = pFirstSrcLine->DoFactorOutCommonChildAttributes(NULL,TRUE,&NonLineLevelAttrs);
04779 if (ok) ok = pCaretLine->DoFactorOutCommonChildAttributes(pUndoOp,TRUE,&NonLineLevelAttrs);
04780
04781
04782
04783
04784 TextLine* pNewLine = NULL;
04785 if (ok) pNewLine = new TextLine;
04786 if (ok) ok = (pNewLine!=NULL);
04787 if (ok) ok = pNewLine->DoInsertNewNode(pUndoOp,pCaretLine,NEXT);
04788 if (ok) ok = pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,NULL);
04789 if (ok) ok = pCaret->DoMoveNodes(pUndoOp,pCaretLineLastVTN,pNewLine,FIRSTCHILD);
04790 if (ok) ok = pCaretLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
04791 if (ok) ok = pNewLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
04792 pCaretLine = pNewLine;
04793
04794
04795
04796
04797 TextLine* pSrcLine = pFirstSrcLine->FindNextLine();
04798 if (pSrcLine!=NULL)
04799 {
04800 if (ok) ok = pFocusStory->DoLocaliseCommonAttributes(pUndoOp,FALSE,TRUE,NULL);
04801 if (ok) ok = pPasteStory->DoLocaliseCommonAttributes(NULL,FALSE,TRUE,NULL);
04802 while (ok && pSrcLine!=NULL)
04803 {
04804 TextLine* pLineCopy = NULL;
04805 CALL_WITH_FAIL(pSrcLine->NodeCopy((Node**)&pLineCopy), pUndoOp, ok);
04806 pLineCopy->ClearSelection(TRUE);
04807
04808 #ifndef PHIL_ATTRS_FIX
04809 CaretNode* pCaret = ((TextLine*)pLineCopy)->FindCaret();
04810 if (pCaret!=NULL)
04811 {
04812 pCaret->CascadeDelete();
04813 delete pCaret;
04814 }
04815 if (ok) ok = pLineCopy->DoInsertNewNode(pUndoOp,pCaretLine,PREV);
04816 #else
04817 CaretNode* pCopyCaret = ((TextLine*)pLineCopy)->FindCaret();
04818 if (pCopyCaret!=NULL)
04819 {
04820 pCopyCaret->CascadeDelete();
04821 delete pCopyCaret;
04822 pCopyCaret = NULL;
04823 }
04824 if (ok) ok = pLineCopy->DoInsertNewNode(pUndoOp,pCaretLine,PREV);
04825
04826
04827 VisibleTextNode* pLineNode = pLineCopy->FindFirstVTN();
04828 if (ok) ok = pLineCopy->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,NULL);
04829 if (ok) ok = pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,NULL);
04830 while (ok && pLineNode)
04831 {
04832 if (ok) ok = pCaret->DoApplyAttrsTo(pUndoOp, pLineNode, FALSE);
04833 pLineNode = pLineNode->FindNextVTNInLine();
04834 }
04835 if (ok) ok = pCaretLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
04836 if (ok) ok = pLineCopy->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,NULL);
04837 #endif
04838 pSrcLine = pSrcLine->FindNextLine();
04839 }
04840 if (ok) ok = pFocusStory->DoFactorOutCommonChildAttributes(pUndoOp,TRUE,NULL);
04841 if (ok) ok = pPasteStory->DoFactorOutCommonChildAttributes(NULL,TRUE,NULL);
04842 }
04843
04844
04845
04846
04847 if (ok)
04848 {
04849 TextLine* pLastPastedLine = pCaretLine->FindPrevLine();
04850 ERROR2IF(pLastPastedLine==NULL,FALSE,"OpTextPaste::DoPasteText() - could not find last line pasted!");
04851 EOLNode* pLastPastedEOL = pLastPastedLine->FindEOLNode();
04852 ERROR2IF(pLastPastedEOL==NULL,FALSE,"OpTextPaste::DoPasteText() - story to paste has no final EOL");
04853 pLastPastedVTN = pLastPastedEOL;
04854 if (pLastPastedEOL->IsVirtual())
04855 {
04856 pLastPastedVTN = pLastPastedVTN->FindPrevVTNInStory();
04857 ERROR2IF(pLastPastedVTN==NULL,FALSE,"OpTextPaste::DoPasteText() - no chars on pasted line which ended in a virtual EOL");
04858 if (ok) ok = pLastPastedLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,&NonLineLevelAttrs);
04859 if (ok) ok = pCaretLine->DoLocaliseCommonAttributes(pUndoOp,FALSE,FALSE,&NonLineLevelAttrs);
04860 if (ok) ok = pLastPastedEOL->DoHideNode(pUndoOp);
04861 if (ok) ok = pCaret->DoMoveNodes(pUndoOp,pCaretLineLastVTN,pLastPastedLine,LASTCHILD);
04862 if (ok) ok = pCaretLine->DoHideNode(pUndoOp);
04863 if (ok) ok = pLastPastedLine->DoFactorOutCommonChildAttributes(pUndoOp,FALSE,&NonLineLevelAttrs);
04864 }
04865 }
04866
04867
04868 if (ok)
04869 {
04870 Range r(pFirstPastedVTN, pLastPastedVTN, RangeControl(TRUE,TRUE,FALSE));
04871 *pPasteRange = r;
04872 }
04873 return ok;
04874 }
04875
04876
04878
04879
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889 BOOL OpTogglePrintTextAsShapes::Init()
04890 {
04891 return RegisterOpDescriptor(0,
04892 _R(IDS_OPTOGGLEPRINTTEXTASCURVES),
04893 CC_RUNTIME_CLASS(OpTogglePrintTextAsShapes),
04894 OPTOKEN_TOGGLEPRINTASSHAPES,
04895 OpTogglePrintTextAsShapes::GetState);
04896 }
04897
04898
04899
04900
04901
04902
04903
04904
04905
04906
04907
04908
04909 OpState OpTogglePrintTextAsShapes::GetState(String_256*, OpDescriptor*)
04910 {
04911 OpState os;
04912
04913 SelRange* pSelection = GetApplication()->FindSelection();
04914 TextStory* pStory = (TextStory*)pSelection->FindFirstObject(CC_RUNTIME_CLASS(TextStory));
04915
04916 if (pStory != NULL)
04917 {
04918 os.Greyed = FALSE;
04919 os.Ticked = pStory->IsPrintingAsShapes();
04920 }
04921 else
04922 {
04923 os.Greyed = TRUE;
04924 os.Ticked = FALSE;
04925 }
04926
04927 return os;
04928 }
04929
04930
04931
04932
04933
04934
04935
04936
04937
04938
04939
04940
04941 void OpTogglePrintTextAsShapes::Do(OpDescriptor*)
04942 {
04943 SelRange* pSelection = GetApplication()->FindSelection();
04944 TextStory* pStory = (TextStory*)pSelection->FindFirstObject(CC_RUNTIME_CLASS(TextStory));
04945
04946 if (pStory != NULL)
04947 {
04948 BOOL NewState = !pStory->IsPrintingAsShapes();
04949
04950 while (pStory != NULL)
04951 {
04952 pStory->SetPrintingAsShapes(NewState);
04953
04954 pStory = (TextStory*)pSelection->FindNextObject(CC_RUNTIME_CLASS(TextStory), pStory);
04955 }
04956 }
04957 }
04958
04959
04960
04961
04962
04963
04964
04965
04966
04967
04968 OpDragStoryIndent::OpDragStoryIndent()
04969 {
04970 mpStartSpread = NULL;
04971 mpDragStory = NULL;
04972 mpStoryPath = NULL;
04973 }
04974
04975
04976
04977
04978
04979
04980
04981
04982
04983
04984 OpDragStoryIndent::~OpDragStoryIndent()
04985 {
04986
04987 }
04988
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
04999
05000 OpState OpDragStoryIndent::GetState(String_256* Description, OpDescriptor*)
05001 {
05002 OpState apple;
05003 return apple;
05004 }
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019 BOOL OpDragStoryIndent::DoDrag( DocCoord Anchor, Spread* pSpread, ClickModifiers ClickMods, TextStory* pStory)
05020 {
05021 ERROR2IF((pSpread == NULL) || (pStory == NULL), FALSE, "NULL entry param");
05022 ERROR3IF(pSpread != pStory->FindParentSpread(), "Spread pointer didn't point to the spread the story was on. Is this bad?");
05023 BOOL ok = TRUE;
05024
05025
05026 mStartPoint = Anchor;
05027 mpStartSpread = pSpread;
05028 mpDragStory = pStory;
05029 mpStoryPath = pStory->GetTextPath();
05030
05031
05032 if (ok)
05033 {
05034 SetCurrentPos(mStartPoint, ClickMods);
05035 mStartPoint = mCurrentBlobPos;
05036 }
05037
05038
05039 DocRect Empty;
05040 Empty.MakeEmpty();
05041 RenderDragBlobs(Empty, mpStartSpread, FALSE);
05042
05043
05044 if (ok)
05045 ok = StartDrag( DRAGTYPE_AUTOSCROLL );
05046
05047 return ok;
05048 }
05049
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060
05061 void OpDragStoryIndent::DragPointerMove( DocCoord PointerPos, ClickModifiers ClickMods, Spread *pSpread, BOOL bSolidDrag)
05062 {
05063
05064 if ((mpStartSpread == NULL) || (mpDragStory == NULL))
05065 {
05066 ERROR3("A pointer was NULL");
05067 return;
05068 }
05069
05070
05071 if (pSpread != mpStartSpread)
05072 PointerPos = MakeRelativeToSpread(mpStartSpread, pSpread, PointerPos);
05073
05074
05075 DocRect Empty;
05076 Empty.MakeEmpty();
05077 RenderDraggingBlobs(Empty, mpStartSpread);
05078
05079
05080 SetCurrentPos(PointerPos, ClickMods);
05081
05082
05083 RenderDraggingBlobs(Empty, mpStartSpread);
05084
05085
05086 if (mpStoryPath==NULL)
05087 {
05088 String_256 HelpString(_R(IDS_TEXTTOOL_DRAGSTORYHANDLE));
05089 GetApplication()->UpdateStatusBarText(&HelpString);
05090 }
05091 }
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101
05102
05103
05104
05105 void OpDragStoryIndent::DragFinished( DocCoord PointerPos, ClickModifiers ClickMods, Spread *pSpread, BOOL Success, BOOL bSolidDrag)
05106 {
05107 BOOL ok = TRUE;
05108
05109
05110 DocRect Empty;
05111 Empty.MakeEmpty();
05112 RenderDragBlobs(Empty, mpStartSpread, bSolidDrag);
05113
05114 BeginSlowJob();
05115 EndDrag();
05116
05117 if (Success)
05118 {
05119 if (ok)
05120 ok = DoStartTextOp(mpDragStory, TRUE, TRUE);
05121
05122
05123 if (ok)
05124 {
05125 ObjChangeParam ObjInsert(OBJCHANGE_STARTING, ObjChangeFlags(), NULL, this);
05126 ok = mpDragStory->AllowOp(&ObjInsert);
05127 }
05128
05129
05130 if (ok)
05131 ok = StorePathIndentAction::DoStoreIndent(this, &UndoActions, mpDragStory);
05132
05133 if (ok)
05134 ok = DoIndentChange();
05135
05136 GetApplication()->FindSelection()->Update();
05137
05138
05139 if (ok)
05140 {
05141 ObjChangeParam ObjChange(OBJCHANGE_FINISHED, ObjChangeFlags(), NULL, this);
05142 ok = UpdateChangedNodes(&ObjChange);
05143 }
05144 }
05145
05146 if (!ok)
05147 FailAndExecute();
05148
05149 End();
05150 }
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163 void OpDragStoryIndent::RenderDragBlobs(DocRect ClipRect, Spread* pSpread, BOOL bSolidDrag)
05164 {
05165 DocCoord OtherIndent = GetOtherIndent();
05166
05167 if (ClipRect.IsEmpty())
05168 TextToolBlobPosList::RenderBlob(pSpread, NULL, OtherIndent);
05169 else
05170 TextToolBlobPosList::RenderBlob(pSpread, &ClipRect, OtherIndent);
05171
05172 RenderDraggingBlobs(ClipRect, pSpread);
05173 }
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184
05185
05186
05187 void OpDragStoryIndent::RenderDraggingBlobs(DocRect ClipRect, Spread* pSpread)
05188 {
05189 if (ClipRect.IsEmpty())
05190 TextToolBlobPosList::RenderBlob(pSpread, NULL, mCurrentBlobPos);
05191 else
05192 TextToolBlobPosList::RenderBlob(pSpread, &ClipRect, mCurrentBlobPos);
05193
05194
05195 if (mpStoryPath==NULL)
05196 {
05197 DocRect* pClipper = &ClipRect;
05198 if (ClipRect.IsEmpty())
05199 pClipper = NULL;
05200
05201 RenderRegion* pRegion = DocView::RenderOnTop(pClipper, pSpread, ClippedEOR);
05202 while (pRegion != NULL)
05203 {
05204
05205 pRegion->SetLineColour(COLOUR_XOREDIT);
05206 pRegion->SetFillColour(COLOUR_TRANS);
05207 pRegion->DrawLine(mCurrentBlobPos, GetOtherIndent());
05208
05209
05210 pRegion = DocView::GetNextOnTop(pClipper);
05211 }
05212 }
05213 }
05214
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224
05225
05226
05227 BOOL OpDragStoryIndent::GetLeftHandLength(MILLIPOINT* pResult)
05228 {
05229 return GetLeftHandLength(mCurrentBlobPos, mpStoryPath, pResult);
05230 }
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242
05243
05244 BOOL OpDragStoryIndent::GetRightHandLength(MILLIPOINT* pResult)
05245 {
05246 return GetRightHandLength(mCurrentBlobPos, mpStoryPath, pResult);
05247 }
05248
05249
05250
05251
05252
05253
05254
05255
05256
05257
05258
05259
05260
05261
05262 BOOL OpDragStoryIndent::GetLeftHandLength(DocCoord Coord, NodePath* pPath, MILLIPOINT* pResult)
05263 {
05264 ERROR2IF(pResult==NULL, FALSE, "NULL output parameter");
05265 *pResult = 0;
05266 ERROR2IF(pPath==NULL, FALSE, "NULL path pointer");
05267
05268 return pPath->InkPath.GetDistanceToPoint(Coord, pResult);
05269 }
05270
05271
05272
05273
05274
05275
05276
05277
05278
05279
05280
05281
05282
05283
05284 BOOL OpDragStoryIndent::GetRightHandLength(DocCoord Coord, NodePath* pPath, MILLIPOINT* pResult)
05285 {
05286 ERROR2IF(pResult==NULL, FALSE, "NULL output parameter");
05287 *pResult = 0;
05288 ERROR2IF(pPath==NULL, FALSE, "NULL path pointer");
05289
05290
05291 MILLIPOINT TotalLength = (MILLIPOINT)(pPath->InkPath.GetPathLength());
05292
05293
05294 MILLIPOINT Distance = 0;
05295 BOOL ok = pPath->InkPath.GetDistanceToPoint(Coord, &Distance);
05296
05297 *pResult = TotalLength - Distance;
05298
05299 return ok;
05300 }
05301
05302
05303
05304
05305
05306
05307
05308
05309
05310
05311
05312 BOOL OpDragStoryPathLeftIndent::Init()
05313 {
05314 return (RegisterOpDescriptor( 0,
05315 _R(IDS_OPTEXT_DRAGINDENT),
05316 CC_RUNTIME_CLASS(OpDragStoryPathLeftIndent),
05317 OPTOKEN_TEXTDRAGLEFTPATHINDENT,
05318 OpDragStoryIndent::GetState,
05319 0,
05320 0,
05321 0,
05322 0,
05323 SYSTEMBAR_ILLEGAL,
05324 TRUE,
05325 FALSE,
05326 FALSE,
05327 0,
05328 GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION | DONT_GREY_WHEN_SELECT_INSIDE
05329 ));
05330 }
05331
05332
05333
05334
05335
05336
05337
05338
05339
05340
05341 BOOL OpDragStoryPathRightIndent::Init()
05342 {
05343 return (RegisterOpDescriptor( 0,
05344 _R(IDS_OPTEXT_DRAGINDENT),
05345 CC_RUNTIME_CLASS(OpDragStoryPathRightIndent),
05346 OPTOKEN_TEXTDRAGRIGHTPATHINDENT,
05347 OpDragStoryIndent::GetState,
05348 0,
05349 0,
05350 0,
05351 0,
05352 SYSTEMBAR_ILLEGAL,
05353 TRUE,
05354 FALSE,
05355 FALSE,
05356 0,
05357 GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION | DONT_GREY_WHEN_SELECT_INSIDE
05358 ));
05359 }
05360
05361
05362
05363
05364
05365
05366
05367
05368
05369
05370 BOOL OpDragStoryNonPathLeftIndent::Init()
05371 {
05372 return (RegisterOpDescriptor( 0,
05373 _R(IDS_OPTEXT_DRAGINDENT),
05374 CC_RUNTIME_CLASS(OpDragStoryNonPathLeftIndent),
05375 OPTOKEN_TEXTDRAGLEFTNONPATHINDENT,
05376 OpDragStoryIndent::GetState,
05377 0,
05378 0,
05379 0,
05380 0,
05381 SYSTEMBAR_ILLEGAL,
05382 TRUE,
05383 FALSE,
05384 FALSE,
05385 0,
05386 GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION | DONT_GREY_WHEN_SELECT_INSIDE
05387 ));
05388 }
05389
05390
05391
05392
05393
05394
05395
05396
05397
05398
05399 BOOL OpDragStoryNonPathRightIndent::Init()
05400 {
05401 return (RegisterOpDescriptor( 0,
05402 _R(IDS_OPTEXT_DRAGINDENT),
05403 CC_RUNTIME_CLASS(OpDragStoryNonPathRightIndent),
05404 OPTOKEN_TEXTDRAGRIGHTNONPATHINDENT,
05405 OpDragStoryIndent::GetState,
05406 0,
05407 0,
05408 0,
05409 0,
05410 SYSTEMBAR_ILLEGAL,
05411 TRUE,
05412 FALSE,
05413 FALSE,
05414 0,
05415 GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION | DONT_GREY_WHEN_SELECT_INSIDE
05416 ));
05417 }
05418
05419
05420
05421
05422
05423
05424
05425
05426
05427
05428
05429
05430 BOOL OpDragStoryPathLeftIndent::DoIndentChange()
05431 {
05432 ERROR2IF(mpDragStory==NULL, FALSE, "NULL story pointer");
05433
05434 MILLIPOINT Distance = 0;
05435 BOOL ok = TRUE;
05436
05437 if (mpDragStory->IsTextOnPathReversed())
05438 ok = GetRightHandLength(&Distance);
05439 else
05440 ok = GetLeftHandLength(&Distance);
05441
05442 if (ok)
05443 mpDragStory->SetLeftIndent(Distance);
05444
05445 return ok;
05446 }
05447
05448
05449
05450
05451
05452
05453
05454
05455
05456
05457
05458 BOOL OpDragStoryPathRightIndent::DoIndentChange()
05459 {
05460 ERROR2IF(mpDragStory==NULL, FALSE, "NULL story pointer");
05461
05462 MILLIPOINT Distance = 0;
05463 BOOL ok = TRUE;
05464
05465 if (mpDragStory->IsTextOnPathReversed())
05466 ok = GetLeftHandLength(&Distance);
05467 else
05468 ok = GetRightHandLength(&Distance);
05469
05470 if (ok)
05471 mpDragStory->SetRightIndent(Distance);
05472
05473 return ok;
05474 }
05475
05476
05477
05478
05479
05480
05481
05482
05483
05484
05485
05486 BOOL OpDragStoryNonPathLeftIndent::DoIndentChange()
05487 {
05488
05489 DocCoord LeftIndentPos = GetThisIndent();
05490 DocCoord RightIndentPos = GetOtherIndent();
05491 mpDragStory->SetStoryWidth((INT32)mCurrentBlobPos.Distance(RightIndentPos));
05492
05493
05494 double OldAngle = atan2((double)(LeftIndentPos.y-RightIndentPos.y), (double)(LeftIndentPos.x-RightIndentPos.x));
05495 double NewAngle = atan2((double)(mCurrentBlobPos.y-RightIndentPos.y), (double)(mCurrentBlobPos.x-RightIndentPos.x));
05496 ANGLE RotAngle = (NewAngle-OldAngle)*(180/PI);
05497 Matrix RMatrix(RightIndentPos, RotAngle);
05498 Trans2DMatrix* pTransMat = new Trans2DMatrix(RMatrix);
05499 BOOL ok = pTransMat!=NULL;
05500 if (ok)
05501 ok = DoTransformNode(mpDragStory, pTransMat);
05502
05503
05504 if (ok)
05505 {
05506 LeftIndentPos = GetThisIndent();
05507 DocCoord TransOffset = mCurrentBlobPos - LeftIndentPos;
05508 Matrix TMatrix(TransOffset.x, TransOffset.y);
05509 Trans2DMatrix* pTransMat = new Trans2DMatrix(TMatrix);
05510 ok = pTransMat!=NULL;
05511 if (ok)
05512 ok = DoTransformNode(mpDragStory, pTransMat);
05513 }
05514
05515 return ok;
05516 }
05517
05518
05519
05520
05521
05522
05523
05524
05525
05526
05527
05528 BOOL OpDragStoryNonPathRightIndent::DoIndentChange()
05529 {
05530
05531 mpDragStory->SetStoryWidth((INT32)mCurrentBlobPos.Distance(GetOtherIndent()));
05532
05533
05534 DocCoord LeftIndentPos = GetOtherIndent();
05535 DocCoord OldRightIndentPos = GetThisIndent();
05536
05537 double OldAngle = atan2((double)(OldRightIndentPos.y-LeftIndentPos.y), (double)(OldRightIndentPos.x-LeftIndentPos.x));
05538 double NewAngle = atan2((double)(mCurrentBlobPos.y-LeftIndentPos.y), (double)(mCurrentBlobPos.x-LeftIndentPos.x));
05539 ANGLE RotAngle = (NewAngle-OldAngle)*(180/PI);
05540
05541 Matrix RotMatrix(LeftIndentPos, RotAngle);
05542
05543
05544 Trans2DMatrix* pTransMat = new Trans2DMatrix(RotMatrix);
05545
05546 if (pTransMat == NULL)
05547 return FALSE;
05548 else
05549 return DoTransformNode(mpDragStory, pTransMat);
05550 }
05551
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561
05562 DocCoord OpDragStoryPathLeftIndent::GetThisIndent()
05563 {
05564 return mpDragStory->GetLeftIndentPos();
05565 }
05566
05567
05568
05569
05570
05571
05572
05573
05574
05575
05576 DocCoord OpDragStoryPathRightIndent::GetThisIndent()
05577 {
05578 return mpDragStory->GetRightIndentPos();
05579 }
05580
05581
05582
05583
05584
05585
05586
05587
05588
05589
05590 DocCoord OpDragStoryNonPathLeftIndent::GetThisIndent()
05591 {
05592 const Matrix* pStoryMatrix = mpDragStory->GetpStoryMatrix();
05593 DocCoord LeftIndent(0,0);
05594 pStoryMatrix->transform(&LeftIndent);
05595
05596 return LeftIndent;
05597 }
05598
05599
05600
05601
05602
05603
05604
05605
05606
05607
05608 DocCoord OpDragStoryNonPathRightIndent::GetThisIndent()
05609 {
05610 const Matrix* pStoryMatrix = mpDragStory->GetpStoryMatrix();
05611 DocCoord RightIndent(mpDragStory->GetStoryWidth(),0);
05612 pStoryMatrix->transform(&RightIndent);
05613
05614 return RightIndent;
05615 }
05616
05617
05618
05619
05620
05621
05622
05623
05624
05625
05626
05627 DocCoord OpDragStoryPathLeftIndent::GetOtherIndent()
05628 {
05629 return mpDragStory->GetRightIndentPos();
05630 }
05631
05632
05633
05634
05635
05636
05637
05638
05639
05640
05641 DocCoord OpDragStoryPathRightIndent::GetOtherIndent()
05642 {
05643 return mpDragStory->GetLeftIndentPos();
05644 }
05645
05646
05647
05648
05649
05650
05651
05652
05653
05654
05655 DocCoord OpDragStoryNonPathLeftIndent::GetOtherIndent()
05656 {
05657 const Matrix* pStoryMatrix = mpDragStory->GetpStoryMatrix();
05658 DocCoord RightIndent(mpDragStory->GetStoryWidth(),0);
05659 pStoryMatrix->transform(&RightIndent);
05660
05661 return RightIndent;
05662 }
05663
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673 DocCoord OpDragStoryNonPathRightIndent::GetOtherIndent()
05674 {
05675 const Matrix* pStoryMatrix = mpDragStory->GetpStoryMatrix();
05676 DocCoord LeftIndent(0,0);
05677 pStoryMatrix->transform(&LeftIndent);
05678
05679 return LeftIndent;
05680 }
05681
05682
05683
05684
05685
05686
05687
05688
05689
05690
05691
05692
05693
05694 DocCoord OpDragStoryPathLeftIndent::InternalConstrain(DocCoord Current, ClickModifiers ClickMods)
05695 {
05696 ERROR2IF(mpDragStory==NULL || mpStoryPath==NULL, DocCoord(0,0), "NULL pointer");
05697
05698 DocView::SnapCurrent(mpStartSpread, &Current);
05699
05700 INT32 NearEl=0;
05701 double mu=0.0;
05702 mpStoryPath->InkPath.SqrDistanceToPoint(Current, &NearEl, &mu);
05703 DocCoord LinePoint = mpStoryPath->InkPath.ClosestPointTo(mu, NearEl);
05704
05705
05706 MILLIPOINT TotalLineLength = (MILLIPOINT)mpStoryPath->InkPath.GetPathLength();
05707 MILLIPOINT LeftIndentLength = 0;
05708 BOOL ok = TRUE;
05709 if (mpDragStory->IsTextOnPathReversed())
05710 ok = GetRightHandLength(LinePoint, mpStoryPath, &LeftIndentLength);
05711 else
05712 ok = GetLeftHandLength(LinePoint, mpStoryPath, &LeftIndentLength);
05713
05714 if (((TotalLineLength-LeftIndentLength) < mpDragStory->GetRightIndent()) && ok)
05715 return mpDragStory->GetRightIndentPos();
05716 else
05717 return LinePoint;
05718 }
05719
05720
05721
05722
05723
05724
05725
05726
05727
05728
05729
05730
05731 DocCoord OpDragStoryPathRightIndent::InternalConstrain(DocCoord Current, ClickModifiers ClickMods)
05732 {
05733 DocView::SnapCurrent(mpStartSpread, &Current);
05734
05735 INT32 NearEl=0;
05736 double mu=0.0;
05737 mpStoryPath->InkPath.SqrDistanceToPoint(Current, &NearEl, &mu);
05738 DocCoord LinePoint = mpStoryPath->InkPath.ClosestPointTo(mu, NearEl);
05739
05740
05741 MILLIPOINT TotalLineLength = (MILLIPOINT)mpStoryPath->InkPath.GetPathLength();
05742 MILLIPOINT RightIndentLength = 0;
05743 BOOL ok = TRUE;
05744 if (mpDragStory->IsTextOnPathReversed())
05745 ok = GetLeftHandLength(LinePoint, mpStoryPath, &RightIndentLength);
05746 else
05747 ok = GetRightHandLength(LinePoint, mpStoryPath, &RightIndentLength);
05748
05749 if (((TotalLineLength-RightIndentLength) < mpDragStory->GetLeftIndent()) && ok)
05750 return mpDragStory->GetLeftIndentPos();
05751 else
05752 return LinePoint;
05753 }
05754
05755
05756
05757
05758
05759
05760
05761
05762
05763
05764
05765
05766 DocCoord OpDragStoryNonPathIndent::InternalConstrain(DocCoord Current, ClickModifiers ClickMods)
05767 {
05768
05769 if (!ClickMods.Adjust && !ClickMods.Constrain)
05770 {
05771 const double OrigLength = GetThisIndent().Distance(GetOtherIndent());
05772 double Hypot = GetOtherIndent().Distance(Current);
05773 double Oppo = DocCoord::DistanceFromLine(GetThisIndent(), GetOtherIndent(), Current);
05774 double Adj = sqrt(Hypot*Hypot - Oppo*Oppo);
05775 double Ratio = 1.0;
05776 if (OrigLength != 0.0)
05777 Ratio = Adj/(OrigLength);
05778
05779 const DocCoord JoinPoint = GetOtherIndent();
05780 const DocCoord OtherJoinEnd = GetThisIndent();
05781 const DocCoord cCurrent = Current;
05782
05783 if (DocCoord::IsJoinAcute(&JoinPoint, &OtherJoinEnd, &cCurrent))
05784 return DocCoord::PositionPointFromRatio(JoinPoint, OtherJoinEnd, Ratio);
05785 else
05786 return DocCoord::PositionPointFromRatio(JoinPoint, OtherJoinEnd, -Ratio);
05787 }
05788 else
05789 {
05790
05791 if (ClickMods.Constrain)
05792 {
05793 DocCoord Anchor = GetOtherIndent();
05794 DocView::ConstrainToAngle(Anchor, &Current);
05795 }
05796
05797 DocView::SnapCurrent(mpStartSpread, &Current);
05798 }
05799
05800 return Current;
05801 }
05802
05803
05804
05805
05806
05807
05808
05809
05810
05811
05812
05813
05814
05815
05816
05817 BOOL OpDragStoryPathIndent::SetCurrentPos(DocCoord MousePos, ClickModifiers ClickMods)
05818 {
05819 ERROR2IF(mpStoryPath==NULL, FALSE, "NULL story pointer");
05820
05821 mCurrentBlobPos = InternalConstrain(MousePos, ClickMods);
05822
05823 return TRUE;
05824 }
05825
05826
05827
05828
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838 BOOL OpDragStoryNonPathIndent::SetCurrentPos(DocCoord MousePos, ClickModifiers ClickMods)
05839 {
05840 ERROR3IF(mpStoryPath!=NULL, "Story is on a path, you don't want to use this function");
05841
05842 mCurrentBlobPos = InternalConstrain(MousePos, ClickMods);
05843
05844 return TRUE;
05845 }
05846
05847
05848
05849
05850
05851
05852
05853
05854
05855
05856
05857
05858
05859
05860
05861
05862
05863
05864
05865
05866
05867 StorePathIndentAction::StorePathIndentAction()
05868 {
05869 mpTextStory = NULL;
05870 mLeftIndentLength = 0;
05871 mRightIndentLength = 0;
05872 mStoryWidth = 0;
05873 }
05874
05875
05876
05877
05878
05879
05880
05881
05882
05883
05884 StorePathIndentAction::~StorePathIndentAction()
05885 {
05886 }
05887
05888
05889
05890
05891
05892
05893
05894
05895
05896
05897
05898
05899
05900 ActionCode StorePathIndentAction::Execute()
05901 {
05902
05903 ERROR2IF(mpTextStory == NULL, AC_FAIL, "The TextStory pointer is NULL");
05904
05905
05906 ActionCode Act;
05907 Act = StorePathIndentAction::Init(pOperation,
05908 pOppositeActLst,
05909 mpTextStory,
05910 mpTextStory->GetLeftIndent(),
05911 mpTextStory->GetRightIndent(),
05912 mpTextStory->GetStoryWidth());
05913
05914
05915 if (Act != AC_FAIL)
05916 {
05917 mpTextStory->SetLeftIndent(mLeftIndentLength);
05918 mpTextStory->SetRightIndent(mRightIndentLength);
05919 mpTextStory->SetStoryWidth(mStoryWidth);
05920 }
05921
05922 return Act;
05923 }
05924
05925
05926
05927
05928
05929
05930
05931
05932
05933
05934
05935
05936
05937
05938
05939
05940
05941
05942
05943
05944
05945
05946
05947 ActionCode StorePathIndentAction::Init(Operation* pOp,
05948 ActionList* pActionList,
05949 TextStory* pStory,
05950 MILLIPOINT LeftIndent,
05951 MILLIPOINT RightIndent,
05952 MILLIPOINT StoryWidth)
05953 {
05954
05955 ERROR2IF(pStory == NULL, AC_FAIL, "TextStory pointer was NULL");
05956
05957
05958 UINT32 ActSize = sizeof(StorePathIndentAction);
05959 StorePathIndentAction* pNewAction = NULL;
05960 ActionCode Ac = Action::Init( pOp, pActionList, ActSize, CC_RUNTIME_CLASS(StorePathIndentAction), (Action**)&pNewAction);
05961
05962
05963 if ((Ac == AC_OK) && (pNewAction != NULL))
05964 {
05965 pNewAction->mpTextStory = pStory;
05966 pNewAction->mLeftIndentLength = LeftIndent;
05967 pNewAction->mRightIndentLength = RightIndent;
05968 pNewAction->mStoryWidth = StoryWidth;
05969 }
05970
05971 return Ac;
05972 }
05973
05974
05975
05976
05977
05978
05979
05980
05981
05982
05983
05984
05985
05986
05987
05988
05989
05990
05991 BOOL StorePathIndentAction::DoStoreIndent( Operation* pOp, ActionList* pActionList, TextStory* pStory)
05992 {
05993
05994 ERROR2IF(pStory == NULL, FALSE, "The TextStory pointer is NULL");
05995
05996
05997 ActionCode Act;
05998 Act = StorePathIndentAction::Init(pOp, pActionList, pStory, pStory->GetLeftIndent(), pStory->GetRightIndent(), pStory->GetStoryWidth());
05999
06000 return (Act != AC_FAIL);
06001 }
06002
06003
06004 #endif
06005
06006
06008
06009
06010
06011
06012
06013
06014
06015
06016
06017
06018
06019
06020
06021
06022 void OpApplyGlobalAffect::DoAffectChange(ObjChangeParam* pObjChange, Document* pSearchDoc)
06023 {
06024
06025 ERROR3IF(pObjChange == NULL, "DoAffectChange called with a NULL pObjChange param");
06026 if (pObjChange==NULL)
06027 return;
06028
06029 Document* pDocument = pSearchDoc;
06030 if (!pDocument)
06031 pDocument = (Document*) Camelot.Documents.GetHead();
06032
06033 #if !defined(EXCLUDE_FROM_RALPH)
06034
06035 if (Camelot.FindSelection()!=NULL)
06036 {
06037 Node* SelNode = Camelot.FindSelection()->FindFirst();
06038 if (SelNode!=NULL)
06039 {
06040 Spread* SelSpread = (Spread*)SelNode->FindParent(CC_RUNTIME_CLASS(Spread));
06041 if (SelSpread!=NULL)
06042 Camelot.GetBlobManager()->RenderOff(NULL, SelSpread);
06043 }
06044 }
06045 #endif
06046
06047
06048 while (pDocument != NULL)
06049 {
06050
06051 Node* pNode = Node::DocFindFirstDepthFirst(pDocument);
06052
06053 while (pNode != NULL)
06054 {
06055 AffectNode(pDocument, pNode, pObjChange);
06056
06057 pNode = pNode->DocFindNextDepthFirst();
06058 }
06059
06060 pDocument->FlushRedraw();
06061
06062 if (pSearchDoc==NULL)
06063 pDocument = (Document*) Camelot.Documents.GetNext(pDocument);
06064 else
06065 pDocument = NULL;
06066 }
06067
06068
06069 pObjChange->Define(OBJCHANGE_FINISHED,pObjChange->GetChangeFlags(),NULL,NULL);
06070 UpdateAllChangedNodes(pObjChange);
06071
06072 #if !defined(EXCLUDE_FROM_RALPH)
06073
06074 if (Camelot.FindSelection()!=NULL)
06075 {
06076 Node* SelNode = Camelot.FindSelection()->FindFirst();
06077 if (SelNode!=NULL)
06078 {
06079 Spread* SelSpread = (Spread*)SelNode->FindParent(CC_RUNTIME_CLASS(Spread));
06080 if (SelSpread!=NULL)
06081 Camelot.GetBlobManager()->RenderOff(NULL, SelSpread);
06082 }
06083 }
06084 #endif
06085 }
06086
06087
06088
06089
06090
06091
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102 void OpApplyGlobalAffect::AffectNode(Document* pDocument, Node* pNode, ObjChangeParam* pObjChange)
06103 {
06104 }
06105
06106
06107
06108
06109
06110
06111
06112
06113
06114
06115
06116
06117
06118
06119 BOOL OpAffectFontChange::Init()
06120 {
06121 return (RegisterOpDescriptor( 0,
06122 0,
06123 CC_RUNTIME_CLASS(OpAffectFontChange),
06124 OPTOKEN_AFFECTFONTCHANGE,
06125 OpAffectFontChange::GetState,
06126 0,
06127 0,
06128 0 ));
06129 }
06130
06131
06132
06133
06134
06135
06136
06137
06138
06139
06140
06141 OpState OpAffectFontChange::GetState(String_256* UIDescription, OpDescriptor*)
06142 {
06143 OpState OpSt;
06144 return (OpSt);
06145 }
06146
06147
06148
06149
06150
06151
06152
06153
06154
06155
06156
06157
06158
06159 void OpAffectFontChange::DoAffectFontChange()
06160 {
06161 ObjChangeFlags cFlags;
06162 cFlags.Attribute = TRUE;
06163 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
06164
06165 BeginSlowJob();
06166 DoAffectChange(&ObjChange);
06167 EndSlowJob();
06168 End();
06169 }
06170
06171
06172
06173
06174
06175
06176
06177
06178
06179
06180
06181
06182
06183
06184
06185
06186
06187 void OpAffectFontChange::AffectNode(Document* pDocument, Node* pNode, ObjChangeParam* pObjChange)
06188 {
06189
06190 if (IS_A(pNode,NodeDocument))
06191 {
06192 pDocument->GetOpHistory().DeleteUndoableOps();
06193 pDocument->GetOpHistory().DeleteRedoableOps();
06194 }
06195
06196 if (IS_A(pNode,TextStory))
06197 ((TextStory*)pNode)->AllowOp(pObjChange);
06198 }
06199
06200
06201
06202
06203
06204
06205
06206
06207
06208
06209
06210
06211
06212 ToggleAutoKerningAction::ToggleAutoKerningAction()
06213 {
06214 pTextStory = 0;
06215 OldIsAutoKerning = FALSE;
06216 }
06217
06218
06219
06220
06221
06222
06223
06224
06225
06226
06227
06228
06229
06230
06231
06232
06233
06234
06235
06236
06237
06238
06239
06240
06241
06242
06243 ActionCode ToggleAutoKerningAction::Init(Operation* pOp,
06244 ActionList* pActionList,
06245 TextStory* pStory,
06246 BOOL NewIsAutoKerning)
06247 {
06248 ERROR2IF(pStory==0,AC_FAIL,"pStory was NULL");
06249
06250 UINT32 ActSize = sizeof(ToggleAutoKerningAction);
06251
06252 ToggleAutoKerningAction* pNewAction = NULL;
06253
06254 ActionCode Ac = Action::Init( pOp,
06255 pActionList,
06256 ActSize,
06257 CC_RUNTIME_CLASS(ToggleAutoKerningAction),
06258 (Action**)&pNewAction);
06259
06260 if ((Ac != AC_FAIL) && (pNewAction != NULL))
06261 {
06262 ERROR2IF(pStory == NULL,AC_FAIL,"TextStory pointer was NULL");
06263 pNewAction->pTextStory = pStory;
06264 pNewAction->OldIsAutoKerning = !NewIsAutoKerning;
06265
06266 pStory->SetAutoKerning(NewIsAutoKerning);
06267 pStory->FlagNodeAndDescendantsModifiedByOpAndParentsHaveDescendantModifiedByOp();
06268 pStory->FormatAndChildren(NULL,FALSE);
06269 }
06270
06271 return Ac;
06272 }
06273
06274
06275
06276
06277
06278
06279
06280
06281
06282
06283
06284
06285 ActionCode ToggleAutoKerningAction::Execute()
06286 {
06287 ActionCode Act;
06288
06289 Act = ToggleAutoKerningAction::Init(pOperation,
06290 pOppositeActLst,
06291 pTextStory,
06292 OldIsAutoKerning);
06293
06294 return Act;
06295 }