Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <unotools/streamwrap.hxx>
22 : #include <unotools/ucbstreamhelper.hxx>
23 : #include <comphelper/processfactory.hxx>
24 : #include <comphelper/string.hxx>
25 : #include <ucbhelper/content.hxx>
26 : #include <tools/resmgr.hxx>
27 : #include <tools/urlobj.hxx>
28 : #include <svl/solar.hrc>
29 : #include <svl/urihelper.hxx>
30 : #include <vcl/graphicfilter.hxx>
31 : #include <svl/itempool.hxx>
32 : #include <sfx2/docfile.hxx>
33 : #include <avmedia/mediawindow.hxx>
34 : #include <vcl/svapp.hxx>
35 : #include <vcl/settings.hxx>
36 : #include <svx/svdpage.hxx>
37 : #include <svx/svdograf.hxx>
38 : #include <svx/fmmodel.hxx>
39 : #include <svx/fmview.hxx>
40 : #include <svx/unomodel.hxx>
41 : #include "codec.hxx"
42 : #include "gallery.hrc"
43 : #include "svx/gallery1.hxx"
44 : #include "svx/galtheme.hxx"
45 : #include "svx/galmisc.hxx"
46 : #include <com/sun/star/sdbc/XResultSet.hpp>
47 : #include <com/sun/star/ucb/XContentAccess.hpp>
48 : #include <com/sun/star/ucb/TransferInfo.hpp>
49 : #include <com/sun/star/ucb/NameClash.hpp>
50 : #include <boost/scoped_ptr.hpp>
51 :
52 : using namespace ::com::sun::star;
53 :
54 0 : ResMgr* GetGalleryResMgr()
55 : {
56 : static ResMgr* pGalleryResMgr = NULL;
57 :
58 0 : if( !pGalleryResMgr )
59 : {
60 : pGalleryResMgr = ResMgr::CreateResMgr(
61 0 : "gal", Application::GetSettings().GetUILanguageTag() );
62 : }
63 :
64 0 : return pGalleryResMgr;
65 : }
66 :
67 0 : BitmapEx GalleryResGetBitmapEx( sal_uInt32 nId )
68 : {
69 0 : BitmapEx aBmpEx( GAL_RES( nId ) );
70 :
71 0 : if( !aBmpEx.IsTransparent() )
72 0 : aBmpEx = BitmapEx( aBmpEx.GetBitmap(), COL_LIGHTMAGENTA );
73 :
74 0 : return aBmpEx;
75 : }
76 :
77 0 : IMPL_LINK( SgaUserDataFactory, MakeUserData, SdrObjFactory*, pObjFactory )
78 : {
79 0 : if ( pObjFactory->nInventor == IV_IMAPINFO && pObjFactory->nIdentifier == ID_IMAPINFO )
80 0 : pObjFactory->pNewData = new SgaIMapInfo;
81 :
82 0 : return 0L;
83 : }
84 :
85 503 : sal_uInt16 GalleryGraphicImport( const INetURLObject& rURL, Graphic& rGraphic,
86 : OUString& rFilterName, bool bShowProgress )
87 : {
88 503 : sal_uInt16 nRet = SGA_IMPORT_NONE;
89 503 : SfxMedium aMedium( rURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );
90 :
91 503 : aMedium.Download();
92 :
93 503 : SvStream* pIStm = aMedium.GetInStream();
94 :
95 503 : if( pIStm )
96 : {
97 503 : GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
98 503 : boost::scoped_ptr<GalleryProgress> pProgress(bShowProgress ? new GalleryProgress( &rGraphicFilter ) : NULL);
99 : sal_uInt16 nFormat;
100 :
101 503 : if( !rGraphicFilter.ImportGraphic( rGraphic, rURL.GetMainURL( INetURLObject::NO_DECODE ), *pIStm, GRFILTER_FORMAT_DONTKNOW, &nFormat ) )
102 : {
103 468 : rFilterName = rGraphicFilter.GetImportFormatName( nFormat );
104 468 : nRet = SGA_IMPORT_FILE;
105 503 : }
106 : }
107 :
108 503 : return nRet;
109 : }
110 :
111 0 : bool GallerySvDrawImport( SvStream& rIStm, SdrModel& rModel )
112 : {
113 : sal_uInt32 nVersion;
114 0 : bool bRet = false;
115 :
116 0 : if( GalleryCodec::IsCoded( rIStm, nVersion ) )
117 : {
118 0 : SvMemoryStream aMemStm( 65535, 65535 );
119 0 : GalleryCodec aCodec( rIStm );
120 :
121 0 : aCodec.Read( aMemStm );
122 0 : aMemStm.Seek( 0UL );
123 :
124 0 : if( 1 == nVersion )
125 : {
126 : OSL_FAIL( "staroffice binary file formats are no longer supported inside the gallery!" );
127 0 : bRet = false;
128 : }
129 0 : else if( 2 == nVersion )
130 : {
131 : // recall to read as XML
132 0 : bRet = GallerySvDrawImport( aMemStm, rModel );
133 0 : }
134 : }
135 : else
136 : {
137 : // read as XML
138 0 : uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rIStm ) );
139 :
140 0 : rModel.GetItemPool().SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
141 0 : uno::Reference< lang::XComponent > xComponent;
142 :
143 0 : bRet = SvxDrawingLayerImport( &rModel, xInputStream, xComponent, "com.sun.star.comp.Draw.XMLOasisImporter" );
144 0 : if( !bRet || (rModel.GetPageCount() == 0) )
145 : {
146 0 : rIStm.Seek(0);
147 0 : bRet = SvxDrawingLayerImport( &rModel, xInputStream, xComponent, "com.sun.star.comp.Draw.XMLImporter" );
148 0 : }
149 :
150 : }
151 :
152 0 : return bRet;
153 : }
154 :
155 0 : bool CreateIMapGraphic( const FmFormModel& rModel, Graphic& rGraphic, ImageMap& rImageMap )
156 : {
157 0 : bool bRet = false;
158 :
159 0 : if ( rModel.GetPageCount() )
160 : {
161 0 : const SdrPage* pPage = rModel.GetPage( 0 );
162 0 : const SdrObject* pObj = pPage->GetObj( 0 );
163 :
164 0 : if ( pPage->GetObjCount() == 1 && pObj->ISA( SdrGrafObj ) )
165 : {
166 0 : const sal_uInt16 nCount = pObj->GetUserDataCount();
167 :
168 : // Exist in the user data an IMap information?
169 0 : for ( sal_uInt16 i = 0; i < nCount; i++ )
170 : {
171 0 : const SdrObjUserData* pUserData = pObj->GetUserData( i );
172 :
173 0 : if ( ( pUserData->GetInventor() == IV_IMAPINFO ) && ( pUserData->GetId() == ID_IMAPINFO ) )
174 : {
175 0 : rGraphic = static_cast<const SdrGrafObj*>( pObj )->GetGraphic();
176 0 : rImageMap = static_cast<const SgaIMapInfo*>( pUserData )->GetImageMap();
177 0 : bRet = true;
178 0 : break;
179 : }
180 : }
181 : }
182 : }
183 :
184 0 : return bRet;
185 : }
186 :
187 0 : OUString GetReducedString( const INetURLObject& rURL, sal_Int32 nMaxLen )
188 : {
189 0 : OUString aReduced( rURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) );
190 :
191 0 : aReduced = aReduced.getToken( comphelper::string::getTokenCount(aReduced, '/') - 1, '/' );
192 :
193 0 : if( INET_PROT_PRIV_SOFFICE != rURL.GetProtocol() )
194 : {
195 : sal_Unicode aDelimiter;
196 0 : const OUString aPath( rURL.getFSysPath( INetURLObject::FSYS_DETECT, &aDelimiter ) );
197 0 : const OUString aName( aReduced );
198 :
199 0 : if( aPath.getLength() > nMaxLen )
200 : {
201 0 : sal_Int32 nPathPrefixLen = nMaxLen - aName.getLength() - 4;
202 :
203 0 : if (nPathPrefixLen >= 0)
204 : {
205 0 : aReduced = aPath.copy(0, nPathPrefixLen);
206 0 : aReduced += "...";
207 0 : aReduced += OUString(aDelimiter);
208 0 : aReduced += aName;
209 : }
210 : else
211 : {
212 0 : aReduced += "...";
213 0 : aReduced += OUString(aDelimiter);
214 0 : aReduced += "...";
215 0 : aReduced += aName.copy( aName.getLength() - (nMaxLen - 7) );
216 : }
217 : }
218 : else
219 0 : aReduced = aPath;
220 : }
221 :
222 0 : return aReduced;
223 : }
224 :
225 0 : OUString GetSvDrawStreamNameFromURL( const INetURLObject& rSvDrawObjURL )
226 : {
227 0 : OUString aRet;
228 :
229 0 : if( rSvDrawObjURL.GetProtocol() == INET_PROT_PRIV_SOFFICE &&
230 0 : comphelper::string::getTokenCount(rSvDrawObjURL.GetMainURL( INetURLObject::NO_DECODE ), '/') == 3 )
231 : {
232 0 : aRet = rSvDrawObjURL.GetMainURL( INetURLObject::NO_DECODE ).getToken( 2, '/' );
233 : }
234 :
235 0 : return aRet;
236 : }
237 :
238 679 : bool FileExists( const INetURLObject& rURL )
239 : {
240 679 : bool bRet = false;
241 :
242 679 : if( rURL.GetProtocol() != INET_PROT_NOT_VALID )
243 : {
244 : try
245 : {
246 679 : ::ucbhelper::Content aCnt( rURL.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
247 1358 : OUString aTitle;
248 :
249 802 : aCnt.getPropertyValue("Title") >>= aTitle;
250 1235 : bRet = ( !aTitle.isEmpty() );
251 : }
252 0 : catch( const ucb::ContentCreationException& )
253 : {
254 : }
255 0 : catch( const uno::RuntimeException& )
256 : {
257 : }
258 123 : catch( const uno::Exception& )
259 : {
260 : }
261 : }
262 :
263 679 : return bRet;
264 : }
265 :
266 0 : bool CreateDir( const INetURLObject& rURL )
267 : {
268 0 : bool bRet = FileExists( rURL );
269 :
270 0 : if( !bRet )
271 : {
272 : try
273 : {
274 0 : uno::Reference< ucb::XCommandEnvironment > aCmdEnv;
275 0 : INetURLObject aNewFolderURL( rURL );
276 0 : INetURLObject aParentURL( aNewFolderURL ); aParentURL.removeSegment();
277 0 : ::ucbhelper::Content aParent( aParentURL.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, comphelper::getProcessComponentContext() );
278 0 : uno::Sequence< OUString > aProps( 1 );
279 0 : uno::Sequence< uno::Any > aValues( 1 );
280 :
281 0 : aProps[0] = "Title";
282 0 : aValues[0] = uno::makeAny( OUString( aNewFolderURL.GetName() ) );
283 :
284 0 : ::ucbhelper::Content aContent( aNewFolderURL.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, comphelper::getProcessComponentContext() );
285 0 : bRet = aParent.insertNewContent( OUString("application/vnd.sun.staroffice.fsys-folder"), aProps, aValues, aContent );
286 : }
287 0 : catch( const ucb::ContentCreationException& )
288 : {
289 : }
290 0 : catch( const uno::RuntimeException& )
291 : {
292 : }
293 0 : catch( const uno::Exception& )
294 : {
295 : }
296 : }
297 :
298 0 : return bRet;
299 : }
300 :
301 0 : bool CopyFile( const INetURLObject& rSrcURL, const INetURLObject& rDstURL )
302 : {
303 0 : bool bRet = false;
304 :
305 : try
306 : {
307 0 : ::ucbhelper::Content aDestPath( rDstURL.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
308 :
309 : aDestPath.executeCommand( OUString("transfer"),
310 : uno::makeAny( ucb::TransferInfo( sal_False, rSrcURL.GetMainURL( INetURLObject::NO_DECODE ),
311 0 : rDstURL.GetName(), ucb::NameClash::OVERWRITE ) ) );
312 0 : bRet = true;
313 : }
314 0 : catch( const ucb::ContentCreationException& )
315 : {
316 : }
317 0 : catch( const uno::RuntimeException& )
318 : {
319 : }
320 0 : catch( const uno::Exception& )
321 : {
322 : }
323 :
324 0 : return bRet;
325 : }
326 :
327 22 : bool KillFile( const INetURLObject& rURL )
328 : {
329 22 : bool bRet = FileExists( rURL );
330 :
331 22 : if( bRet )
332 : {
333 : try
334 : {
335 20 : ::ucbhelper::Content aCnt( rURL.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
336 20 : aCnt.executeCommand( OUString("delete"), uno::makeAny( true ) );
337 : }
338 0 : catch( const ucb::ContentCreationException& )
339 : {
340 0 : bRet = false;
341 : }
342 0 : catch( const uno::RuntimeException& )
343 : {
344 0 : bRet = false;
345 : }
346 0 : catch( const uno::Exception& )
347 : {
348 0 : bRet = false;
349 : }
350 : }
351 :
352 22 : return bRet;
353 : }
354 :
355 :
356 0 : GalleryProgress::GalleryProgress( GraphicFilter* pFilter ) :
357 0 : mpFilter( pFilter )
358 : {
359 :
360 0 : uno::Reference< lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
361 :
362 0 : uno::Reference< awt::XProgressMonitor > xMonitor( xMgr->createInstance(
363 0 : OUString("com.sun.star.awt.XProgressMonitor") ),
364 0 : uno::UNO_QUERY );
365 :
366 0 : if ( xMonitor.is() )
367 : {
368 0 : mxProgressBar = uno::Reference< awt::XProgressBar >( xMonitor, uno::UNO_QUERY );
369 :
370 0 : if( mxProgressBar.is() )
371 : {
372 0 : OUString aProgressText;
373 :
374 0 : if( mpFilter )
375 : {
376 0 : aProgressText = GAL_RESSTR(RID_SVXSTR_GALLERY_FILTER);
377 : // mpFilter->SetUpdatePercentHdl( LINK( this, GalleryProgress, Update ) ); // sj: progress wasn't working up from SO7 at all
378 : // // so I am removing this. The gallery progress should
379 : // // be changed to use the XStatusIndicator instead of XProgressMonitor
380 : }
381 : else
382 0 : aProgressText = "Gallery";
383 :
384 0 : xMonitor->addText( "Gallery", aProgressText, sal_False ) ;
385 0 : mxProgressBar->setRange( 0, GALLERY_PROGRESS_RANGE );
386 : }
387 0 : }
388 0 : }
389 :
390 0 : GalleryProgress::~GalleryProgress()
391 : {
392 0 : }
393 :
394 0 : void GalleryProgress::Update( sal_uIntPtr nVal, sal_uIntPtr nMaxVal )
395 : {
396 0 : if( mxProgressBar.is() && nMaxVal )
397 0 : mxProgressBar->setValue( std::min( (sal_uIntPtr)( (double) nVal / nMaxVal * GALLERY_PROGRESS_RANGE ), (sal_uIntPtr) GALLERY_PROGRESS_RANGE ) );
398 0 : }
399 :
400 :
401 0 : GalleryTransferable::GalleryTransferable( GalleryTheme* pTheme, sal_uIntPtr nObjectPos, bool bLazy ) :
402 : mpTheme( pTheme ),
403 0 : meObjectKind( mpTheme->GetObjectKind( nObjectPos ) ),
404 : mnObjectPos( nObjectPos ),
405 : mpGraphicObject( NULL ),
406 : mpImageMap( NULL ),
407 0 : mpURL( NULL )
408 : {
409 :
410 0 : InitData( bLazy );
411 0 : }
412 :
413 0 : GalleryTransferable::~GalleryTransferable()
414 : {
415 0 : }
416 :
417 0 : void GalleryTransferable::InitData( bool bLazy )
418 : {
419 0 : switch( meObjectKind )
420 : {
421 : case( SGA_OBJ_SVDRAW ):
422 : {
423 0 : if( !bLazy )
424 : {
425 0 : if( !mpGraphicObject )
426 : {
427 0 : Graphic aGraphic;
428 :
429 0 : if( mpTheme->GetGraphic( mnObjectPos, aGraphic ) )
430 0 : mpGraphicObject = new GraphicObject( aGraphic );
431 : }
432 :
433 0 : if( !mxModelStream.Is() )
434 : {
435 0 : mxModelStream = new SotStorageStream( "" );
436 0 : mxModelStream->SetBufferSize( 16348 );
437 :
438 0 : if( !mpTheme->GetModelStream( mnObjectPos, mxModelStream ) )
439 0 : mxModelStream.Clear();
440 : else
441 0 : mxModelStream->Seek( 0 );
442 : }
443 : }
444 : }
445 0 : break;
446 :
447 : case( SGA_OBJ_ANIM ):
448 : case( SGA_OBJ_BMP ):
449 : case( SGA_OBJ_INET ):
450 : case( SGA_OBJ_SOUND ):
451 : {
452 0 : if( !mpURL )
453 : {
454 0 : mpURL = new INetURLObject;
455 :
456 0 : if( !mpTheme->GetURL( mnObjectPos, *mpURL ) )
457 0 : delete mpURL, mpURL = NULL;
458 : }
459 :
460 0 : if( ( SGA_OBJ_SOUND != meObjectKind ) && !mpGraphicObject )
461 : {
462 0 : Graphic aGraphic;
463 :
464 0 : if( mpTheme->GetGraphic( mnObjectPos, aGraphic ) )
465 0 : mpGraphicObject = new GraphicObject( aGraphic );
466 : }
467 : }
468 0 : break;
469 :
470 : default:
471 : OSL_FAIL( "GalleryTransferable::GalleryTransferable: invalid object type" );
472 0 : break;
473 : }
474 0 : }
475 :
476 0 : void GalleryTransferable::AddSupportedFormats()
477 : {
478 0 : if( SGA_OBJ_SVDRAW == meObjectKind )
479 : {
480 0 : AddFormat( SOT_FORMATSTR_ID_DRAWING );
481 0 : AddFormat( SOT_FORMATSTR_ID_SVXB );
482 0 : AddFormat( FORMAT_GDIMETAFILE );
483 0 : AddFormat( FORMAT_BITMAP );
484 : }
485 : else
486 : {
487 0 : if( mpURL )
488 0 : AddFormat( FORMAT_FILE );
489 :
490 0 : if( mpGraphicObject )
491 : {
492 0 : AddFormat( SOT_FORMATSTR_ID_SVXB );
493 :
494 0 : if( mpGraphicObject->GetType() == GRAPHIC_GDIMETAFILE )
495 : {
496 0 : AddFormat( FORMAT_GDIMETAFILE );
497 0 : AddFormat( FORMAT_BITMAP );
498 : }
499 : else
500 : {
501 0 : AddFormat( FORMAT_BITMAP );
502 0 : AddFormat( FORMAT_GDIMETAFILE );
503 : }
504 : }
505 : }
506 0 : }
507 :
508 0 : bool GalleryTransferable::GetData( const datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
509 : {
510 0 : sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
511 0 : bool bRet = false;
512 :
513 0 : InitData( false );
514 :
515 0 : if( ( SOT_FORMATSTR_ID_DRAWING == nFormat ) && ( SGA_OBJ_SVDRAW == meObjectKind ) )
516 : {
517 0 : bRet = ( mxModelStream.Is() && SetObject( &mxModelStream, 0, rFlavor ) );
518 : }
519 0 : else if( ( SOT_FORMATSTR_ID_SVIM == nFormat ) && mpImageMap )
520 : {
521 : // TODO/MBA: do we need a BaseURL here?!
522 0 : bRet = SetImageMap( *mpImageMap, rFlavor );
523 : }
524 0 : else if( ( FORMAT_FILE == nFormat ) && mpURL )
525 : {
526 0 : bRet = SetString( mpURL->GetMainURL( INetURLObject::NO_DECODE ), rFlavor );
527 : }
528 0 : else if( ( SOT_FORMATSTR_ID_SVXB == nFormat ) && mpGraphicObject )
529 : {
530 0 : bRet = SetGraphic( mpGraphicObject->GetGraphic(), rFlavor );
531 : }
532 0 : else if( ( FORMAT_GDIMETAFILE == nFormat ) && mpGraphicObject )
533 : {
534 0 : bRet = SetGDIMetaFile( mpGraphicObject->GetGraphic().GetGDIMetaFile(), rFlavor );
535 : }
536 0 : else if( ( FORMAT_BITMAP == nFormat ) && mpGraphicObject )
537 : {
538 0 : bRet = SetBitmapEx( mpGraphicObject->GetGraphic().GetBitmapEx(), rFlavor );
539 : }
540 :
541 0 : return bRet;
542 : }
543 :
544 0 : bool GalleryTransferable::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject,
545 : sal_uInt32, const datatransfer::DataFlavor& )
546 : {
547 0 : bool bRet = false;
548 :
549 0 : if( pUserObject )
550 : {
551 0 : rxOStm->WriteStream( *static_cast< SotStorageStream* >( pUserObject ) );
552 0 : bRet = ( rxOStm->GetError() == ERRCODE_NONE );
553 : }
554 :
555 0 : return bRet;
556 : }
557 :
558 0 : void GalleryTransferable::DragFinished( sal_Int8 nDropAction )
559 : {
560 0 : mpTheme->SetDragging( false );
561 0 : mpTheme->SetDragPos( 0 );
562 0 : if ( nDropAction )
563 : {
564 0 : vcl::Window *pFocusWindow = Application::GetFocusWindow();
565 0 : if ( pFocusWindow )
566 0 : pFocusWindow->GrabFocusToDocument();
567 : }
568 0 : }
569 :
570 0 : void GalleryTransferable::ObjectReleased()
571 : {
572 0 : mxModelStream.Clear();
573 0 : delete mpGraphicObject, mpGraphicObject = NULL;
574 0 : delete mpImageMap, mpImageMap = NULL;
575 0 : delete mpURL, mpURL = NULL;
576 0 : }
577 :
578 0 : void GalleryTransferable::CopyToClipboard( vcl::Window* pWindow )
579 : {
580 0 : TransferableHelper::CopyToClipboard( pWindow );
581 0 : }
582 :
583 0 : void GalleryTransferable::StartDrag( vcl::Window* pWindow, sal_Int8 nDragSourceActions,
584 : sal_Int32 nDragPointer, sal_Int32 nDragImage )
585 : {
586 0 : INetURLObject aURL;
587 :
588 0 : if( mpTheme->GetURL( mnObjectPos, aURL ) && ( aURL.GetProtocol() != INET_PROT_NOT_VALID ) )
589 : {
590 0 : mpTheme->SetDragging( true );
591 0 : mpTheme->SetDragPos( mnObjectPos );
592 0 : TransferableHelper::StartDrag( pWindow, nDragSourceActions, nDragPointer, nDragImage );
593 0 : }
594 651 : }
595 :
596 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|