lok: Don't attempt to select the exact text after a failed search.
[LibreOffice.git] / cui / source / dialogs / cuigaldlg.cxx
blobdef7872b7edf5881b8c3e448513702d9af6a3a4b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "sal/config.h"
22 #include <algorithm>
23 #include <cassert>
25 #include <ucbhelper/content.hxx>
26 #include <osl/mutex.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/msgbox.hxx>
29 #include <avmedia/mediawindow.hxx>
30 #include <unotools/pathoptions.hxx>
31 #include <sfx2/opengrf.hxx>
32 #include <vcl/graphicfilter.hxx>
33 #include <svx/gallery1.hxx>
34 #include <svx/galtheme.hxx>
35 #include "cuigaldlg.hxx"
36 #include "helpid.hrc"
37 #include <unotools/syslocale.hxx>
38 #include <cppuhelper/implbase1.hxx>
39 #include <com/sun/star/uno/Reference.hxx>
40 #include <com/sun/star/lang/XInitialization.hpp>
41 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
42 #include <comphelper/processfactory.hxx>
43 #include <com/sun/star/sdbc/XResultSet.hpp>
44 #include <com/sun/star/sdbc/XRow.hpp>
45 #include <com/sun/star/ucb/XContentAccess.hpp>
46 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
47 #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
48 #include <sfx2/sfxuno.hxx>
49 #include "dialmgr.hxx"
50 #include "gallery.hrc"
51 #include <svx/dialogs.hrc>
52 #include <svx/dialmgr.hxx>
56 // - Namespaces -
59 using namespace ::ucbhelper;
60 using namespace ::cppu;
61 using namespace ::com::sun::star::lang;
62 using namespace ::com::sun::star::sdbc;
63 using namespace ::com::sun::star::ucb;
64 using namespace ::com::sun::star::ui::dialogs;
65 using namespace ::com::sun::star::uno;
68 // - SearchThread -
71 SearchThread::SearchThread( SearchProgress* pProgess,
72 TPGalleryThemeProperties* pBrowser,
73 const INetURLObject& rStartURL ) :
74 Thread ( "cuiSearchThread" ),
75 mpProgress ( pProgess ),
76 mpBrowser ( pBrowser ),
77 maStartURL ( rStartURL )
83 SearchThread::~SearchThread()
89 void SearchThread::execute()
91 const OUString aFileType( mpBrowser->m_pCbbFileType->GetText() );
93 if( !aFileType.isEmpty() )
95 const sal_uInt16 nFileNumber = mpBrowser->m_pCbbFileType->GetEntryPos( aFileType );
96 sal_uInt16 nBeginFormat, nEndFormat;
97 ::std::vector< OUString > aFormats;
99 if( !nFileNumber || ( nFileNumber >= mpBrowser->m_pCbbFileType->GetEntryCount() ) )
101 nBeginFormat = 1;
102 nEndFormat = mpBrowser->m_pCbbFileType->GetEntryCount() - 1;
104 else
105 nBeginFormat = nEndFormat = nFileNumber;
107 for( sal_uInt16 i = nBeginFormat; i <= nEndFormat; ++i )
108 aFormats.push_back( mpBrowser->aFilterEntryList[ i ]->aFilterName.toAsciiLowerCase() );
110 ImplSearch( maStartURL, aFormats, mpBrowser->bSearchRecursive );
113 Application::PostUserEvent( LINK( mpProgress, SearchProgress, CleanUpHdl ), NULL, true );
118 void SearchThread::ImplSearch( const INetURLObject& rStartURL,
119 const ::std::vector< OUString >& rFormats,
120 bool bRecursive )
123 SolarMutexGuard aGuard;
125 mpProgress->SetDirectory( rStartURL );
126 mpProgress->Sync();
131 ::com::sun::star::uno::Reference< XCommandEnvironment > xEnv;
132 Content aCnt( rStartURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv, comphelper::getProcessComponentContext() );
133 Sequence< OUString > aProps( 2 );
135 aProps.getArray()[ 0 ] = "IsFolder";
136 aProps.getArray()[ 1 ] = "IsDocument";
137 ::com::sun::star::uno::Reference< XResultSet > xResultSet(
138 aCnt.createCursor( aProps, INCLUDE_FOLDERS_AND_DOCUMENTS ) );
140 if( xResultSet.is() )
142 ::com::sun::star::uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
143 ::com::sun::star::uno::Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
145 while( xResultSet->next() && schedule() )
147 INetURLObject aFoundURL( xContentAccess->queryContentIdentifierString() );
148 DBG_ASSERT( aFoundURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
150 bool bFolder = xRow->getBoolean( 1 ); // property "IsFolder"
151 if ( xRow->wasNull() )
152 bFolder = false;
154 if( bRecursive && bFolder )
155 ImplSearch( aFoundURL, rFormats, true );
156 else
158 bool bDocument = xRow->getBoolean( 2 ); // property "IsDocument"
159 if ( xRow->wasNull() )
160 bDocument = false;
162 if( bDocument )
164 GraphicDescriptor aDesc( aFoundURL );
166 if( ( aDesc.Detect() &&
167 ::std::find( rFormats.begin(),
168 rFormats.end(),
169 GraphicDescriptor::GetImportFormatShortName(
170 aDesc.GetFileFormat() ).toAsciiLowerCase() )
171 != rFormats.end() ) ||
172 ::std::find( rFormats.begin(),
173 rFormats.end(),
174 aFoundURL.GetExtension().toAsciiLowerCase() )
175 != rFormats.end() )
177 SolarMutexGuard aGuard;
179 mpBrowser->aFoundList.push_back(
180 aFoundURL.GetMainURL( INetURLObject::NO_DECODE )
182 mpBrowser->m_pLbxFound->InsertEntry(
183 GetReducedString( aFoundURL, 50 ),
184 (sal_uInt16) mpBrowser->aFoundList.size() - 1 );
191 catch (const ContentCreationException&)
194 catch (const ::com::sun::star::uno::RuntimeException&)
197 catch (const ::com::sun::star::uno::Exception&)
203 // - SearchProgress -
206 SearchProgress::SearchProgress( vcl::Window* pParent, const INetURLObject& rStartURL )
207 : ModalDialog(pParent, "GallerySearchProgress", "cui/ui/gallerysearchprogress.ui")
208 , parent_(pParent)
209 , startUrl_(rStartURL)
211 get(m_pFtSearchDir, "dir");
212 get(m_pFtSearchType, "file");
213 m_pFtSearchType->set_width_request(m_pFtSearchType->get_preferred_size().Width());
214 get(m_pBtnCancel, "cancel");
215 m_pBtnCancel->SetClickHdl( LINK( this, SearchProgress, ClickCancelBtn ) );
218 SearchProgress::~SearchProgress()
220 disposeOnce();
223 void SearchProgress::dispose()
225 m_pFtSearchDir.clear();
226 m_pFtSearchType.clear();
227 m_pBtnCancel.clear();
228 parent_.clear();
229 ModalDialog::dispose();
233 void SearchProgress::Terminate()
235 if (maSearchThread.is())
236 maSearchThread->terminate();
241 IMPL_LINK_NOARG(SearchProgress, ClickCancelBtn)
243 Terminate();
244 return 0L;
249 IMPL_LINK_NOARG(SearchProgress, CleanUpHdl)
251 if (maSearchThread.is())
252 maSearchThread->join();
254 EndDialog( RET_OK );
256 disposeOnce();
257 return 0L;
262 short SearchProgress::Execute()
264 OSL_FAIL( "SearchProgress cannot be executed via Dialog::Execute!\n"
265 "It creates a thread that will call back to VCL apartment => deadlock!\n"
266 "Use Dialog::StartExecuteModal to execute the dialog!" );
267 return RET_CANCEL;
272 void SearchProgress::StartExecuteModal( const Link<>& rEndDialogHdl )
274 assert(!maSearchThread.is());
275 maSearchThread = new SearchThread(
276 this, static_cast< TPGalleryThemeProperties * >(parent_.get()), startUrl_);
277 maSearchThread->launch();
278 ModalDialog::StartExecuteModal( rEndDialogHdl );
282 // - TakeThread -
285 TakeThread::TakeThread(
286 TakeProgress* pProgess,
287 TPGalleryThemeProperties* pBrowser,
288 TokenList_impl& rTakenList
290 Thread ( "cuiTakeThread" ),
291 mpProgress ( pProgess ),
292 mpBrowser ( pBrowser ),
293 mrTakenList ( rTakenList )
299 TakeThread::~TakeThread()
305 void TakeThread::execute()
307 INetURLObject aURL;
308 sal_uInt16 nEntries;
309 GalleryTheme* pThm = mpBrowser->GetXChgData()->pTheme;
310 sal_uInt16 nPos;
311 GalleryProgress* pStatusProgress;
314 SolarMutexGuard aGuard;
315 pStatusProgress = new GalleryProgress;
316 nEntries = mpBrowser->bTakeAll ? mpBrowser->m_pLbxFound->GetEntryCount() : mpBrowser->m_pLbxFound->GetSelectEntryCount();
317 pThm->LockBroadcaster();
320 for( sal_uInt16 i = 0; i < nEntries && schedule(); i++ )
322 if( mpBrowser->bTakeAll )
323 aURL = INetURLObject( mpBrowser->aFoundList[ nPos = i ] );
324 else
325 aURL = INetURLObject( mpBrowser->aFoundList[ nPos = mpBrowser->m_pLbxFound->GetSelectEntryPos( i ) ]);
327 mrTakenList.push_back( (sal_uLong)nPos );
330 SolarMutexGuard aGuard;
332 mpProgress->SetFile( aURL );
333 pStatusProgress->Update( i, nEntries - 1 );
334 mpProgress->Sync();
335 pThm->InsertURL( aURL );
340 SolarMutexGuard aGuard;
342 pThm->UnlockBroadcaster();
343 delete pStatusProgress;
346 Application::PostUserEvent( LINK( mpProgress, TakeProgress, CleanUpHdl ), NULL, true );
349 // - TakeProgress -
350 TakeProgress::TakeProgress(vcl::Window* pWindow)
351 : ModalDialog(pWindow, "GalleryApplyProgress",
352 "cui/ui/galleryapplyprogress.ui")
353 , window_(pWindow)
355 get(m_pFtTakeFile, "file");
356 get(m_pBtnCancel, "cancel");
358 m_pBtnCancel->SetClickHdl( LINK( this, TakeProgress, ClickCancelBtn ) );
361 TakeProgress::~TakeProgress()
363 disposeOnce();
366 void TakeProgress::dispose()
368 m_pFtTakeFile.clear();
369 m_pBtnCancel.clear();
370 window_.clear();
371 ModalDialog::dispose();
374 void TakeProgress::Terminate()
376 if (maTakeThread.is())
377 maTakeThread->terminate();
380 IMPL_LINK_NOARG(TakeProgress, ClickCancelBtn)
382 Terminate();
383 return 0L;
386 IMPL_LINK_NOARG(TakeProgress, CleanUpHdl)
388 if (maTakeThread.is())
389 maTakeThread->join();
391 TPGalleryThemeProperties* mpBrowser = static_cast<TPGalleryThemeProperties*>( GetParent() );
392 ::std::vector<bool, std::allocator<bool> > aRemoveEntries( mpBrowser->aFoundList.size(), false );
393 ::std::vector< OUString > aRemainingVector;
394 sal_uInt32 i, nCount;
396 GetParent()->EnterWait();
397 mpBrowser->m_pLbxFound->SetUpdateMode( false );
398 mpBrowser->m_pLbxFound->SetNoSelection();
400 // mark all taken positions in aRemoveEntries
401 for( i = 0, nCount = maTakenList.size(); i < nCount; ++i )
402 aRemoveEntries[ maTakenList[ i ] ] = true;
403 maTakenList.clear();
405 // refill found list
406 for( i = 0, nCount = aRemoveEntries.size(); i < nCount; ++i )
407 if( !aRemoveEntries[ i ] )
408 aRemainingVector.push_back( mpBrowser->aFoundList[i] );
410 mpBrowser->aFoundList.clear();
412 for( i = 0, nCount = aRemainingVector.size(); i < nCount; ++i )
413 mpBrowser->aFoundList.push_back( aRemainingVector[ i ] );
415 aRemainingVector.clear();
417 // refill list box
418 for( i = 0, nCount = aRemoveEntries.size(); i < nCount; ++i )
419 if( !aRemoveEntries[ i ] )
420 aRemainingVector.push_back( mpBrowser->m_pLbxFound->GetEntry( (sal_uInt16) i ) );
422 mpBrowser->m_pLbxFound->Clear();
424 for( i = 0, nCount = aRemainingVector.size(); i < nCount; ++i )
425 mpBrowser->m_pLbxFound->InsertEntry( aRemainingVector[ i ] );
427 aRemainingVector.clear();
429 mpBrowser->m_pLbxFound->SetUpdateMode( true );
430 mpBrowser->SelectFoundHdl( NULL );
431 GetParent()->LeaveWait();
433 EndDialog( RET_OK );
434 disposeOnce();
435 return 0L;
440 short TakeProgress::Execute()
442 OSL_FAIL( "TakeProgress cannot be executed via Dialog::Execute!\n"
443 "It creates a thread that will call back to VCL apartment => deadlock!\n"
444 "Use Dialog::StartExecuteModal to execute the dialog!" );
445 return RET_CANCEL;
450 void TakeProgress::StartExecuteModal( const Link<>& rEndDialogHdl )
452 assert(!maTakeThread.is());
453 maTakeThread = new TakeThread(
454 this, static_cast< TPGalleryThemeProperties * >(window_.get()), maTakenList);
455 maTakeThread->launch();
456 ModalDialog::StartExecuteModal( rEndDialogHdl );
460 // - ActualizeProgress -
461 ActualizeProgress::ActualizeProgress(vcl::Window* pWindow, GalleryTheme* pThm)
462 : ModalDialog(pWindow, "GalleryUpdateProgress",
463 "cui/ui/galleryupdateprogress.ui")
464 , pIdle(NULL)
465 , pTheme(pThm)
467 get(m_pFtActualizeFile, "file");
468 get(m_pBtnCancel, "cancel");
469 m_pBtnCancel->SetClickHdl( LINK( this, ActualizeProgress, ClickCancelBtn ) );
472 ActualizeProgress::~ActualizeProgress()
474 disposeOnce();
477 void ActualizeProgress::dispose()
479 m_pFtActualizeFile.clear();
480 m_pBtnCancel.clear();
481 ModalDialog::dispose();
484 short ActualizeProgress::Execute()
486 short nRet;
488 pIdle = new Idle;
489 pIdle->SetIdleHdl( LINK( this, ActualizeProgress, TimeoutHdl ) );
490 pIdle->SetPriority( SchedulerPriority::LOWEST );
491 pIdle->Start();
493 nRet = ModalDialog::Execute();
495 return nRet;
500 IMPL_LINK_NOARG(ActualizeProgress, ClickCancelBtn)
502 pTheme->AbortActualize();
503 EndDialog( RET_OK );
505 return 0L;
510 IMPL_LINK_TYPED( ActualizeProgress, TimeoutHdl, Idle*, _pTimer, void)
512 if ( _pTimer )
514 _pTimer->Stop();
515 delete _pTimer;
518 pTheme->Actualize( LINK( this, ActualizeProgress, ActualizeHdl ), &aStatusProgress );
519 ClickCancelBtn( NULL );
524 IMPL_LINK( ActualizeProgress, ActualizeHdl, INetURLObject*, pURL )
526 for( long i = 0; i < 128; i++ )
527 Application::Reschedule();
529 Flush();
530 Sync();
532 if( pURL )
534 m_pFtActualizeFile->SetText( GetReducedString( *pURL, 30 ) );
535 m_pFtActualizeFile->Flush();
536 m_pFtActualizeFile->Sync();
539 return 0;
542 TitleDialog::TitleDialog(vcl::Window* pParent, const OUString& rOldTitle)
543 : ModalDialog(pParent, "GalleryTitleDialog", "cui/ui/gallerytitledialog.ui")
545 get(m_pEdit, "entry");
546 m_pEdit->SetText( rOldTitle );
547 m_pEdit->GrabFocus();
550 TitleDialog::~TitleDialog()
552 disposeOnce();
555 void TitleDialog::dispose()
557 m_pEdit.clear();
558 ModalDialog::dispose();
562 // - GalleryIdDialog -
565 GalleryIdDialog::GalleryIdDialog( vcl::Window* pParent, GalleryTheme* _pThm )
566 : ModalDialog(pParent, "GalleryThemeIDDialog", "cui/ui/gallerythemeiddialog.ui")
567 , pThm(_pThm )
569 get(m_pBtnOk, "ok");
570 get(m_pLbResName, "entry");
572 m_pLbResName->InsertEntry( OUString( "!!! No Id !!!" ) );
574 GalleryTheme::InsertAllThemes(*m_pLbResName);
576 m_pLbResName->SelectEntryPos( (sal_uInt16) pThm->GetId() );
577 m_pLbResName->GrabFocus();
579 m_pBtnOk->SetClickHdl( LINK( this, GalleryIdDialog, ClickOkHdl ) );
582 GalleryIdDialog::~GalleryIdDialog()
584 disposeOnce();
587 void GalleryIdDialog::dispose()
589 m_pBtnOk.clear();
590 m_pLbResName.clear();
591 ModalDialog::dispose();
594 IMPL_LINK_NOARG(GalleryIdDialog, ClickOkHdl)
596 Gallery* pGal = pThm->GetParent();
597 const sal_uLong nId = GetId();
598 bool bDifferentThemeExists = false;
600 for( sal_uLong i = 0, nCount = pGal->GetThemeCount(); i < nCount && !bDifferentThemeExists; i++ )
602 const GalleryThemeEntry* pInfo = pGal->GetThemeInfo( i );
604 if( ( pInfo->GetId() == nId ) && ( pInfo->GetThemeName() != pThm->GetName() ) )
606 OUString aStr( CUI_RES( RID_SVXSTR_GALLERY_ID_EXISTS ) );
608 aStr += " (";
609 aStr += pInfo->GetThemeName();
610 aStr += ")";
612 ScopedVclPtrInstance< InfoBox > aBox( this, aStr );
613 aBox->Execute();
614 m_pLbResName->GrabFocus();
615 bDifferentThemeExists = true;
619 if( !bDifferentThemeExists )
620 EndDialog( RET_OK );
622 return 0L;
627 // - GalleryThemeProperties -
630 GalleryThemeProperties::GalleryThemeProperties(vcl::Window* pParent,
631 ExchangeData* _pData, SfxItemSet* pItemSet)
632 : SfxTabDialog( pParent, "GalleryThemeDialog",
633 "cui/ui/gallerythemedialog.ui", pItemSet)
634 , pData(_pData)
635 , m_nGeneralPageId(0)
636 , m_nFilesPageId(0)
638 m_nGeneralPageId = AddTabPage("general", TPGalleryThemeGeneral::Create, 0);
639 m_nFilesPageId = AddTabPage("files", TPGalleryThemeProperties::Create, 0);
641 if( pData->pTheme->IsReadOnly() )
642 RemoveTabPage(m_nFilesPageId);
644 OUString aText( GetText() );
646 aText += pData->pTheme->GetName();
648 if( pData->pTheme->IsReadOnly() )
649 aText += CUI_RES( RID_SVXSTR_GALLERY_READONLY );
651 SetText( aText );
654 void GalleryThemeProperties::PageCreated( sal_uInt16 nId, SfxTabPage &rPage )
656 if (nId == m_nGeneralPageId)
657 static_cast<TPGalleryThemeGeneral&>( rPage ).SetXChgData( pData );
658 else
659 static_cast<TPGalleryThemeProperties&>( rPage ).SetXChgData( pData );
662 // - TPGalleryThemeGeneral -
663 TPGalleryThemeGeneral::TPGalleryThemeGeneral(vcl::Window* pParent, const SfxItemSet& rSet)
664 : SfxTabPage(pParent, "GalleryGeneralPage",
665 "cui/ui/gallerygeneralpage.ui", &rSet)
666 , pData(NULL)
668 get(m_pFiMSImage, "image");
669 get(m_pEdtMSName, "name");
670 get(m_pFtMSShowType, "type");
671 get(m_pFtMSShowPath, "location");
672 get(m_pFtMSShowContent, "contents");
673 get(m_pFtMSShowChangeDate, "modified");
676 TPGalleryThemeGeneral::~TPGalleryThemeGeneral()
678 disposeOnce();
681 void TPGalleryThemeGeneral::dispose()
683 m_pFiMSImage.clear();
684 m_pEdtMSName.clear();
685 m_pFtMSShowType.clear();
686 m_pFtMSShowPath.clear();
687 m_pFtMSShowContent.clear();
688 m_pFtMSShowChangeDate.clear();
689 SfxTabPage::dispose();
692 void TPGalleryThemeGeneral::SetXChgData( ExchangeData* _pData )
694 pData = _pData;
696 GalleryTheme* pThm = pData->pTheme;
697 OUString aOutStr( OUString::number(pThm->GetObjectCount()) );
698 OUString aObjStr( CUI_RES( RID_SVXSTR_GALLERYPROPS_OBJECT ) );
699 OUString aAccess;
700 OUString aType( SVX_RES( RID_SVXSTR_GALLERYPROPS_GALTHEME ) );
701 bool bReadOnly = pThm->IsReadOnly();
703 m_pEdtMSName->SetText( pThm->GetName() );
704 m_pEdtMSName->SetReadOnly( bReadOnly );
706 if( bReadOnly )
707 m_pEdtMSName->Disable();
708 else
709 m_pEdtMSName->Enable();
711 if( pThm->IsReadOnly() )
712 aType += CUI_RES( RID_SVXSTR_GALLERY_READONLY );
714 m_pFtMSShowType->SetText( aType );
715 m_pFtMSShowPath->SetText( pThm->GetSdgURL().GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) );
717 // singular or plural?
718 if ( 1 == pThm->GetObjectCount() )
719 aObjStr = aObjStr.getToken( 0, ';' );
720 else
721 aObjStr = aObjStr.getToken( 1, ';' );
723 aOutStr += " " + aObjStr;
725 m_pFtMSShowContent->SetText( aOutStr );
727 // get locale wrapper (singleton)
728 const SvtSysLocale aSysLocale;
729 const LocaleDataWrapper& aLocaleData = aSysLocale.GetLocaleData();
731 // ChangeDate/Time
732 aAccess = aLocaleData.getDate( pData->aThemeChangeDate ) + ", " + aLocaleData.getTime( pData->aThemeChangeTime );
733 m_pFtMSShowChangeDate->SetText( aAccess );
735 // set image
736 sal_uInt16 nId;
738 if( pThm->IsReadOnly() )
739 nId = RID_SVXBMP_THEME_READONLY_BIG;
740 else if( pThm->IsDefault() )
741 nId = RID_SVXBMP_THEME_DEFAULT_BIG;
742 else
743 nId = RID_SVXBMP_THEME_NORMAL_BIG;
745 m_pFiMSImage->SetImage( Image( Bitmap( CUI_RES( nId ) ), COL_LIGHTMAGENTA ) );
750 bool TPGalleryThemeGeneral::FillItemSet( SfxItemSet* /*rSet*/ )
752 pData->aEditedTitle = m_pEdtMSName->GetText();
753 return true;
758 VclPtr<SfxTabPage> TPGalleryThemeGeneral::Create( vcl::Window* pParent, const SfxItemSet* rSet )
760 return VclPtr<TPGalleryThemeGeneral>::Create( pParent, *rSet );
763 // - TPGalleryThemeProperties -
764 TPGalleryThemeProperties::TPGalleryThemeProperties( vcl::Window* pWindow, const SfxItemSet& rSet )
765 : SfxTabPage(pWindow, "GalleryFilesPage", "cui/ui/galleryfilespage.ui", &rSet)
766 , pData(NULL)
767 , nCurFilterPos(0)
768 , nFirstExtFilterPos(0)
769 , bEntriesFound(false)
770 , bInputAllowed(true)
771 , bTakeAll(false)
772 , bSearchRecursive(false)
773 , xDialogListener(new ::svt::DialogClosedListener())
775 get(m_pCbbFileType, "filetype");
776 get(m_pLbxFound, "files");
777 Size aSize(LogicToPixel(Size(172, 156), MAP_APPFONT));
778 m_pLbxFound->set_width_request(aSize.Width());
779 m_pLbxFound->set_height_request(aSize.Height());
780 m_pLbxFound->EnableMultiSelection(true);
781 get(m_pBtnSearch, "findfiles");
782 get(m_pBtnTake, "add");
783 get(m_pBtnTakeAll, "addall");
784 get(m_pCbxPreview, "preview");
785 get(m_pWndPreview, "image");
787 xDialogListener->SetDialogClosedLink( LINK( this, TPGalleryThemeProperties, DialogClosedHdl ) );
790 void TPGalleryThemeProperties::SetXChgData( ExchangeData* _pData )
792 pData = _pData;
794 aPreviewTimer.SetTimeoutHdl( LINK( this, TPGalleryThemeProperties, PreviewTimerHdl ) );
795 aPreviewTimer.SetTimeout( 500 );
796 m_pBtnSearch->SetClickHdl(LINK(this, TPGalleryThemeProperties, ClickSearchHdl));
797 m_pBtnTake->SetClickHdl(LINK(this, TPGalleryThemeProperties, ClickTakeHdl));
798 m_pBtnTakeAll->SetClickHdl(LINK(this, TPGalleryThemeProperties, ClickTakeAllHdl));
799 m_pCbxPreview->SetClickHdl(LINK(this, TPGalleryThemeProperties, ClickPreviewHdl));
800 m_pCbbFileType->SetSelectHdl(LINK(this, TPGalleryThemeProperties, SelectFileTypeHdl));
801 m_pCbbFileType->EnableDDAutoWidth( false );
802 m_pLbxFound->SetDoubleClickHdl(LINK(this, TPGalleryThemeProperties, DClickFoundHdl));
803 m_pLbxFound->SetSelectHdl(LINK(this, TPGalleryThemeProperties, SelectFoundHdl));
804 m_pLbxFound->InsertEntry(OUString(CUI_RES(RID_SVXSTR_GALLERY_NOFILES)));
805 m_pLbxFound->Show();
807 FillFilterList();
809 m_pBtnTake->Enable();
810 m_pBtnTakeAll->Disable();
811 m_pCbxPreview->Disable();
816 void TPGalleryThemeProperties::StartSearchFiles( const OUString& _rFolderURL, short _nDlgResult )
818 if ( RET_OK == _nDlgResult )
820 aURL = INetURLObject( _rFolderURL );
821 bSearchRecursive = true; // UI choice no longer possible, windows file picker allows no user controls
822 SearchFiles();
825 nCurFilterPos = m_pCbbFileType->GetEntryPos( m_pCbbFileType->GetText() );
830 TPGalleryThemeProperties::~TPGalleryThemeProperties()
832 disposeOnce();
835 void TPGalleryThemeProperties::dispose()
837 xMediaPlayer.clear();
838 xDialogListener.clear();
840 for ( size_t i = 0, n = aFilterEntryList.size(); i < n; ++i ) {
841 delete aFilterEntryList[ i ];
843 aFilterEntryList.clear();
845 m_pCbbFileType.clear();
846 m_pLbxFound.clear();
847 m_pBtnSearch.clear();
848 m_pBtnTake.clear();
849 m_pBtnTakeAll.clear();
850 m_pCbxPreview.clear();
851 m_pWndPreview.clear();
852 SfxTabPage::dispose();
855 VclPtr<SfxTabPage> TPGalleryThemeProperties::Create( vcl::Window* pParent, const SfxItemSet* rSet )
857 return VclPtr<TPGalleryThemeProperties>::Create( pParent, *rSet );
860 OUString TPGalleryThemeProperties::addExtension( const OUString& _rDisplayText, const OUString& _rExtension )
862 OUString sAllFilter( "(*.*)" );
863 OUString sOpenBracket( " (" );
864 OUString sCloseBracket( ")" );
865 OUString sRet = _rDisplayText;
867 if ( sRet.indexOf( sAllFilter ) == -1 )
869 OUString sExt = _rExtension;
870 sRet += sOpenBracket;
871 sRet += sExt;
872 sRet += sCloseBracket;
874 return sRet;
879 void TPGalleryThemeProperties::FillFilterList()
881 GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
882 OUString aExt;
883 OUString aName;
884 FilterEntry* pFilterEntry;
885 sal_uInt16 i, nKeyCount;
887 // graphic filters
888 for( i = 0, nKeyCount = rFilter.GetImportFormatCount(); i < nKeyCount; i++ )
890 aExt = rFilter.GetImportFormatShortName( i );
891 aName = rFilter.GetImportFormatName( i );
892 size_t entryIndex = 0;
893 FilterEntry* pTestEntry = aFilterEntryList.empty() ? NULL : aFilterEntryList[ entryIndex ];
894 bool bInList = false;
896 OUString aExtensions;
897 int j = 0;
898 OUString sWildcard;
899 while( true )
901 sWildcard = rFilter.GetImportWildcard( i, j++ );
902 if ( sWildcard.isEmpty() )
903 break;
904 if ( aExtensions.indexOf( sWildcard ) == -1 )
906 if ( !aExtensions.isEmpty() )
907 aExtensions += ";";
908 aExtensions += sWildcard;
911 aName = addExtension( aName, aExtensions );
913 while( pTestEntry )
915 if ( pTestEntry->aFilterName == aExt )
917 bInList = true;
918 break;
920 pTestEntry = ( ++entryIndex < aFilterEntryList.size() )
921 ? aFilterEntryList[ entryIndex ] : NULL;
923 if ( !bInList )
925 pFilterEntry = new FilterEntry;
926 pFilterEntry->aFilterName = aExt;
927 size_t pos = m_pCbbFileType->InsertEntry( aName );
928 if ( pos < aFilterEntryList.size() ) {
929 aFilterEntryList.insert( aFilterEntryList.begin() + pos, pFilterEntry );
930 } else {
931 aFilterEntryList.push_back( pFilterEntry );
936 // media filters
937 static const char aWildcard[] = "*.";
938 ::avmedia::FilterNameVector aFilters;
939 ::avmedia::MediaWindow::getMediaFilters( aFilters );
941 for( unsigned long l = 0; l < aFilters.size(); ++l )
943 for( sal_Int32 nIndex = 0; nIndex >= 0; )
945 OUString aFilterWildcard( aWildcard );
947 pFilterEntry = new FilterEntry;
948 pFilterEntry->aFilterName = aFilters[ l ].second.getToken( 0, ';', nIndex );
949 nFirstExtFilterPos = m_pCbbFileType->InsertEntry(
950 addExtension(
951 aFilters[ l ].first,
952 aFilterWildcard += pFilterEntry->aFilterName
955 if ( nFirstExtFilterPos < aFilterEntryList.size() ) {
956 aFilterEntryList.insert(
957 aFilterEntryList.begin() + nFirstExtFilterPos,
958 pFilterEntry
960 } else {
961 aFilterEntryList.push_back( pFilterEntry );
966 // 'All' filters
967 OUString aExtensions;
969 // graphic filters
970 for ( i = 0; i < nKeyCount; ++i )
972 int j = 0;
973 OUString sWildcard;
974 while( true )
976 sWildcard = rFilter.GetImportWildcard( i, j++ );
977 if ( sWildcard.isEmpty() )
978 break;
979 if ( aExtensions.indexOf( sWildcard ) == -1 )
981 if ( !aExtensions.isEmpty() )
982 aExtensions += ";";
984 aExtensions += sWildcard;
989 // media filters
990 for( unsigned long k = 0; k < aFilters.size(); ++k )
992 for( sal_Int32 nIndex = 0; nIndex >= 0; )
994 if ( !aExtensions.isEmpty() )
995 aExtensions += ";";
996 aExtensions += aWildcard + aFilters[ k ].second.getToken( 0, ';', nIndex );
1000 #if defined(WNT)
1001 if (aExtensions.getLength() > 240)
1002 aExtensions = "*.*";
1003 #endif
1005 pFilterEntry = new FilterEntry;
1006 pFilterEntry->aFilterName = CUI_RESSTR(RID_SVXSTR_GALLERY_ALLFILES);
1007 pFilterEntry->aFilterName = addExtension( pFilterEntry->aFilterName, aExtensions );
1008 size_t pos = m_pCbbFileType->InsertEntry( pFilterEntry->aFilterName, 0 );
1009 if ( pos < aFilterEntryList.size() ) {
1010 aFilterEntryList.insert( aFilterEntryList.begin() + pos, pFilterEntry );
1011 } else {
1012 aFilterEntryList.push_back( pFilterEntry );
1014 m_pCbbFileType->SetText( pFilterEntry->aFilterName );
1019 IMPL_LINK_NOARG(TPGalleryThemeProperties, SelectFileTypeHdl)
1021 OUString aText( m_pCbbFileType->GetText() );
1023 if( bInputAllowed && ( aLastFilterName != aText ) )
1025 aLastFilterName = aText;
1027 if( ScopedVclPtrInstance<MessageDialog>::Create( this, "QueryUpdateFileListDialog","cui/ui/queryupdategalleryfilelistdialog.ui" )->Execute() == RET_YES )
1028 SearchFiles();
1031 return 0L;
1036 void TPGalleryThemeProperties::SearchFiles()
1038 SearchProgress* pProgress = VclPtr<SearchProgress>::Create( this, aURL );
1040 aFoundList.clear();
1041 m_pLbxFound->Clear();
1043 pProgress->SetFileType( m_pCbbFileType->GetText() );
1044 pProgress->SetDirectory( INetURLObject() );
1045 pProgress->Update();
1047 pProgress->StartExecuteModal( LINK( this, TPGalleryThemeProperties, EndSearchProgressHdl ) );
1052 IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickSearchHdl)
1054 if( bInputAllowed )
1058 // setup folder picker
1059 com::sun::star::uno::Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1060 xFolderPicker = FolderPicker::create(xContext);
1062 OUString aDlgPathName( SvtPathOptions().GetGraphicPath() );
1063 xFolderPicker->setDisplayDirectory(aDlgPathName);
1065 aPreviewTimer.Stop();
1067 com::sun::star::uno::Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
1068 if ( xAsyncDlg.is() )
1069 xAsyncDlg->startExecuteModal( xDialogListener.get() );
1070 else
1072 if( xFolderPicker->execute() == RET_OK )
1074 aURL = INetURLObject( xFolderPicker->getDirectory() );
1075 bSearchRecursive = true; // UI choice no longer possible, windows file picker allows no user controls
1076 SearchFiles();
1079 nCurFilterPos = m_pCbbFileType->GetEntryPos( m_pCbbFileType->GetText() );
1082 catch (const IllegalArgumentException&)
1084 OSL_FAIL( "Folder picker failed with illegal arguments" );
1088 return 0L;
1093 void TPGalleryThemeProperties::TakeFiles()
1095 if( m_pLbxFound->GetSelectEntryCount() || ( bTakeAll && bEntriesFound ) )
1097 VclPtrInstance<TakeProgress> pTakeProgress( this );
1098 pTakeProgress->Update();
1100 pTakeProgress->StartExecuteModal(
1101 Link<>() /* no postprocessing needed, pTakeProgress
1102 will be disposed in TakeProgress::CleanupHdl */ );
1108 IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickPreviewHdl)
1110 if ( bInputAllowed )
1112 aPreviewTimer.Stop();
1113 aPreviewString.clear();
1115 if( !m_pCbxPreview->IsChecked() )
1117 xMediaPlayer.clear();
1118 m_pWndPreview->SetGraphic( Graphic() );
1119 m_pWndPreview->Invalidate();
1121 else
1122 DoPreview();
1125 return 0;
1130 void TPGalleryThemeProperties::DoPreview()
1132 OUString aString( m_pLbxFound->GetSelectEntry() );
1134 if( aString != aPreviewString )
1136 INetURLObject _aURL( aFoundList[ m_pLbxFound->GetEntryPos( aString ) ] );
1137 bInputAllowed = false;
1139 if ( !m_pWndPreview->SetGraphic( _aURL ) )
1141 GetParent()->LeaveWait();
1142 ErrorHandler::HandleError( ERRCODE_IO_NOTEXISTSPATH );
1143 GetParent()->EnterWait();
1145 else if( ::avmedia::MediaWindow::isMediaURL( _aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ), "" ) )
1147 xMediaPlayer = ::avmedia::MediaWindow::createPlayer( _aURL.GetMainURL( INetURLObject::NO_DECODE ), "" );
1148 if( xMediaPlayer.is() )
1149 xMediaPlayer->start();
1152 bInputAllowed = true;
1153 aPreviewString = aString;
1159 IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickTakeHdl)
1161 if( bInputAllowed )
1163 aPreviewTimer.Stop();
1165 if( !m_pLbxFound->GetSelectEntryCount() || !bEntriesFound )
1167 SvxOpenGraphicDialog aDlg("Gallery");
1168 aDlg.EnableLink(false);
1169 aDlg.AsLink(false);
1171 if( !aDlg.Execute() )
1172 pData->pTheme->InsertURL( INetURLObject( aDlg.GetPath() ) );
1174 else
1176 bTakeAll = false;
1177 TakeFiles();
1181 return 0L;
1186 IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickTakeAllHdl)
1188 if( bInputAllowed )
1190 aPreviewTimer.Stop();
1191 bTakeAll = true;
1192 TakeFiles();
1195 return 0L;
1200 IMPL_LINK_NOARG(TPGalleryThemeProperties, SelectFoundHdl)
1202 if( bInputAllowed )
1204 bool bPreviewPossible = false;
1206 aPreviewTimer.Stop();
1208 if( bEntriesFound )
1210 if( m_pLbxFound->GetSelectEntryCount() == 1 )
1212 m_pCbxPreview->Enable();
1213 bPreviewPossible = true;
1215 else
1216 m_pCbxPreview->Disable();
1218 if( !aFoundList.empty() )
1219 m_pBtnTakeAll->Enable();
1220 else
1221 m_pBtnTakeAll->Disable();
1224 if( bPreviewPossible && m_pCbxPreview->IsChecked() )
1225 aPreviewTimer.Start();
1228 return 0;
1233 IMPL_LINK_NOARG(TPGalleryThemeProperties, DClickFoundHdl)
1235 if( bInputAllowed )
1237 aPreviewTimer.Stop();
1239 return (m_pLbxFound->GetSelectEntryCount() == 1 && bEntriesFound) ?
1240 ClickTakeHdl(NULL) : 0;
1242 else
1243 return 0;
1248 IMPL_LINK_NOARG_TYPED(TPGalleryThemeProperties, PreviewTimerHdl, Timer *, void)
1250 aPreviewTimer.Stop();
1251 DoPreview();
1256 IMPL_LINK_NOARG(TPGalleryThemeProperties, EndSearchProgressHdl)
1258 if( !aFoundList.empty() )
1260 m_pLbxFound->SelectEntryPos( 0 );
1261 m_pBtnTakeAll->Enable();
1262 m_pCbxPreview->Enable();
1263 bEntriesFound = true;
1265 else
1267 m_pLbxFound->InsertEntry( OUString( CUI_RES( RID_SVXSTR_GALLERY_NOFILES ) ) );
1268 m_pBtnTakeAll->Disable();
1269 m_pCbxPreview->Disable();
1270 bEntriesFound = false;
1272 return 0L;
1277 IMPL_LINK( TPGalleryThemeProperties, DialogClosedHdl, ::com::sun::star::ui::dialogs::DialogClosedEvent*, pEvt )
1279 DBG_ASSERT( xFolderPicker.is(), "TPGalleryThemeProperties::DialogClosedHdl(): no folder picker" );
1281 OUString sURL = xFolderPicker->getDirectory();
1282 StartSearchFiles( sURL, pEvt->DialogResult );
1284 return 0L;
1287 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */