Back to index

lightning-sunbird  0.9+nobinonly
nsDataObjCollection.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsDataObjCollection.h"
00039 //#include "nsString.h"
00040 #include "nsVoidArray.h"
00041 #include "nsITransferable.h"
00042 #include "nsClipboard.h"
00043 #include "IENUMFE.H"
00044 
00045 #include <ole2.h>
00046 #ifndef __MINGW32__
00047 #include <urlmon.h>
00048 #endif
00049 
00050 #if 0
00051 #define PRNTDEBUG(_x) printf(_x);
00052 #define PRNTDEBUG2(_x1, _x2) printf(_x1, _x2);
00053 #define PRNTDEBUG3(_x1, _x2, _x3) printf(_x1, _x2, _x3);
00054 #else
00055 #define PRNTDEBUG(_x) // printf(_x);
00056 #define PRNTDEBUG2(_x1, _x2) // printf(_x1, _x2);
00057 #define PRNTDEBUG3(_x1, _x2, _x3) // printf(_x1, _x2, _x3);
00058 #endif
00059 
00060 ULONG nsDataObjCollection::g_cRef = 0;
00061 
00062 EXTERN_C GUID CDECL CLSID_nsDataObjCollection =
00063 { 0x2d851b91, 0xd4c, 0x11d3, { 0x96, 0xd4, 0x0, 0x60, 0xb0, 0xfb, 0x99, 0x56 } };
00064 
00065 /*
00066  * Class nsDataObjCollection
00067  */
00068 
00069 //-----------------------------------------------------
00070 // construction 
00071 //-----------------------------------------------------
00072 nsDataObjCollection::nsDataObjCollection()
00073 {
00074        m_cRef         = 0;
00075   mTransferable   = nsnull;
00076   mDataFlavors    = new nsVoidArray();
00077   mDataObjects    = new nsVoidArray();
00078 
00079   m_enumFE = new CEnumFormatEtc(32);
00080   m_enumFE->AddRef();
00081 
00082 }
00083 
00084 //-----------------------------------------------------
00085 // destruction
00086 //-----------------------------------------------------
00087 nsDataObjCollection::~nsDataObjCollection()
00088 {
00089   NS_IF_RELEASE(mTransferable);
00090   PRInt32 i;
00091   for (i=0;i<mDataFlavors->Count();i++) {
00092     nsString * df = (nsString *)mDataFlavors->ElementAt(i);
00093     delete df;
00094   }
00095   delete mDataFlavors;
00096  
00097   for (i=0;i<mDataObjects->Count();i++) {
00098     IDataObject * dataObj = (IDataObject *)mDataObjects->ElementAt(i);
00099     NS_RELEASE(dataObj);
00100   }
00101   delete mDataObjects;
00102 
00103        m_cRef = 0;
00104   m_enumFE->Release();
00105 
00106 }
00107 
00108 
00109 //-----------------------------------------------------
00110 // IUnknown interface methods - see inknown.h for documentation
00111 //-----------------------------------------------------
00112 STDMETHODIMP nsDataObjCollection::QueryInterface(REFIID riid, void** ppv)
00113 {
00114        *ppv=NULL;
00115 
00116        if ( (IID_IUnknown == riid) || (IID_IDataObject  == riid) ) {
00117               *ppv = static_cast<IDataObject*>(this); 
00118               AddRef();
00119               return NOERROR;
00120        }
00121 
00122        if ( IID_IDataObjCollection == riid ) {
00123               *ppv = static_cast<nsIDataObjCollection*>(this); 
00124               AddRef();
00125               return NOERROR;
00126        }
00127 
00128        return ResultFromScode(E_NOINTERFACE);
00129 }
00130 
00131 //-----------------------------------------------------
00132 STDMETHODIMP_(ULONG) nsDataObjCollection::AddRef()
00133 {
00134        ++g_cRef;
00135   //PRNTDEBUG3("nsDataObjCollection::AddRef  >>>>>>>>>>>>>>>>>> %d on %p\n", (m_cRef+1), this);
00136        return ++m_cRef;
00137 }
00138 
00139 
00140 //-----------------------------------------------------
00141 STDMETHODIMP_(ULONG) nsDataObjCollection::Release()
00142 {
00143   //PRNTDEBUG3("nsDataObjCollection::Release >>>>>>>>>>>>>>>>>> %d on %p\n", (m_cRef-1), this);
00144        if (0 < g_cRef)
00145               --g_cRef;
00146 
00147        if (0 != --m_cRef)
00148               return m_cRef;
00149 
00150        delete this;
00151 
00152        return 0;
00153 }
00154 
00155 //-----------------------------------------------------
00156 BOOL nsDataObjCollection::FormatsMatch(const FORMATETC& source, const FORMATETC& target) const
00157 {
00158        if ((source.cfFormat == target.cfFormat) &&
00159                (source.dwAspect  & target.dwAspect)  &&
00160                (source.tymed     & target.tymed))       {
00161               return TRUE;
00162        } else {
00163               return FALSE;
00164        }
00165 }
00166 
00167 //-----------------------------------------------------
00168 // IDataObject methods
00169 //-----------------------------------------------------
00170 STDMETHODIMP nsDataObjCollection::GetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
00171 {
00172   PRNTDEBUG("nsDataObjCollection::GetData\n");
00173   PRNTDEBUG3("  format: %d  Text: %d\n", pFE->cfFormat, CF_TEXT);
00174 
00175   for (PRInt32 i=0;i<mDataObjects->Count();i++) {
00176     IDataObject * dataObj = (IDataObject *)mDataObjects->ElementAt(i);
00177     if (S_OK == dataObj->GetData(pFE, pSTM)) {
00178       return S_OK;
00179     }
00180   }
00181 
00182        return ResultFromScode(DATA_E_FORMATETC);
00183 }
00184 
00185 
00186 //-----------------------------------------------------
00187 STDMETHODIMP nsDataObjCollection::GetDataHere(LPFORMATETC pFE, LPSTGMEDIUM pSTM)
00188 {
00189   PRNTDEBUG("nsDataObjCollection::GetDataHere\n");
00190               return ResultFromScode(E_FAIL);
00191 }
00192 
00193 
00194 //-----------------------------------------------------
00195 // Other objects querying to see if we support a 
00196 // particular format
00197 //-----------------------------------------------------
00198 STDMETHODIMP nsDataObjCollection::QueryGetData(LPFORMATETC pFE)
00199 {
00200   UINT format = nsClipboard::GetFormat(MULTI_MIME);
00201   PRNTDEBUG("nsDataObjCollection::QueryGetData  ");
00202 
00203   PRNTDEBUG3("format: %d  Mulitple: %d\n", pFE->cfFormat, format);
00204 
00205   if (format == pFE->cfFormat) {
00206     return S_OK;
00207   }
00208 
00209 
00210   for (PRInt32 i=0;i<mDataObjects->Count();i++) {
00211     IDataObject * dataObj = (IDataObject *)mDataObjects->ElementAt(i);
00212     if (S_OK == dataObj->QueryGetData(pFE)) {
00213       return S_OK;
00214     }
00215   }
00216 
00217   PRNTDEBUG2("***** nsDataObjCollection::QueryGetData - Unknown format %d\n", pFE->cfFormat);
00218        return ResultFromScode(E_FAIL);
00219 }
00220 
00221 //-----------------------------------------------------
00222 STDMETHODIMP nsDataObjCollection::GetCanonicalFormatEtc
00223         (LPFORMATETC pFEIn, LPFORMATETC pFEOut)
00224 {
00225   PRNTDEBUG("nsDataObjCollection::GetCanonicalFormatEtc\n");
00226               return ResultFromScode(E_FAIL);
00227 }
00228 
00229 
00230 //-----------------------------------------------------
00231 STDMETHODIMP nsDataObjCollection::SetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM, BOOL fRelease)
00232 {
00233   PRNTDEBUG("nsDataObjCollection::SetData\n");
00234 
00235   return ResultFromScode(E_FAIL);
00236 }
00237 
00238 
00239 //-----------------------------------------------------
00240 STDMETHODIMP nsDataObjCollection::EnumFormatEtc(DWORD dwDir, LPENUMFORMATETC *ppEnum)
00241 {
00242   PRNTDEBUG("nsDataObjCollection::EnumFormatEtc\n");
00243 
00244   switch (dwDir) {
00245     case DATADIR_GET: {
00246        m_enumFE->Clone(ppEnum);
00247     } break;
00248     case DATADIR_SET:
00249         *ppEnum=NULL;
00250         break;
00251     default:
00252         *ppEnum=NULL;
00253         break;
00254   } // switch
00255 
00256   // Since a new one has been created, 
00257   // we will ref count the new clone here 
00258   // before giving it back
00259   if (NULL == *ppEnum)
00260     return ResultFromScode(E_FAIL);
00261   else
00262     (*ppEnum)->AddRef();
00263 
00264   return NOERROR;
00265 
00266 }
00267 
00268 //-----------------------------------------------------
00269 STDMETHODIMP nsDataObjCollection::DAdvise(LPFORMATETC pFE, DWORD dwFlags,
00270                                                                                             LPADVISESINK pIAdviseSink, DWORD* pdwConn)
00271 {
00272   PRNTDEBUG("nsDataObjCollection::DAdvise\n");
00273        return ResultFromScode(E_FAIL);
00274 }
00275 
00276 
00277 //-----------------------------------------------------
00278 STDMETHODIMP nsDataObjCollection::DUnadvise(DWORD dwConn)
00279 {
00280   PRNTDEBUG("nsDataObjCollection::DUnadvise\n");
00281        return ResultFromScode(E_FAIL);
00282 }
00283 
00284 //-----------------------------------------------------
00285 STDMETHODIMP nsDataObjCollection::EnumDAdvise(LPENUMSTATDATA *ppEnum)
00286 {
00287   PRNTDEBUG("nsDataObjCollection::EnumDAdvise\n");
00288        return ResultFromScode(E_FAIL);
00289 }
00290 
00291 //-----------------------------------------------------
00292 // other methods
00293 //-----------------------------------------------------
00294 ULONG nsDataObjCollection::GetCumRefCount()
00295 {
00296        return g_cRef;
00297 }
00298 
00299 //-----------------------------------------------------
00300 ULONG nsDataObjCollection::GetRefCount() const
00301 {
00302        return m_cRef;
00303 }
00304 
00305 //-----------------------------------------------------
00306 // GetData and SetData helper functions
00307 //-----------------------------------------------------
00308 HRESULT nsDataObjCollection::AddSetFormat(FORMATETC& aFE)
00309 {
00310   PRNTDEBUG("nsDataObjCollection::AddSetFormat\n");
00311        return ResultFromScode(S_OK);
00312 }
00313 
00314 //-----------------------------------------------------
00315 HRESULT nsDataObjCollection::AddGetFormat(FORMATETC& aFE)
00316 {
00317   PRNTDEBUG("nsDataObjCollection::AddGetFormat\n");
00318        return ResultFromScode(S_OK);
00319 }
00320 
00321 //-----------------------------------------------------
00322 HRESULT nsDataObjCollection::GetBitmap(FORMATETC&, STGMEDIUM&)
00323 {
00324   PRNTDEBUG("nsDataObjCollection::GetBitmap\n");
00325        return ResultFromScode(E_NOTIMPL);
00326 }
00327 
00328 //-----------------------------------------------------
00329 HRESULT nsDataObjCollection::GetDib(FORMATETC&, STGMEDIUM&)
00330 {
00331   PRNTDEBUG("nsDataObjCollection::GetDib\n");
00332        return ResultFromScode(E_NOTIMPL);
00333 }
00334 
00335 //-----------------------------------------------------
00336 HRESULT nsDataObjCollection::GetMetafilePict(FORMATETC&, STGMEDIUM&)
00337 {
00338        return ResultFromScode(E_NOTIMPL);
00339 }
00340 
00341 //-----------------------------------------------------
00342 HRESULT nsDataObjCollection::SetBitmap(FORMATETC&, STGMEDIUM&)
00343 {
00344        return ResultFromScode(E_NOTIMPL);
00345 }
00346 
00347 //-----------------------------------------------------
00348 HRESULT nsDataObjCollection::SetDib   (FORMATETC&, STGMEDIUM&)
00349 {
00350        return ResultFromScode(E_FAIL);
00351 }
00352 
00353 //-----------------------------------------------------
00354 HRESULT nsDataObjCollection::SetMetafilePict (FORMATETC&, STGMEDIUM&)
00355 {
00356        return ResultFromScode(E_FAIL);
00357 }
00358 
00359 //-----------------------------------------------------
00360 //-----------------------------------------------------
00361 CLSID nsDataObjCollection::GetClassID() const
00362 {
00363        return CLSID_nsDataObjCollection;
00364 }
00365 
00366 //-----------------------------------------------------
00367 // Registers a the DataFlavor/FE pair
00368 //-----------------------------------------------------
00369 void nsDataObjCollection::AddDataFlavor(nsString * aDataFlavor, LPFORMATETC aFE)
00370 {
00371   // These two lists are the mapping to and from data flavors and FEs
00372   // Later, OLE will tell us it's needs a certain type of FORMATETC (text, unicode, etc)
00373   // so we will look up data flavor that corresponds to the FE
00374   // and then ask the transferable for that type of data
00375   mDataFlavors->AppendElement(new nsString(*aDataFlavor));
00376   m_enumFE->AddFE(aFE);
00377 
00378 }
00379 
00380 //-----------------------------------------------------
00381 // Registers a the DataFlavor/FE pair
00382 //-----------------------------------------------------
00383 void nsDataObjCollection::AddDataObject(IDataObject * aDataObj)
00384 {
00385   NS_ADDREF(aDataObj);
00386   mDataObjects->AppendElement(aDataObj);
00387 
00388 }