1 : /*
2 : * ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * a mozilla.org contributor.
19 : * Portions created by the Initial Developer are Copyright (C) 2006
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifndef nsFrameSelection_h___
39 : #define nsFrameSelection_h___
40 :
41 : #include "mozilla/Attributes.h"
42 :
43 : #include "nsIFrame.h"
44 : #include "nsIContent.h"
45 : #include "nsISelectionController.h"
46 : #include "nsITableLayout.h"
47 : #include "nsITableCellLayout.h"
48 : #include "nsIDOMElement.h"
49 : #include "nsGUIEvent.h"
50 : #include "nsRange.h"
51 :
52 : // IID for the nsFrameSelection interface
53 : // 3c6ae2d0-4cf1-44a1-9e9d-2411867f19c6
54 : #define NS_FRAME_SELECTION_IID \
55 : { 0x3c6ae2d0, 0x4cf1, 0x44a1, \
56 : { 0x9e, 0x9d, 0x24, 0x11, 0x86, 0x7f, 0x19, 0xc6 } }
57 :
58 : #ifdef IBMBIDI // Constant for Set/Get CaretBidiLevel
59 : #define BIDI_LEVEL_UNDEFINED 0x80
60 : #endif
61 :
62 : //----------------------------------------------------------------------
63 :
64 : // Selection interface
65 :
66 : struct SelectionDetails
67 : {
68 : #ifdef NS_BUILD_REFCNT_LOGGING
69 0 : SelectionDetails() {
70 0 : MOZ_COUNT_CTOR(SelectionDetails);
71 0 : }
72 0 : ~SelectionDetails() {
73 0 : MOZ_COUNT_DTOR(SelectionDetails);
74 0 : }
75 : #endif
76 : PRInt32 mStart;
77 : PRInt32 mEnd;
78 : SelectionType mType;
79 : nsTextRangeStyle mTextRangeStyle;
80 : SelectionDetails *mNext;
81 : };
82 :
83 : class nsIPresShell;
84 : class nsIScrollableFrame;
85 :
86 : enum EWordMovementType { eStartWord, eEndWord, eDefaultBehavior };
87 :
88 : /** PeekOffsetStruct is used to group various arguments (both input and output)
89 : * that are passed to nsFrame::PeekOffset(). See below for the description of
90 : * individual arguments.
91 : */
92 : struct NS_STACK_CLASS nsPeekOffsetStruct
93 0 : {
94 0 : void SetData(nsSelectionAmount aAmount,
95 : nsDirection aDirection,
96 : PRInt32 aStartOffset,
97 : nscoord aDesiredX,
98 : bool aJumpLines,
99 : bool aScrollViewStop,
100 : bool aIsKeyboardSelect,
101 : bool aVisual,
102 : EWordMovementType aWordMovementType = eDefaultBehavior)
103 :
104 : {
105 0 : mAmount = aAmount;
106 0 : mDirection = aDirection;
107 0 : mStartOffset = aStartOffset;
108 0 : mDesiredX = aDesiredX;
109 0 : mJumpLines = aJumpLines;
110 0 : mScrollViewStop = aScrollViewStop;
111 0 : mIsKeyboardSelect = aIsKeyboardSelect;
112 0 : mVisual = aVisual;
113 0 : mWordMovementType = aWordMovementType;
114 0 : }
115 :
116 : // Note: Most arguments (input and output) are only used with certain values
117 : // of mAmount. These values are indicated for each argument below.
118 : // Arguments with no such indication are used with all values of mAmount.
119 :
120 : /*** Input arguments ***/
121 : // Note: The value of some of the input arguments may be changed upon exit.
122 :
123 : // mAmount: The type of movement requested (by character, word, line, etc.)
124 : nsSelectionAmount mAmount;
125 :
126 : // mDirection: eDirPrevious or eDirNext.
127 : // * Note for visual bidi movement:
128 : // eDirPrevious means 'left-then-up' if the containing block is LTR,
129 : // 'right-then-up' if it is RTL.
130 : // eDirNext means 'right-then-down' if the containing block is LTR,
131 : // 'left-then-down' if it is RTL.
132 : // Between paragraphs, eDirPrevious means "go to the visual end of the
133 : // previous paragraph", and eDirNext means "go to the visual beginning
134 : // of the next paragraph".
135 : // Used with: eSelectCharacter, eSelectWord, eSelectLine, eSelectParagraph.
136 : nsDirection mDirection;
137 :
138 : // mStartOffset: Offset into the content of the current frame where the peek starts.
139 : // Used with: eSelectCharacter, eSelectWord
140 : PRInt32 mStartOffset;
141 :
142 : // mDesiredX: The desired x coordinate for the caret.
143 : // Used with: eSelectLine.
144 : nscoord mDesiredX;
145 :
146 : // mWordMovementType: An enum that determines whether to prefer the start or end of a word
147 : // or to use the default beahvior, which is a combination of
148 : // direction and the platform-based pref
149 : // "layout.word_select.eat_space_to_next_word"
150 : EWordMovementType mWordMovementType;
151 :
152 : // mJumpLines: Whether to allow jumping across line boundaries.
153 : // Used with: eSelectCharacter, eSelectWord.
154 : bool mJumpLines;
155 :
156 : // mScrollViewStop: Whether to stop when reaching a scroll view boundary.
157 : // Used with: eSelectCharacter, eSelectWord, eSelectLine.
158 : bool mScrollViewStop;
159 :
160 : // mIsKeyboardSelect: Whether the peeking is done in response to a keyboard action.
161 : // Used with: eSelectWord.
162 : bool mIsKeyboardSelect;
163 :
164 : // mVisual: Whether bidi caret behavior is visual (true) or logical (false).
165 : // Used with: eSelectCharacter, eSelectWord, eSelectBeginLine, eSelectEndLine.
166 : bool mVisual;
167 :
168 : /*** Output arguments ***/
169 :
170 : // mResultContent: Content reached as a result of the peek.
171 : nsCOMPtr<nsIContent> mResultContent;
172 :
173 : // mResultFrame: Frame reached as a result of the peek.
174 : // Used with: eSelectCharacter, eSelectWord.
175 : nsIFrame *mResultFrame;
176 :
177 : // mContentOffset: Offset into content reached as a result of the peek.
178 : PRInt32 mContentOffset;
179 :
180 : // mAttachForward: When the result position is between two frames,
181 : // indicates which of the two frames the caret should be painted in.
182 : // false means "the end of the frame logically before the caret",
183 : // true means "the beginning of the frame logically after the caret".
184 : // Used with: eSelectLine, eSelectBeginLine, eSelectEndLine.
185 : bool mAttachForward;
186 : };
187 :
188 : struct nsPrevNextBidiLevels
189 : {
190 0 : void SetData(nsIFrame* aFrameBefore,
191 : nsIFrame* aFrameAfter,
192 : PRUint8 aLevelBefore,
193 : PRUint8 aLevelAfter)
194 : {
195 0 : mFrameBefore = aFrameBefore;
196 0 : mFrameAfter = aFrameAfter;
197 0 : mLevelBefore = aLevelBefore;
198 0 : mLevelAfter = aLevelAfter;
199 0 : }
200 : nsIFrame* mFrameBefore;
201 : nsIFrame* mFrameAfter;
202 : PRUint8 mLevelBefore;
203 : PRUint8 mLevelAfter;
204 : };
205 :
206 : class nsTypedSelection;
207 : class nsIScrollableFrame;
208 :
209 : /**
210 : * Methods which are marked with *unsafe* should be handled with special care.
211 : * They may cause nsFrameSelection to be deleted, if strong pointer isn't used,
212 : * or they may cause other objects to be deleted.
213 : */
214 :
215 0 : class nsFrameSelection MOZ_FINAL : public nsISupports {
216 : public:
217 : enum HINT { HINTLEFT = 0, HINTRIGHT = 1}; //end of this line or beginning of next
218 : /*interfaces for addref and release and queryinterface*/
219 :
220 0 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
221 1464 : NS_DECL_CYCLE_COLLECTION_CLASS(nsFrameSelection)
222 :
223 : /** Init will initialize the frame selector with the necessary pres shell to
224 : * be used by most of the methods
225 : * @param aShell is the parameter to be used for most of the other calls for callbacks etc
226 : * @param aLimiter limits the selection to nodes with aLimiter parents
227 : */
228 : void Init(nsIPresShell *aShell, nsIContent *aLimiter);
229 :
230 : /** HandleClick will take the focus to the new frame at the new offset and
231 : * will either extend the selection from the old anchor, or replace the old anchor.
232 : * the old anchor and focus position may also be used to deselect things
233 : * @param aNewfocus is the content that wants the focus
234 : * @param aContentOffset is the content offset of the parent aNewFocus
235 : * @param aContentOffsetEnd is the content offset of the parent aNewFocus and is specified different
236 : * when you need to select to and include both start and end points
237 : * @param aContinueSelection is the flag that tells the selection to keep the old anchor point or not.
238 : * @param aMultipleSelection will tell the frame selector to replace /or not the old selection.
239 : * cannot coexist with aContinueSelection
240 : * @param aHint will tell the selection which direction geometrically to actually show the caret on.
241 : * 1 = end of this line 0 = beginning of this line
242 : */
243 : /*unsafe*/
244 : nsresult HandleClick(nsIContent *aNewFocus,
245 : PRUint32 aContentOffset,
246 : PRUint32 aContentEndOffset,
247 : bool aContinueSelection,
248 : bool aMultipleSelection,
249 : bool aHint);
250 :
251 : /** HandleDrag extends the selection to contain the frame closest to aPoint.
252 : * @param aPresContext is the context to use when figuring out what frame contains the point.
253 : * @param aFrame is the parent of all frames to use when searching for the closest frame to the point.
254 : * @param aPoint is relative to aFrame
255 : */
256 : /*unsafe*/
257 : void HandleDrag(nsIFrame *aFrame, nsPoint aPoint);
258 :
259 : /** HandleTableSelection will set selection to a table, cell, etc
260 : * depending on information contained in aFlags
261 : * @param aParentContent is the paretent of either a table or cell that user clicked or dragged the mouse in
262 : * @param aContentOffset is the offset of the table or cell
263 : * @param aTarget indicates what to select (defined in nsISelectionPrivate.idl/nsISelectionPrivate.h):
264 : * TABLESELECTION_CELL We should select a cell (content points to the cell)
265 : * TABLESELECTION_ROW We should select a row (content points to any cell in row)
266 : * TABLESELECTION_COLUMN We should select a row (content points to any cell in column)
267 : * TABLESELECTION_TABLE We should select a table (content points to the table)
268 : * TABLESELECTION_ALLCELLS We should select all cells (content points to any cell in table)
269 : * @param aMouseEvent passed in so we can get where event occurred and what keys are pressed
270 : */
271 : /*unsafe*/
272 : nsresult HandleTableSelection(nsINode *aParentContent,
273 : PRInt32 aContentOffset,
274 : PRInt32 aTarget,
275 : nsMouseEvent *aMouseEvent);
276 :
277 : /**
278 : * Add cell to the selection.
279 : *
280 : * @param aCell [in] HTML td element.
281 : */
282 : virtual nsresult SelectCellElement(nsIContent *aCell);
283 :
284 : /**
285 : * Add cells to the selection inside of the given cells range.
286 : *
287 : * @param aTable [in] HTML table element
288 : * @param aStartRowIndex [in] row index where the cells range starts
289 : * @param aStartColumnIndex [in] column index where the cells range starts
290 : * @param aEndRowIndex [in] row index where the cells range ends
291 : * @param aEndColumnIndex [in] column index where the cells range ends
292 : */
293 : virtual nsresult AddCellsToSelection(nsIContent *aTable,
294 : PRInt32 aStartRowIndex,
295 : PRInt32 aStartColumnIndex,
296 : PRInt32 aEndRowIndex,
297 : PRInt32 aEndColumnIndex);
298 :
299 : /**
300 : * Remove cells from selection inside of the given cell range.
301 : *
302 : * @param aTable [in] HTML table element
303 : * @param aStartRowIndex [in] row index where the cells range starts
304 : * @param aStartColumnIndex [in] column index where the cells range starts
305 : * @param aEndRowIndex [in] row index where the cells range ends
306 : * @param aEndColumnIndex [in] column index where the cells range ends
307 : */
308 : virtual nsresult RemoveCellsFromSelection(nsIContent *aTable,
309 : PRInt32 aStartRowIndex,
310 : PRInt32 aStartColumnIndex,
311 : PRInt32 aEndRowIndex,
312 : PRInt32 aEndColumnIndex);
313 :
314 : /**
315 : * Remove cells from selection outside of the given cell range.
316 : *
317 : * @param aTable [in] HTML table element
318 : * @param aStartRowIndex [in] row index where the cells range starts
319 : * @param aStartColumnIndex [in] column index where the cells range starts
320 : * @param aEndRowIndex [in] row index where the cells range ends
321 : * @param aEndColumnIndex [in] column index where the cells range ends
322 : */
323 : virtual nsresult RestrictCellsToSelection(nsIContent *aTable,
324 : PRInt32 aStartRowIndex,
325 : PRInt32 aStartColumnIndex,
326 : PRInt32 aEndRowIndex,
327 : PRInt32 aEndColumnIndex);
328 :
329 : /** StartAutoScrollTimer is responsible for scrolling frames so that
330 : * aPoint is always visible, and for selecting any frame that contains
331 : * aPoint. The timer will also reset itself to fire again if we have
332 : * not scrolled to the end of the document.
333 : * @param aFrame is the outermost frame to use when searching for
334 : * the closest frame for the point, i.e. the frame that is capturing
335 : * the mouse
336 : * @param aPoint is relative to aFrame.
337 : * @param aDelay is the timer's interval.
338 : */
339 : /*unsafe*/
340 : nsresult StartAutoScrollTimer(nsIFrame *aFrame,
341 : nsPoint aPoint,
342 : PRUint32 aDelay);
343 :
344 : /** StopAutoScrollTimer stops any active auto scroll timer.
345 : */
346 : void StopAutoScrollTimer();
347 :
348 : /** Lookup Selection
349 : * returns in frame coordinates the selection beginning and ending with the type of selection given
350 : * @param aContent is the content asking
351 : * @param aContentOffset is the starting content boundary
352 : * @param aContentLength is the length of the content piece asking
353 : * @param aReturnDetails linkedlist of return values for the selection.
354 : * @param aSlowCheck will check using slow method with no shortcuts
355 : */
356 : SelectionDetails* LookUpSelection(nsIContent *aContent,
357 : PRInt32 aContentOffset,
358 : PRInt32 aContentLength,
359 : bool aSlowCheck) const;
360 :
361 : /** SetMouseDownState(bool);
362 : * sets the mouse state to aState for resons of drag state.
363 : * @param aState is the new state of mousedown
364 : */
365 : /*unsafe*/
366 : void SetMouseDownState(bool aState);
367 :
368 : /** GetMouseDownState(bool *);
369 : * gets the mouse state to aState for resons of drag state.
370 : * @param aState will hold the state of mousedown
371 : */
372 0 : bool GetMouseDownState() const { return mMouseDownState; }
373 :
374 : /**
375 : if we are in table cell selection mode. aka ctrl click in table cell
376 : */
377 0 : bool GetTableCellSelection() const { return mSelectingTableCellMode != 0; }
378 0 : void ClearTableCellSelection() { mSelectingTableCellMode = 0; }
379 :
380 : /** GetSelection
381 : * no query interface for selection. must use this method now.
382 : * @param aSelectionType enum value defined in nsISelection for the seleciton you want.
383 : */
384 : nsISelection* GetSelection(SelectionType aType) const;
385 :
386 : /**
387 : * ScrollSelectionIntoView scrolls a region of the selection,
388 : * so that it is visible in the scrolled view.
389 : *
390 : * @param aType the selection to scroll into view.
391 : * @param aRegion the region inside the selection to scroll into view.
392 : * @param aFlags the scroll flags. Valid bits include:
393 : * SCROLL_SYNCHRONOUS: when set, scrolls the selection into view
394 : * before returning. If not set, posts a request which is processed
395 : * at some point after the method returns.
396 : * SCROLL_FIRST_ANCESTOR_ONLY: if set, only the first ancestor will be scrolled
397 : * into view.
398 : */
399 : /*unsafe*/
400 : nsresult ScrollSelectionIntoView(SelectionType aType,
401 : SelectionRegion aRegion,
402 : PRInt16 aFlags) const;
403 :
404 : /** RepaintSelection repaints the selected frames that are inside the selection
405 : * specified by aSelectionType.
406 : * @param aSelectionType enum value defined in nsISelection for the seleciton you want.
407 : */
408 : nsresult RepaintSelection(SelectionType aType) const;
409 :
410 : /** GetFrameForNodeOffset given a node and its child offset, return the nsIFrame and
411 : * the offset into that frame.
412 : * @param aNode input parameter for the node to look at
413 : * @param aOffset offset into above node.
414 : * @param aReturnOffset will contain offset into frame.
415 : */
416 : virtual nsIFrame* GetFrameForNodeOffset(nsIContent *aNode,
417 : PRInt32 aOffset,
418 : HINT aHint,
419 : PRInt32 *aReturnOffset) const;
420 :
421 : /**
422 : * Scrolling then moving caret placement code in common to text areas and
423 : * content areas should be located in the implementer
424 : * This method will accept the following parameters and perform the scroll
425 : * and caret movement. It remains for the caller to call the final
426 : * ScrollCaretIntoView if that called wants to be sure the caret is always
427 : * visible.
428 : *
429 : * @param aForward if true, scroll forward if not scroll backward
430 : * @param aExtend if true, extend selection to the new point
431 : * @param aScrollableFrame the frame to scroll
432 : */
433 : /*unsafe*/
434 : void CommonPageMove(bool aForward,
435 : bool aExtend,
436 : nsIScrollableFrame* aScrollableFrame);
437 :
438 0 : void SetHint(HINT aHintRight) { mHint = aHintRight; }
439 0 : HINT GetHint() const { return mHint; }
440 :
441 : #ifdef IBMBIDI
442 : /** SetCaretBidiLevel sets the caret bidi level
443 : * @param aLevel the caret bidi level
444 : * This method is virtual since it gets called from outside of layout.
445 : */
446 : virtual void SetCaretBidiLevel (PRUint8 aLevel);
447 : /** GetCaretBidiLevel gets the caret bidi level
448 : * This method is virtual since it gets called from outside of layout.
449 : */
450 : virtual PRUint8 GetCaretBidiLevel() const;
451 : /** UndefineCaretBidiLevel sets the caret bidi level to "undefined"
452 : * This method is virtual since it gets called from outside of layout.
453 : */
454 : virtual void UndefineCaretBidiLevel();
455 : #endif
456 :
457 : /** CharacterMove will generally be called from the nsiselectioncontroller implementations.
458 : * the effect being the selection will move one character left or right.
459 : * @param aForward move forward in document.
460 : * @param aExtend continue selection
461 : */
462 : /*unsafe*/
463 : nsresult CharacterMove(bool aForward, bool aExtend);
464 :
465 : /** CharacterExtendForDelete extends the selection forward (logically) to
466 : * the next character cell, so that the selected cell can be deleted.
467 : */
468 : /*unsafe*/
469 : nsresult CharacterExtendForDelete();
470 :
471 : /** CharacterExtendForBackspace extends the selection backward (logically) to
472 : * the previous character cell, so that the selected cell can be deleted.
473 : */
474 : /*unsafe*/
475 : nsresult CharacterExtendForBackspace();
476 :
477 : /** WordMove will generally be called from the nsiselectioncontroller implementations.
478 : * the effect being the selection will move one word left or right.
479 : * @param aForward move forward in document.
480 : * @param aExtend continue selection
481 : */
482 : /*unsafe*/
483 : nsresult WordMove(bool aForward, bool aExtend);
484 :
485 : /** WordExtendForDelete extends the selection backward or forward (logically) to the
486 : * next word boundary, so that the selected word can be deleted.
487 : * @param aForward select forward in document.
488 : */
489 : /*unsafe*/
490 : nsresult WordExtendForDelete(bool aForward);
491 :
492 : /** LineMove will generally be called from the nsiselectioncontroller implementations.
493 : * the effect being the selection will move one line up or down.
494 : * @param aForward move forward in document.
495 : * @param aExtend continue selection
496 : */
497 : /*unsafe*/
498 : nsresult LineMove(bool aForward, bool aExtend);
499 :
500 : /** IntraLineMove will generally be called from the nsiselectioncontroller implementations.
501 : * the effect being the selection will move to beginning or end of line
502 : * @param aForward move forward in document.
503 : * @param aExtend continue selection
504 : */
505 : /*unsafe*/
506 : nsresult IntraLineMove(bool aForward, bool aExtend);
507 :
508 : /** Select All will generally be called from the nsiselectioncontroller implementations.
509 : * it will select the whole doc
510 : */
511 : /*unsafe*/
512 : nsresult SelectAll();
513 :
514 : /** Sets/Gets The display selection enum.
515 : */
516 0 : void SetDisplaySelection(PRInt16 aState) { mDisplaySelection = aState; }
517 0 : PRInt16 GetDisplaySelection() const { return mDisplaySelection; }
518 :
519 : /** This method can be used to store the data received during a MouseDown
520 : * event so that we can place the caret during the MouseUp event.
521 : * @aMouseEvent the event received by the selection MouseDown
522 : * handling method. A NULL value can be use to tell this method
523 : * that any data is storing is no longer valid.
524 : */
525 : void SetDelayedCaretData(nsMouseEvent *aMouseEvent);
526 :
527 : /** Get the delayed MouseDown event data necessary to place the
528 : * caret during MouseUp processing.
529 : * @return a pointer to the event received
530 : * by the selection during MouseDown processing. It can be NULL
531 : * if the data is no longer valid.
532 : */
533 : nsMouseEvent* GetDelayedCaretData();
534 :
535 : /** Get the content node that limits the selection
536 : * When searching up a nodes for parents, as in a text edit field
537 : * in an browser page, we must stop at this node else we reach into the
538 : * parent page, which is very bad!
539 : */
540 0 : nsIContent* GetLimiter() const { return mLimiter; }
541 :
542 0 : nsIContent* GetAncestorLimiter() const { return mAncestorLimiter; }
543 : /*unsafe*/
544 : void SetAncestorLimiter(nsIContent *aLimiter);
545 :
546 : /** This will tell the frame selection that a double click has been pressed
547 : * so it can track abort future drags if inside the same selection
548 : * @aDoubleDown has the double click down happened
549 : */
550 0 : void SetMouseDoubleDown(bool aDoubleDown) { mMouseDoubleDownState = aDoubleDown; }
551 :
552 : /** This will return whether the double down flag was set.
553 : * @return whether the double down flag was set
554 : */
555 : bool GetMouseDoubleDown() const { return mMouseDoubleDownState; }
556 :
557 : /** GetPrevNextBidiLevels will return the frames and associated Bidi levels of the characters
558 : * logically before and after a (collapsed) selection.
559 : * @param aNode is the node containing the selection
560 : * @param aContentOffset is the offset of the selection in the node
561 : * @param aJumpLines If true, look across line boundaries.
562 : * If false, behave as if there were base-level frames at line edges.
563 : *
564 : * @return A struct holding the before/after frame and the before/after level.
565 : *
566 : * At the beginning and end of each line there is assumed to be a frame with
567 : * Bidi level equal to the paragraph embedding level.
568 : * In these cases the before frame and after frame respectively will be
569 : * nsnull.
570 : *
571 : * This method is virtual since it gets called from outside of layout.
572 : */
573 : virtual nsPrevNextBidiLevels GetPrevNextBidiLevels(nsIContent *aNode,
574 : PRUint32 aContentOffset,
575 : bool aJumpLines) const;
576 :
577 : /** GetFrameFromLevel will scan in a given direction
578 : * until it finds a frame with a Bidi level less than or equal to a given level.
579 : * It will return the last frame before this.
580 : * @param aPresContext is the context to use
581 : * @param aFrameIn is the frame to start from
582 : * @param aDirection is the direction to scan
583 : * @param aBidiLevel is the level to search for
584 : * @param aFrameOut will hold the frame returned
585 : */
586 : nsresult GetFrameFromLevel(nsIFrame *aFrameIn,
587 : nsDirection aDirection,
588 : PRUint8 aBidiLevel,
589 : nsIFrame **aFrameOut) const;
590 :
591 : /**
592 : * MaintainSelection will track the current selection as being "sticky".
593 : * Dragging or extending selection will never allow for a subset
594 : * (or the whole) of the maintained selection to become unselected.
595 : * Primary use: double click selecting then dragging on second click
596 : * @param aAmount the initial amount of text selected (word, line or paragraph).
597 : * For "line", use eSelectBeginLine.
598 : */
599 : nsresult MaintainSelection(nsSelectionAmount aAmount = eSelectNoAmount);
600 :
601 : nsFrameSelection();
602 :
603 : void StartBatchChanges();
604 : void EndBatchChanges();
605 : /*unsafe*/
606 : nsresult DeleteFromDocument();
607 :
608 0 : nsIPresShell *GetShell()const { return mShell; }
609 :
610 : void DisconnectFromPresShell();
611 : private:
612 : nsresult TakeFocus(nsIContent *aNewFocus,
613 : PRUint32 aContentOffset,
614 : PRUint32 aContentEndOffset,
615 : HINT aHint,
616 : bool aContinueSelection,
617 : bool aMultipleSelection);
618 :
619 : void BidiLevelFromMove(nsIPresShell* aPresShell,
620 : nsIContent *aNode,
621 : PRUint32 aContentOffset,
622 : PRUint32 aKeycode,
623 : HINT aHint);
624 : void BidiLevelFromClick(nsIContent *aNewFocus, PRUint32 aContentOffset);
625 : nsPrevNextBidiLevels GetPrevNextBidiLevels(nsIContent *aNode,
626 : PRUint32 aContentOffset,
627 : HINT aHint,
628 : bool aJumpLines) const;
629 :
630 : bool AdjustForMaintainedSelection(nsIContent *aContent, PRInt32 aOffset);
631 :
632 : // post and pop reasons for notifications. we may stack these later
633 0 : void PostReason(PRInt16 aReason) { mSelectionChangeReason = aReason; }
634 0 : PRInt16 PopReason()
635 : {
636 0 : PRInt16 retval = mSelectionChangeReason;
637 0 : mSelectionChangeReason = 0;
638 0 : return retval;
639 : }
640 :
641 : friend class nsTypedSelection;
642 : #ifdef DEBUG
643 : void printSelection(); // for debugging
644 : #endif /* DEBUG */
645 :
646 : void ResizeBuffer(PRUint32 aNewBufSize);
647 : /*HELPER METHODS*/
648 : nsresult MoveCaret(PRUint32 aKeycode, bool aContinueSelection,
649 : nsSelectionAmount aAmount);
650 : nsresult MoveCaret(PRUint32 aKeycode, bool aContinueSelection,
651 : nsSelectionAmount aAmount,
652 : bool aVisualMovement);
653 :
654 : nsresult FetchDesiredX(nscoord &aDesiredX); //the x position requested by the Key Handling for up down
655 : void InvalidateDesiredX(); //do not listen to mDesiredX you must get another.
656 : void SetDesiredX(nscoord aX); //set the mDesiredX
657 :
658 : nsresult ConstrainFrameAndPointToAnchorSubtree(nsIFrame *aFrame, nsPoint& aPoint, nsIFrame **aRetFrame, nsPoint& aRetPoint);
659 :
660 0 : PRUint32 GetBatching() const {return mBatching; }
661 : bool GetNotifyFrames() const { return mNotifyFrames; }
662 0 : void SetDirty(bool aDirty=true){if (mBatching) mChangesDuringBatching = aDirty;}
663 :
664 : // nsFrameSelection may get deleted when calling this,
665 : // so remember to use nsCOMPtr when needed.
666 : nsresult NotifySelectionListeners(SelectionType aType); // add parameters to say collapsed etc?
667 :
668 : nsRefPtr<nsTypedSelection> mDomSelections[nsISelectionController::NUM_SELECTIONTYPES];
669 :
670 : // Table selection support.
671 : // Interfaces that let us get info based on cellmap locations
672 : nsITableLayout* GetTableLayout(nsIContent *aTableContent) const;
673 : nsITableCellLayout* GetCellLayout(nsIContent *aCellContent) const;
674 :
675 : nsresult SelectBlockOfCells(nsIContent *aStartNode, nsIContent *aEndNode);
676 : nsresult SelectRowOrColumn(nsIContent *aCellContent, PRUint32 aTarget);
677 : nsresult UnselectCells(nsIContent *aTable,
678 : PRInt32 aStartRowIndex, PRInt32 aStartColumnIndex,
679 : PRInt32 aEndRowIndex, PRInt32 aEndColumnIndex,
680 : bool aRemoveOutsideOfCellRange);
681 :
682 : nsresult GetCellIndexes(nsIContent *aCell, PRInt32 &aRowIndex, PRInt32 &aColIndex);
683 :
684 : // Get our first range, if its first selected node is a cell. If this does
685 : // not return null, then the first node in the returned range is a cell
686 : // (according to GetFirstCellNodeInRange).
687 : nsRange* GetFirstCellRange();
688 : // Get our next range, if its first selected node is a cell. If this does
689 : // not return null, then the first node in the returned range is a cell
690 : // (according to GetFirstCellNodeInRange).
691 : nsRange* GetNextCellRange();
692 : nsIContent* GetFirstCellNodeInRange(nsRange *aRange) const;
693 : // Returns non-null table if in same table, null otherwise
694 : nsIContent* IsInSameTable(nsIContent *aContent1, nsIContent *aContent2) const;
695 : // Might return null
696 : nsIContent* GetParentTable(nsIContent *aCellNode) const;
697 : nsresult CreateAndAddRange(nsINode *aParentNode, PRInt32 aOffset);
698 : nsresult ClearNormalSelection();
699 :
700 : nsCOMPtr<nsINode> mCellParent; //used to snap to table selection
701 : nsCOMPtr<nsIContent> mStartSelectedCell;
702 : nsCOMPtr<nsIContent> mEndSelectedCell;
703 : nsCOMPtr<nsIContent> mAppendStartSelectedCell;
704 : nsCOMPtr<nsIContent> mUnselectCellOnMouseUp;
705 : PRInt32 mSelectingTableCellMode;
706 : PRInt32 mSelectedCellIndex;
707 :
708 : // maintain selection
709 : nsRefPtr<nsRange> mMaintainRange;
710 : nsSelectionAmount mMaintainedAmount;
711 :
712 : //batching
713 : PRInt32 mBatching;
714 :
715 : nsIContent *mLimiter; //limit selection navigation to a child of this node.
716 : nsIContent *mAncestorLimiter; // Limit selection navigation to a descendant of
717 : // this node.
718 : nsIPresShell *mShell;
719 :
720 : PRInt16 mSelectionChangeReason; // reason for notifications of selection changing
721 : PRInt16 mDisplaySelection; //for visual display purposes.
722 :
723 : HINT mHint; //hint to tell if the selection is at the end of this line or beginning of next
724 : #ifdef IBMBIDI
725 : PRUint8 mCaretBidiLevel;
726 : #endif
727 :
728 : PRInt32 mDesiredX;
729 :
730 : nsMouseEvent mDelayedMouseEvent;
731 :
732 : bool mDelayedMouseEventValid;
733 :
734 : bool mChangesDuringBatching;
735 : bool mNotifyFrames;
736 : bool mDragSelectingCells;
737 : bool mMouseDownState; //for drag purposes
738 : bool mMouseDoubleDownState; //has the doubleclick down happened
739 : bool mDesiredXSet;
740 :
741 : PRInt8 mCaretMovementStyle;
742 : };
743 :
744 : #endif /* nsFrameSelection_h___ */
|