Back to index

lightning-sunbird  0.9+nobinonly
nsMaiInterfaceText.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* vim:expandtab:shiftwidth=4:tabstop=4:
00003  */
00004 /* ***** BEGIN LICENSE BLOCK *****
00005  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  *
00008  * The contents of this file are subject to the Mozilla Public
00009  * License Version 1.1 (the "License"); you may not use this file
00010  * except in compliance with the License. You may obtain a copy of
00011  * the License at http://www.mozilla.org/MPL/
00012  *
00013  * Software distributed under the License is distributed on an "AS
00014  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
00015  * implied. See the License for the specific language governing
00016  * rights and limitations under the License.
00017  *
00018  * The Original Code is mozilla.org code.
00019  *
00020  * The Initial Developer of the Original Code is Sun Microsystems, Inc.
00021  * Portions created by Sun Microsystems are Copyright (C) 2002 Sun
00022  * Microsystems, Inc. All Rights Reserved.
00023  *
00024  * Original Author: Bolian Yin (bolian.yin@sun.com)
00025  *
00026  * Contributor(s):
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either the GNU General Public License Version 2 or later (the "GPL"), or
00030  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the NPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the NPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #include "nsMaiInterfaceText.h"
00043 #include "nsString.h"
00044 
00045 G_BEGIN_DECLS
00046 
00047 static void interfaceInitCB(AtkTextIface *aIface);
00048 
00049 /* text interface callbacks */
00050 static gchar *getTextCB(AtkText *aText,
00051                         gint aStartOffset, gint aEndOffset);
00052 static gchar *getTextAfterOffsetCB(AtkText *aText, gint aOffset,
00053                                    AtkTextBoundary aBoundaryType,
00054                                    gint *aStartOffset, gint *aEndOffset);
00055 static gchar *getTextAtOffsetCB(AtkText *aText, gint aOffset,
00056                                 AtkTextBoundary aBoundaryType,
00057                                 gint *aStartOffset, gint *aEndOffset);
00058 static gunichar getCharacterAtOffsetCB(AtkText *aText, gint aOffset);
00059 static gchar *getTextBeforeOffsetCB(AtkText *aText, gint aOffset,
00060                                     AtkTextBoundary aBoundaryType,
00061                                     gint *aStartOffset, gint *aEndOffset);
00062 static gint getCaretOffsetCB(AtkText *aText);
00063 static AtkAttributeSet *getRunAttributesCB(AtkText *aText, gint aOffset,
00064                                            gint *aStartOffset,
00065                                            gint *aEndOffset);
00066 static AtkAttributeSet* getDefaultAttributesCB(AtkText *aText);
00067 static void getCharacterExtentsCB(AtkText *aText, gint aOffset,
00068                                   gint *aX, gint *aY,
00069                                   gint *aWidth, gint *aHeight,
00070                                   AtkCoordType aCoords);
00071 static gint getCharacterCountCB(AtkText *aText);
00072 static gint getOffsetAtPointCB(AtkText *aText,
00073                                gint aX, gint aY,
00074                                AtkCoordType aCoords);
00075 static gint getSelectionCountCB(AtkText *aText);
00076 static gchar *getSelectionCB(AtkText *aText, gint aSelectionNum,
00077                              gint *aStartOffset, gint *aEndOffset);
00078 
00079 // set methods
00080 static gboolean addSelectionCB(AtkText *aText,
00081                                gint aStartOffset,
00082                                gint aEndOffset);
00083 static gboolean removeSelectionCB(AtkText *aText,
00084                                   gint aSelectionNum);
00085 static gboolean setSelectionCB(AtkText *aText, gint aSelectionNum,
00086                                gint aStartOffset, gint aEndOffset);
00087 static gboolean setCaretOffsetCB(AtkText *aText, gint aOffset);
00088 
00089 /*************************************************
00090  // signal handlers
00091  //
00092     static void TextChangedCB(AtkText *aText, gint aPosition, gint aLength);
00093     static void TextCaretMovedCB(AtkText *aText, gint aLocation);
00094     static void TextSelectionChangedCB(AtkText *aText);
00095 */
00096 G_END_DECLS
00097 
00098 MaiInterfaceText::MaiInterfaceText(nsAccessibleWrap *aAccWrap):
00099     MaiInterface(aAccWrap)
00100 {
00101 }
00102 
00103 MaiInterfaceText::~MaiInterfaceText()
00104 {
00105 }
00106 
00107 MaiInterfaceType
00108 MaiInterfaceText::GetType()
00109 {
00110     return MAI_INTERFACE_TEXT;
00111 }
00112 
00113 const GInterfaceInfo *
00114 MaiInterfaceText::GetInterfaceInfo()
00115 {
00116     static const GInterfaceInfo atk_if_text_info = {
00117         (GInterfaceInitFunc)interfaceInitCB,
00118         (GInterfaceFinalizeFunc) NULL,
00119         NULL
00120     };
00121     return &atk_if_text_info;
00122 }
00123 
00124 /* statics */
00125 
00126 void
00127 interfaceInitCB(AtkTextIface *aIface)
00128 {
00129     NS_ASSERTION(aIface, "Invalid aIface");
00130     if (!aIface)
00131         return;
00132 
00133     aIface->get_text = getTextCB;
00134     aIface->get_text_after_offset = getTextAfterOffsetCB;
00135     aIface->get_text_at_offset = getTextAtOffsetCB;
00136     aIface->get_character_at_offset = getCharacterAtOffsetCB;
00137     aIface->get_text_before_offset = getTextBeforeOffsetCB;
00138     aIface->get_caret_offset = getCaretOffsetCB;
00139     aIface->get_run_attributes = getRunAttributesCB;
00140     aIface->get_default_attributes = getDefaultAttributesCB;
00141     aIface->get_character_extents = getCharacterExtentsCB;
00142     aIface->get_character_count = getCharacterCountCB;
00143     aIface->get_offset_at_point = getOffsetAtPointCB;
00144     aIface->get_n_selections = getSelectionCountCB;
00145     aIface->get_selection = getSelectionCB;
00146 
00147     // set methods
00148     aIface->add_selection = addSelectionCB;
00149     aIface->remove_selection = removeSelectionCB;
00150     aIface->set_selection = setSelectionCB;
00151     aIface->set_caret_offset = setCaretOffsetCB;
00152 }
00153 
00154 
00155 void ConvertTexttoAsterisks(nsAccessibleWrap* accWrap, nsAString& aString)
00156 {
00157     // convert each char to "*" when it's "password text" 
00158     PRUint32 accRole;
00159     accWrap->GetRole(&accRole);
00160     if (NS_STATIC_CAST(AtkRole, accRole) == ATK_ROLE_PASSWORD_TEXT) {
00161         for (PRUint32 i = 0; i < aString.Length(); i++)
00162             aString.Replace(i, 1, NS_LITERAL_STRING("*"));
00163     }
00164 }
00165 
00166 gchar *
00167 getTextCB(AtkText *aText, gint aStartOffset, gint aEndOffset)
00168 {
00169     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00170     NS_ENSURE_TRUE(accWrap, nsnull);
00171 
00172     nsCOMPtr<nsIAccessibleText> accText;
00173     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00174                             getter_AddRefs(accText));
00175     NS_ENSURE_TRUE(accText, nsnull);
00176 
00177     nsAutoString autoStr;
00178     nsresult rv = accText->GetText(aStartOffset, aEndOffset, autoStr);
00179     NS_ENSURE_SUCCESS(rv, nsnull);
00180 
00181     ConvertTexttoAsterisks(accWrap, autoStr);
00182     NS_ConvertUTF16toUTF8 cautoStr(autoStr);
00183 
00184     //copy and return, libspi will free it.
00185     return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nsnull;
00186 }
00187 
00188 gchar *
00189 getTextAfterOffsetCB(AtkText *aText, gint aOffset,
00190                      AtkTextBoundary aBoundaryType,
00191                      gint *aStartOffset, gint *aEndOffset)
00192 {
00193     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00194     NS_ENSURE_TRUE(accWrap, nsnull);
00195 
00196     nsCOMPtr<nsIAccessibleText> accText;
00197     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00198                             getter_AddRefs(accText));
00199     NS_ENSURE_TRUE(accText, nsnull);
00200 
00201     nsAutoString autoStr;
00202     PRInt32 startOffset = 0, endOffset = 0;
00203     nsresult rv =
00204         accText->GetTextAfterOffset(aOffset, aBoundaryType,
00205                                     &startOffset, &endOffset, autoStr);
00206     *aStartOffset = startOffset;
00207     *aEndOffset = endOffset;
00208 
00209     NS_ENSURE_SUCCESS(rv, nsnull);
00210 
00211     ConvertTexttoAsterisks(accWrap, autoStr);
00212     NS_ConvertUTF16toUTF8 cautoStr(autoStr);
00213     return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nsnull;
00214 }
00215 
00216 gchar *
00217 getTextAtOffsetCB(AtkText *aText, gint aOffset,
00218                   AtkTextBoundary aBoundaryType,
00219                   gint *aStartOffset, gint *aEndOffset)
00220 {
00221     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00222     NS_ENSURE_TRUE(accWrap, nsnull);
00223 
00224     nsCOMPtr<nsIAccessibleText> accText;
00225     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00226                             getter_AddRefs(accText));
00227     NS_ENSURE_TRUE(accText, nsnull);
00228 
00229     nsAutoString autoStr;
00230     PRInt32 startOffset = 0, endOffset = 0;
00231     nsresult rv =
00232         accText->GetTextAtOffset(aOffset, aBoundaryType,
00233                                  &startOffset, &endOffset, autoStr);
00234     *aStartOffset = startOffset;
00235     *aEndOffset = endOffset;
00236 
00237     NS_ENSURE_SUCCESS(rv, nsnull);
00238 
00239     ConvertTexttoAsterisks(accWrap, autoStr);
00240     NS_ConvertUTF16toUTF8 cautoStr(autoStr);
00241     return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nsnull;
00242 }
00243 
00244 gunichar
00245 getCharacterAtOffsetCB(AtkText *aText, gint aOffset)
00246 {
00247     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00248     NS_ENSURE_TRUE(accWrap, 0);
00249 
00250     nsCOMPtr<nsIAccessibleText> accText;
00251     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00252                             getter_AddRefs(accText));
00253     NS_ENSURE_TRUE(accText, 0);
00254 
00255     /* PRUnichar is unsigned short in Mozilla */
00256     /* gnuichar is guint32 in glib */
00257     PRUnichar uniChar;
00258     nsresult rv =
00259         accText->GetCharacterAtOffset(aOffset, &uniChar);
00260 
00261     // convert char to "*" when it's "password text" 
00262     PRUint32 accRole;
00263     accWrap->GetRole(&accRole);
00264     if (NS_STATIC_CAST(AtkRole, accRole) == ATK_ROLE_PASSWORD_TEXT) {
00265         uniChar = '*';
00266     }
00267 
00268     return (NS_FAILED(rv)) ? 0 : NS_STATIC_CAST(gunichar, uniChar);
00269 }
00270 
00271 gchar *
00272 getTextBeforeOffsetCB(AtkText *aText, gint aOffset,
00273                       AtkTextBoundary aBoundaryType,
00274                       gint *aStartOffset, gint *aEndOffset)
00275 {
00276     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00277     NS_ENSURE_TRUE(accWrap, nsnull);
00278 
00279     nsCOMPtr<nsIAccessibleText> accText;
00280     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00281                             getter_AddRefs(accText));
00282     NS_ENSURE_TRUE(accText, nsnull);
00283 
00284     nsAutoString autoStr;
00285     PRInt32 startOffset = 0, endOffset = 0;
00286     nsresult rv =
00287         accText->GetTextBeforeOffset(aOffset, aBoundaryType,
00288                                      &startOffset, &endOffset, autoStr);
00289     *aStartOffset = startOffset;
00290     *aEndOffset = endOffset;
00291 
00292     NS_ENSURE_SUCCESS(rv, nsnull);
00293 
00294     ConvertTexttoAsterisks(accWrap, autoStr);
00295     NS_ConvertUTF16toUTF8 cautoStr(autoStr);
00296     return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nsnull;
00297 }
00298 
00299 gint
00300 getCaretOffsetCB(AtkText *aText)
00301 {
00302     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00303     NS_ENSURE_TRUE(accWrap, 0);
00304 
00305     nsCOMPtr<nsIAccessibleText> accText;
00306     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00307                             getter_AddRefs(accText));
00308     NS_ENSURE_TRUE(accText, 0);
00309 
00310     PRInt32 offset;
00311     nsresult rv = accText->GetCaretOffset(&offset);
00312     return (NS_FAILED(rv)) ? 0 : NS_STATIC_CAST(gint, offset);
00313 }
00314 
00315 AtkAttributeSet *
00316 getRunAttributesCB(AtkText *aText, gint aOffset,
00317                    gint *aStartOffset,
00318                    gint *aEndOffset)
00319 {
00320     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00321     NS_ENSURE_TRUE(accWrap, nsnull);
00322 
00323     nsCOMPtr<nsIAccessibleText> accText;
00324     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00325                             getter_AddRefs(accText));
00326     NS_ENSURE_TRUE(accText, nsnull);
00327 
00328     nsCOMPtr<nsISupports> attrSet;
00329     PRInt32 startOffset = 0, endOffset = 0;
00330     nsresult rv = accText->GetAttributeRange(aOffset,
00331                                              &startOffset, &endOffset,
00332                                              getter_AddRefs(attrSet));
00333     *aStartOffset = startOffset;
00334     *aEndOffset = endOffset;
00335     NS_ENSURE_SUCCESS(rv, nsnull);
00336 
00337     /* what to do with the nsISupports ? ??? */
00338     return nsnull;
00339 }
00340 
00341 AtkAttributeSet *
00342 getDefaultAttributesCB(AtkText *aText)
00343 {
00344     /* not supported ??? */
00345     return nsnull;
00346 }
00347 
00348 void
00349 getCharacterExtentsCB(AtkText *aText, gint aOffset,
00350                       gint *aX, gint *aY,
00351                       gint *aWidth, gint *aHeight,
00352                       AtkCoordType aCoords)
00353 {
00354     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00355     if(!accWrap)
00356         return;
00357 
00358     nsCOMPtr<nsIAccessibleText> accText;
00359     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00360                             getter_AddRefs(accText));
00361     if (!accText)
00362         return;
00363 
00364     PRInt32 extY = 0, extX = 0;
00365     PRInt32 extWidth = 0, extHeight = 0;
00366     nsresult rv = accText->GetCharacterExtents(aOffset, &extX, &extY,
00367                                                &extWidth, &extHeight,
00368                                                aCoords);
00369     *aX = extX;
00370     *aY = extY;
00371     *aWidth = extWidth;
00372     *aHeight = extHeight;
00373     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
00374                      "MaiInterfaceText::GetCharacterExtents, failed\n");
00375 }
00376 
00377 gint
00378 getCharacterCountCB(AtkText *aText)
00379 {
00380     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00381     NS_ENSURE_TRUE(accWrap, 0);
00382 
00383     nsCOMPtr<nsIAccessibleText> accText;
00384     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00385                             getter_AddRefs(accText));
00386     NS_ENSURE_TRUE(accText, 0);
00387 
00388     PRInt32 count = 0;
00389     nsresult rv = accText->GetCharacterCount(&count);
00390     return (NS_FAILED(rv)) ? 0 : NS_STATIC_CAST(gint, count);
00391 }
00392 
00393 gint
00394 getOffsetAtPointCB(AtkText *aText,
00395                    gint aX, gint aY,
00396                    AtkCoordType aCoords)
00397 {
00398     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00399     NS_ENSURE_TRUE(accWrap, 0);
00400 
00401     nsCOMPtr<nsIAccessibleText> accText;
00402     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00403                             getter_AddRefs(accText));
00404     NS_ENSURE_TRUE(accText, 0);
00405 
00406     PRInt32 offset = 0;
00407     nsresult rv = accText->GetOffsetAtPoint(aX, aY, aCoords, &offset);
00408     return (NS_FAILED(rv)) ? 0 : NS_STATIC_CAST(gint, offset);
00409 }
00410 
00411 gint
00412 getSelectionCountCB(AtkText *aText)
00413 {
00414     /* no implemetation in nsIAccessibleText??? */
00415 
00416     //new attribuate will be added in nsIAccessibleText.idl
00417     //readonly attribute long selectionCount;
00418 
00419     return 0;
00420 }
00421 
00422 gchar *
00423 getSelectionCB(AtkText *aText, gint aSelectionNum,
00424                gint *aStartOffset, gint *aEndOffset)
00425 {
00426     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00427     NS_ENSURE_TRUE(accWrap, nsnull);
00428 
00429     nsCOMPtr<nsIAccessibleText> accText;
00430     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00431                             getter_AddRefs(accText));
00432     NS_ENSURE_TRUE(accText, nsnull);
00433 
00434     PRInt32 startOffset = 0, endOffset = 0;
00435     nsresult rv = accText->GetSelectionBounds(aSelectionNum,
00436                                               &startOffset, &endOffset);
00437 
00438     *aStartOffset = startOffset;
00439     *aEndOffset = endOffset;
00440 
00441     NS_ENSURE_SUCCESS(rv, nsnull);
00442 
00443     return getTextCB(aText, *aStartOffset, *aEndOffset);
00444 }
00445 
00446 // set methods
00447 gboolean
00448 addSelectionCB(AtkText *aText,
00449                gint aStartOffset,
00450                gint aEndOffset)
00451 {
00452     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00453     NS_ENSURE_TRUE(accWrap, FALSE);
00454 
00455     nsCOMPtr<nsIAccessibleText> accText;
00456     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00457                             getter_AddRefs(accText));
00458     NS_ENSURE_TRUE(accText, FALSE);
00459 
00460     nsresult rv = accText->AddSelection(aStartOffset, aEndOffset);
00461 
00462     return NS_SUCCEEDED(rv) ? TRUE : FALSE;
00463 }
00464 
00465 gboolean
00466 removeSelectionCB(AtkText *aText,
00467                   gint aSelectionNum)
00468 {
00469     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00470     NS_ENSURE_TRUE(accWrap, FALSE);
00471 
00472     nsCOMPtr<nsIAccessibleText> accText;
00473     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00474                             getter_AddRefs(accText));
00475     NS_ENSURE_TRUE(accText, FALSE);
00476 
00477     nsresult rv = accText->RemoveSelection(aSelectionNum);
00478 
00479     return NS_SUCCEEDED(rv) ? TRUE : FALSE;
00480 }
00481 
00482 gboolean
00483 setSelectionCB(AtkText *aText, gint aSelectionNum,
00484                gint aStartOffset, gint aEndOffset)
00485 {
00486     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00487     NS_ENSURE_TRUE(accWrap, FALSE);
00488 
00489     nsCOMPtr<nsIAccessibleText> accText;
00490     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00491                             getter_AddRefs(accText));
00492     NS_ENSURE_TRUE(accText, FALSE);
00493 
00494     nsresult rv = accText->SetSelectionBounds(aSelectionNum,
00495                                               aStartOffset, aEndOffset);
00496     return NS_SUCCEEDED(rv) ? TRUE : FALSE;
00497 }
00498 
00499 gboolean
00500 setCaretOffsetCB(AtkText *aText, gint aOffset)
00501 {
00502     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
00503     NS_ENSURE_TRUE(accWrap, FALSE);
00504 
00505     nsCOMPtr<nsIAccessibleText> accText;
00506     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
00507                             getter_AddRefs(accText));
00508     NS_ENSURE_TRUE(accText, FALSE);
00509 
00510     nsresult rv = accText->SetCaretOffset(aOffset);
00511     return NS_SUCCEEDED(rv) ? TRUE : FALSE;
00512 }