LCOV - code coverage report
Current view: directory - editor/libeditor/base - IMETextTxn.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 164 2 1.2 %
Date: 2012-06-02 Functions: 16 2 12.5 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       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                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998-1999
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Pierre Phaneuf <pp@ludusdesign.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "IMETextTxn.h"
      40                 : #include "nsIDOMCharacterData.h"
      41                 : #include "nsRange.h"
      42                 : #include "nsIPrivateTextRange.h"
      43                 : #include "nsISelection.h"
      44                 : #include "nsISelectionPrivate.h"
      45                 : #include "nsISelectionController.h"
      46                 : #include "nsComponentManagerUtils.h"
      47                 : #include "nsIEditor.h"
      48                 : 
      49                 : // #define DEBUG_IMETXN
      50                 : 
      51               0 : IMETextTxn::IMETextTxn()
      52               0 :   : EditTxn()
      53                 : {
      54               0 : }
      55                 : 
      56            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(IMETextTxn)
      57                 : 
      58               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IMETextTxn, EditTxn)
      59               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mElement)
      60                 :   // mRangeList can't lead to cycles
      61               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
      62                 : 
      63               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IMETextTxn, EditTxn)
      64               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mElement)
      65                 :   // mRangeList can't lead to cycles
      66               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      67                 : 
      68               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IMETextTxn)
      69               0 :   if (aIID.Equals(IMETextTxn::GetCID())) {
      70               0 :     *aInstancePtr = (void*)(IMETextTxn*)this;
      71               0 :     NS_ADDREF_THIS();
      72               0 :     return NS_OK;
      73                 :   } else
      74               0 : NS_INTERFACE_MAP_END_INHERITING(EditTxn)
      75                 : 
      76               0 : NS_IMETHODIMP IMETextTxn::Init(nsIDOMCharacterData     *aElement,
      77                 :                                PRUint32                 aOffset,
      78                 :                                PRUint32                 aReplaceLength,
      79                 :                                nsIPrivateTextRangeList *aTextRangeList,
      80                 :                                const nsAString         &aStringToInsert,
      81                 :                                nsIEditor               *aEditor)
      82                 : {
      83               0 :   NS_ASSERTION(aElement, "illegal value- null ptr- aElement");
      84               0 :   NS_ASSERTION(aTextRangeList, "illegal value- null ptr - aTextRangeList");
      85               0 :   NS_ENSURE_TRUE(aElement && aTextRangeList, NS_ERROR_NULL_POINTER);
      86               0 :   mElement = do_QueryInterface(aElement);
      87               0 :   mOffset = aOffset;
      88               0 :   mReplaceLength = aReplaceLength;
      89               0 :   mStringToInsert = aStringToInsert;
      90               0 :   mEditor = aEditor;
      91               0 :   mRangeList = do_QueryInterface(aTextRangeList);
      92               0 :   mFixed = false;
      93               0 :   return NS_OK;
      94                 : }
      95                 : 
      96               0 : NS_IMETHODIMP IMETextTxn::DoTransaction(void)
      97                 : {
      98                 : 
      99                 : #ifdef DEBUG_IMETXN
     100                 :   printf("Do IME Text element = %p replace = %d len = %d\n", mElement.get(), mReplaceLength, mStringToInsert.Length());
     101                 : #endif
     102                 : 
     103               0 :   nsCOMPtr<nsISelectionController> selCon;
     104               0 :   mEditor->GetSelectionController(getter_AddRefs(selCon));
     105               0 :   NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED);
     106                 : 
     107                 :   // advance caret: This requires the presentation shell to get the selection.
     108                 :   nsresult result;
     109               0 :   if (mReplaceLength == 0) {
     110               0 :     result = mElement->InsertData(mOffset, mStringToInsert);
     111                 :   } else {
     112               0 :     result = mElement->ReplaceData(mOffset, mReplaceLength, mStringToInsert);
     113                 :   }
     114               0 :   if (NS_SUCCEEDED(result)) {
     115               0 :     result = CollapseTextSelection();
     116                 :   }
     117                 : 
     118               0 :   return result;
     119                 : }
     120                 : 
     121               0 : NS_IMETHODIMP IMETextTxn::UndoTransaction(void)
     122                 : {
     123                 : #ifdef DEBUG_IMETXN
     124                 :   printf("Undo IME Text element = %p\n", mElement.get());
     125                 : #endif
     126                 : 
     127               0 :   nsCOMPtr<nsISelectionController> selCon;
     128               0 :   mEditor->GetSelectionController(getter_AddRefs(selCon));
     129               0 :   NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED);
     130                 : 
     131               0 :   nsresult result = mElement->DeleteData(mOffset, mStringToInsert.Length());
     132               0 :   if (NS_SUCCEEDED(result))
     133                 :   { // set the selection to the insertion point where the string was removed
     134               0 :     nsCOMPtr<nsISelection> selection;
     135               0 :     result = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
     136               0 :     if (NS_SUCCEEDED(result) && selection) {
     137               0 :       result = selection->Collapse(mElement, mOffset);
     138               0 :       NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of IME insert.");
     139                 :     }
     140                 :   }
     141               0 :   return result;
     142                 : }
     143                 : 
     144               0 : NS_IMETHODIMP IMETextTxn::Merge(nsITransaction *aTransaction, bool *aDidMerge)
     145                 : {
     146               0 :   NS_ASSERTION(aDidMerge, "illegal vaule- null ptr- aDidMerge");
     147               0 :   NS_ASSERTION(aTransaction, "illegal vaule- null ptr- aTransaction");
     148               0 :   NS_ENSURE_TRUE(aDidMerge && aTransaction, NS_ERROR_NULL_POINTER);
     149                 :     
     150                 : #ifdef DEBUG_IMETXN
     151                 :   printf("Merge IME Text element = %p\n", mElement.get());
     152                 : #endif
     153                 : 
     154                 :   // 
     155                 :   // check to make sure we aren't fixed, if we are then nothing get's absorbed
     156                 :   //
     157               0 :   if (mFixed) {
     158               0 :     *aDidMerge = false;
     159               0 :     return NS_OK;
     160                 :   }
     161                 : 
     162                 :   //
     163                 :   // if aTransaction is another IMETextTxn then absorb it
     164                 :   //
     165               0 :   IMETextTxn*  otherTxn = nsnull;
     166               0 :   nsresult result = aTransaction->QueryInterface(IMETextTxn::GetCID(),(void**)&otherTxn);
     167               0 :   if (otherTxn && NS_SUCCEEDED(result))
     168                 :   {
     169                 :     //
     170                 :     //  we absorb the next IME transaction by adopting its insert string as our own
     171                 :     //
     172                 :     nsIPrivateTextRangeList* newTextRangeList;
     173               0 :     otherTxn->GetData(mStringToInsert,&newTextRangeList);
     174               0 :     mRangeList = do_QueryInterface(newTextRangeList);
     175               0 :     *aDidMerge = true;
     176                 : #ifdef DEBUG_IMETXN
     177                 :     printf("IMETextTxn assimilated IMETextTxn:%p\n", aTransaction);
     178                 : #endif
     179               0 :     NS_RELEASE(otherTxn);
     180               0 :     return NS_OK;
     181                 :   }
     182                 : 
     183               0 :   *aDidMerge = false;
     184               0 :   return NS_OK;
     185                 : }
     186                 : 
     187               0 : NS_IMETHODIMP IMETextTxn::MarkFixed(void)
     188                 : {
     189               0 :   mFixed = true;
     190               0 :   return NS_OK;
     191                 : }
     192                 : 
     193               0 : NS_IMETHODIMP IMETextTxn::GetTxnDescription(nsAString& aString)
     194                 : {
     195               0 :   aString.AssignLiteral("IMETextTxn: ");
     196               0 :   aString += mStringToInsert;
     197               0 :   return NS_OK;
     198                 : }
     199                 : 
     200                 : /* ============ protected methods ================== */
     201               0 : static SelectionType TextRangeToSelection(int aTextRangeType)
     202                 : {
     203               0 :    switch(aTextRangeType)
     204                 :    {
     205                 :       case nsIPrivateTextRange::TEXTRANGE_RAWINPUT:
     206               0 :            return nsISelectionController::SELECTION_IME_RAWINPUT;
     207                 :       case nsIPrivateTextRange::TEXTRANGE_SELECTEDRAWTEXT:
     208               0 :            return nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT;
     209                 :       case nsIPrivateTextRange::TEXTRANGE_CONVERTEDTEXT:
     210               0 :            return nsISelectionController::SELECTION_IME_CONVERTEDTEXT;
     211                 :       case nsIPrivateTextRange::TEXTRANGE_SELECTEDCONVERTEDTEXT:
     212               0 :            return nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
     213                 :       case nsIPrivateTextRange::TEXTRANGE_CARETPOSITION:
     214                 :       default:
     215               0 :            return nsISelectionController::SELECTION_NORMAL;
     216                 :    };
     217                 : }
     218                 : 
     219               0 : NS_IMETHODIMP IMETextTxn::GetData(nsString& aResult,nsIPrivateTextRangeList** aTextRangeList)
     220                 : {
     221               0 :   NS_ASSERTION(aTextRangeList, "illegal value- null ptr- aTextRangeList");
     222               0 :   NS_ENSURE_TRUE(aTextRangeList, NS_ERROR_NULL_POINTER);
     223               0 :   aResult = mStringToInsert;
     224               0 :   *aTextRangeList = mRangeList;
     225               0 :   return NS_OK;
     226                 : }
     227                 : 
     228                 : static SelectionType sel[4]=
     229                 : {
     230                 :   nsISelectionController::SELECTION_IME_RAWINPUT,
     231                 :   nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT,
     232                 :   nsISelectionController::SELECTION_IME_CONVERTEDTEXT,
     233                 :   nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT
     234                 : };
     235                 : 
     236               0 : NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void)
     237                 : {
     238                 :     nsresult      result;
     239                 :     PRUint16      i;
     240                 : 
     241                 : #ifdef DEBUG_IMETXN
     242                 :     PRUint16 listlen,start,stop,type;
     243                 :     result = mRangeList->GetLength(&listlen);
     244                 :     printf("nsIPrivateTextRangeList[%p]\n",mRangeList);
     245                 :     nsIPrivateTextRange* rangePtr;
     246                 :     for (i=0;i<listlen;i++) {
     247                 :       (void)mRangeList->Item(i,&rangePtr);
     248                 :       rangePtr->GetRangeStart(&start);
     249                 :       rangePtr->GetRangeEnd(&stop);
     250                 :       rangePtr->GetRangeType(&type);
     251                 :       printf("range[%d] start=%d end=%d type=",i,start,stop,type);
     252                 :       if (type==nsIPrivateTextRange::TEXTRANGE_RAWINPUT)
     253                 :                              printf("TEXTRANGE_RAWINPUT\n");
     254                 :       else if (type==nsIPrivateTextRange::TEXTRANGE_SELECTEDRAWTEXT)
     255                 :                                   printf("TEXTRANGE_SELECTEDRAWTEXT\n");
     256                 :       else if (type==nsIPrivateTextRange::TEXTRANGE_CONVERTEDTEXT)
     257                 :                                   printf("TEXTRANGE_CONVERTEDTEXT\n");
     258                 :       else if (type==nsIPrivateTextRange::TEXTRANGE_SELECTEDCONVERTEDTEXT)
     259                 :                                   printf("TEXTRANGE_SELECTEDCONVERTEDTEXT\n");
     260                 :       else if (type==nsIPrivateTextRange::TEXTRANGE_CARETPOSITION)
     261                 :                                   printf("TEXTRANGE_CARETPOSITION\n");
     262                 :       else printf("unknown constant\n");
     263                 :     }
     264                 : #endif
     265                 :         
     266                 :     //
     267                 :     // run through the text range list, if any
     268                 :     //
     269               0 :     nsCOMPtr<nsISelectionController> selCon;
     270               0 :     mEditor->GetSelectionController(getter_AddRefs(selCon));
     271               0 :     NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED);
     272                 : 
     273                 :     PRUint16      textRangeListLength,selectionStart,selectionEnd,
     274                 :                   textRangeType;
     275                 :     
     276               0 :     textRangeListLength = mRangeList->GetLength();
     277               0 :     nsCOMPtr<nsISelection> selection;
     278               0 :     result = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
     279               0 :     if(NS_SUCCEEDED(result))
     280                 :     {
     281               0 :       nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
     282               0 :       result = selPriv->StartBatchChanges();
     283               0 :       if (NS_SUCCEEDED(result))
     284                 :       {
     285               0 :         nsCOMPtr<nsISelection> imeSel;
     286               0 :         for(PRInt8 selIdx = 0; selIdx < 4;selIdx++)
     287                 :         {
     288               0 :           result = selCon->GetSelection(sel[selIdx], getter_AddRefs(imeSel));
     289               0 :           if (NS_SUCCEEDED(result))
     290                 :           {
     291               0 :             result = imeSel->RemoveAllRanges();
     292               0 :             NS_ASSERTION(NS_SUCCEEDED(result), "Cannot ClearSelection");
     293                 :             // we just ignore the result and clean up the next one here
     294                 :           }
     295                 :         }
     296                 : 
     297               0 :         nsCOMPtr<nsIPrivateTextRange> textRange;
     298               0 :         bool setCaret=false;
     299               0 :         for(i=0;i<textRangeListLength;i++)
     300                 :         {
     301               0 :           textRange = mRangeList->Item(i);
     302               0 :           NS_ASSERTION(textRange, "cannot get item");
     303               0 :           if(!textRange)
     304               0 :                break;
     305                 : 
     306               0 :           result = textRange->GetRangeType(&textRangeType);
     307               0 :           NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range type");
     308               0 :           if(NS_FAILED(result))
     309               0 :                break;
     310                 : 
     311               0 :           result = textRange->GetRangeStart(&selectionStart);
     312               0 :           NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range start");
     313               0 :           if(NS_FAILED(result))
     314               0 :                break;
     315               0 :           result = textRange->GetRangeEnd(&selectionEnd);
     316               0 :           NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range end");
     317               0 :           if(NS_FAILED(result))
     318               0 :                break;
     319                 : 
     320               0 :           if(nsIPrivateTextRange::TEXTRANGE_CARETPOSITION == textRangeType)
     321                 :           {
     322               0 :              NS_ASSERTION(selectionStart == selectionEnd,
     323                 :                           "nsEditor doesn't support wide caret");
     324                 :              // Set the caret....
     325               0 :              result = selection->Collapse(mElement,
     326               0 :                       mOffset+selectionStart);
     327               0 :              NS_ASSERTION(NS_SUCCEEDED(result), "Cannot Collapse");
     328               0 :              if(NS_SUCCEEDED(result))
     329               0 :              setCaret = true;
     330                 :           } else {
     331                 :              // NS_ASSERTION(selectionStart != selectionEnd, "end == start");
     332               0 :              if(selectionStart == selectionEnd)
     333               0 :                 continue;
     334                 : 
     335               0 :              result= selCon->GetSelection(TextRangeToSelection(textRangeType),
     336               0 :                      getter_AddRefs(imeSel));
     337               0 :              NS_ASSERTION(NS_SUCCEEDED(result), "Cannot get selction");
     338               0 :              if(NS_FAILED(result))
     339               0 :                 break;
     340                 : 
     341               0 :              nsRefPtr<nsRange> newRange = new nsRange();
     342               0 :              result = newRange->SetStart(mElement,mOffset+selectionStart);
     343               0 :              NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetStart");
     344               0 :              if(NS_FAILED(result))
     345                 :                 break;
     346                 : 
     347               0 :              result = newRange->SetEnd(mElement,mOffset+selectionEnd);
     348               0 :              NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetEnd");
     349               0 :              if(NS_FAILED(result))
     350                 :                 break;
     351                 : 
     352               0 :              result = imeSel->AddRange(newRange);
     353               0 :              NS_ASSERTION(NS_SUCCEEDED(result), "Cannot AddRange");
     354               0 :              if(NS_FAILED(result))
     355                 :                 break;
     356                 : 
     357                 :              nsCOMPtr<nsISelectionPrivate> imeSelPriv(
     358               0 :                                              do_QueryInterface(imeSel));
     359               0 :              if (imeSelPriv) {
     360               0 :                nsTextRangeStyle textRangeStyle;
     361               0 :                result = textRange->GetRangeStyle(&textRangeStyle);
     362               0 :                NS_ASSERTION(NS_SUCCEEDED(result),
     363                 :                             "nsIPrivateTextRange::GetRangeStyle failed");
     364               0 :                if (NS_FAILED(result))
     365                 :                  break;
     366               0 :                result = imeSelPriv->SetTextRangeStyle(newRange, textRangeStyle);
     367               0 :                NS_ASSERTION(NS_SUCCEEDED(result),
     368                 :                  "nsISelectionPrivate::SetTextRangeStyle failed");
     369               0 :                if (NS_FAILED(result))
     370                 :                  break;
     371                 :              } else {
     372               0 :                NS_WARNING("IME selection doesn't have nsISelectionPrivate");
     373                 :              }
     374                 :           } // if GetRangeEnd
     375                 :         } // for textRangeListLength
     376               0 :         if(! setCaret) {
     377                 :           // set cursor
     378               0 :           result = selection->Collapse(mElement,mOffset+mStringToInsert.Length());
     379               0 :           NS_ASSERTION(NS_SUCCEEDED(result), "Cannot Collapse");
     380                 :         }
     381               0 :         result = selPriv->EndBatchChanges();
     382               0 :         NS_ASSERTION(NS_SUCCEEDED(result), "Cannot EndBatchChanges");
     383                 :       } // if StartBatchChanges
     384                 :     } // if GetSelection
     385                 : 
     386               0 :     return result;
     387            4392 : }
     388                 : 

Generated by: LCOV version 1.7